* * NEW DSRLNK * * --- DIRECT ACCESS TO THE FDC DEVICES --- * 2nd Version (V2). 21 August 2008. * Paolo Bagnaresi (paul.bagnaresi@...) * * PAB is always suppposed to be in * VDP ram. * * Warning: this code has been briefly * (and not extensively) tested. * Try it at your own risk, but * please do report any problem to: * paul.bagnaresi@.... * I will gladly answer and help. * Make sure to supply your source code, * though, no matter how large it is. * * Improvements over standard DSRLNK: * 1) Avoids dangerous PAB+1 error checks on * DSRLNK with DATA >A. * 2) Allows a faster new DSRLNK execution. * After a first DSRLNK has been called, next * DSRLNK calls to the same device and subrogram * can be made by calling BLWP @DSRAGN * The catch: no other DSRLNK for different * purposes has to be called in between. * Example: * LI R0,PDNLP Pointer to Device Name Length in PAB * MOV R0,@>8356 * BLWP @DSRLNK * DATA >A First time, DATA 8 or >A has to be added * JNE SUCCESS * SRL R0,8 * CI R0,>00XX See what error * ... * No pointer to Device Name Length in PAB this time * BLWP @DSRAGN Execute again same DSRLNK, no DATA this time * JNE SUCCES2 Much faster execution this time! * SRL R0,8 * CI R0,>00XX See what error * ... * Why this modified version? * DSRLNK takes a lot of time searching the proper * subprogram/device in the suitable card * at >4000. * Once the desired subprogram/device has been found, * there is no need to search again all the available * devices/subprograms should another access be needed * to the same device/subprogram. * * Just get back the last used parameters * (SAVCRU, SAVENT, SAVLEN, SAVPAB and SAVVER), * and you'll avoid a lenghty new search * across all the DSR cards. * * This new version of DSRLNK (with DSRAGN) * has a new type of error checking routine. * The so called PAB+1 (which is truly PAB+1 only * for DATA 8 calls), gets now checked only if * there is a DATA 8 followed the BLWP @DSRLNK. * In all the other cases (DATA >A and similar), * the error checking is performed on byte at >8350. * This is unlike standard DSRLNK, which can * give you a false positive for DATA >A calls. * * As it happens with the standard DSRLNK, * if the EQ bit is set in STATUS, R0 MSByte * of caller's workspace will contain the error * code. This is true for both BLWP @DSRLNK and * BLWP @DSRAGN and will allow you replacing * DSRLNK in your code without having to * modifying anyhting, hopefully. * If you do have to adjust the source code, * (MULTIPLE SYMBOLs and the like), * please remember that the following * addresses must remain in the same order as * they are now: * SAVCRU, SAVENT, SAVLEN, SAVPAB, SAVVER. * Also, TYPE has to point to R5 of DSRLNK * workspace (currently DSRLWS). * * A tip: just get your code working with * multiple accesses to a standard DSRLNK. * Once you've reached that point, try * substituting any DSRLNK access * after the first one with BLWP @DSRAGN * * If more than one device has to be called, * the code has to be changed. Thus: * 1) a STACK containing the vital parameters * of each DSRLNK has to be implemented. * 2) Each new DSRLNK will have to return * its pointer to the STACK. * 3) Each new call to DSRAGN will have to * use this pointer as a handle for the * proper file. * 4) 60 bytes worth of memory space will be * able to manage 5 open files at the same * time. * * REF VSBR -> You should provide a VSBR, as with * the standard DSRLNK DATA8 DATA >8 Just to compare. 8 is the DATA * that usually follows a BLWP @DSRLNK * Save parameters here SAV8A DATA 0 Save data following BLWP @DSRLNK (8 or >A) SAVCRU DATA 0 CRU Address of the Peripheral SAVENT DATA 0 Entry Address of DSR or Subprogram SAVLEN DATA 0 Device or Subprogram name length SAVPAB DATA 0 Pointer to Device or Subprogram in the PAB SAVVER DATA 0 Version # of DSR FLGPTR DATA 0 Pointer to Flag in PAB (Byte 1 in PAB) DSRLWS DATA 0,0,0,0,0 DSRLNK WORKSPACE TYPE DATA 0,0,0,0,0,0,0,0,0,0,0 DECMAL TEXT '.' HAA BYTE >AA EVEN H20 DATA >2000 BLANK, NULL NAMSTO DATA 0,0,0,0 DSRLNK 8 bytes Device Name Buffer * ****DSR LINK ROUTINE DSRLNK EQU $ DATA DSRLWS DSRLNK workspace DATA DLENTR DLENTR EQU $ MOV *R14+,R5 GET PGM TYPE FOR LINK MOV R5,@SAV8A - 2008.8.15 - Save data * following BLWP @DSRLNK (8 or >A) SZCB @H20,R15 RESET EQUAL BIT MOV @>8356,R0 GET PTR TO PAB MOV R0,R9 SAVE PTR MOV R0,@FLGPTR - 2008.8.15 - Save again pointer * to PAB+1 for DSRLNK DATA 8 AI R9,>FFF8 ADJUST TO FLAG BLWP @VSBR READ DEVICE NAME LENGTH MOVB R1,R3 COPY IT SRL R3,8 MAKE IT LO BYTER SETO R4 INIT COUNTER LI R2,NAMSTO POINT TO BUFFER LNKSLP INC R0 POINT TO NEXT CHAR OF NAME INC R4 INCR CHAR COUNTER CI R4,>0007 SEE IF LENGTH MORE THAN 7 CHARS JGT LNKERR YES, ERROR C R4,R3 END OF NAME? JEQ LNKSLN YES BLWP @VSBR READ CURR CHAR MOVB R1,*R2+ MOVE INTO BUFFER CB R1,@DECMAL IS IT A PERIOD? JNE LNKSLP NO LNKSLN MOV R4,R4 SEE IF 0 LENGTH JEQ LNKERR YES, ERROR CLR @>83D0 MOV R4,@>8354 SAVE NAME LENGTH FOR SEARCH MOV R4,@SAVLEN SAVE IT HERE TOO INC R4 ADJUST FOR PERIOD A R4,@>8356 POINT TO POSITION AFTER NAME MOV @>8356,@SAVPAB SAVE POINTER TO POSITION AFTER NAME SROM LWPI >83E0 USE GPLWS CLR R1 VERSION FOUND OF DSR LI R12,>0F00 INIT CRU ADDR NOROM MOV R12,R12 ANYTHING TO TURN OFF? JEQ NOOFF NO SBZ 0 YES, TURN OFF NOOFF AI R12,>0100 NEXT ROM TO TURN ON CLR @>83D0 CLEAR IN CASE WE ARE DONE CI R12,>2000 SEE IF DONE JEQ NODSR YES, NO DSR MATCH MOV R12,@>83D0 SAVE ADDR OF NEXT CRU SBO 0 TURN ON ROM LI R2,>4000 START AT BEGINNING OF ROM CB *R2,@HAA CHECK FOR A VALID ROM JNE NOROM NO ROM HERE A @TYPE,R2 GO TO FIRST POINTER JMP SGO2 SGO MOV @>83D2,R2 CONTINUE WHERE WE LEFT OFF SBO 0 TURN ROM BACK ON SGO2 MOV *R2,R2 IS ADDR A ZERO (END OF LINK) JEQ NOROM YES, NO PROGRAMS TO CHECK MOV R2,@>83D2 REMEMBER WHERE TO GO NEXT INCT R2 GO TO ENTRY POINT MOV *R2+,R9 GET ENTRY ADDR JUST IN CASE MOVB @>8355,R5 GET LENGTH AS COUNTER JEQ NAMTWO IF ZERO, DO NOT CHECK CB R5,*R2+ SEE IF LENGTH MATCHES JNE SGO NO, TRY NEXT SRL R5,8 YES, MOVE TO LO BYTE AS COUNTER LI R6,NAMSTO POINT TO BUFFER NAMONE CB *R6+,*R2+ COMPARE BUFFER WITH ROM JNE SGO TRY NEXT IF NO MATCH DEC R5 LOOP TIL FULL LENGTH CHECKED JNE NAMONE NAMTWO INC R1 NEXT VERSION FOUND MOV R1,@SAVVER SAVE VERSION MOV R9,@SAVENT SAVE ENTRY ADDR MOV R12,@SAVCRU SAVE CRU BL *R9 GO RUN ROUTINE JMP SGO ERROR RETURN SBZ 0 TURN OFF ROM IF GOOD RETURN LWPI DSRLWS RESTORE WORKSPACE MOV R9,R0 POINT TO FLAG IN PAB FRMDSR MOV @SAV8A,R1 - 2008.8.15 - Get back data * following BLWP @DSRLNK (8 or >A) CI R1,8 - 2008.8.15 - Was it 8? JEQ DSRDT8 - 2008.8.15 - Yes, jump: Normal DSRLNK MOVB @>8350,R1 - 2008.8.15 - No, we have a DATA >A. * Get Error byte from >8350 JMP DSRDTA - 2008.8.15 - Go and return error * byte to the caller DSRDT8 BLWP @VSBR READ FLAG DSRDTA SRL R1,13 JUST KEEP ERROR BITS - 2008.8.15 - Label added JNE IOERR HANDLE ERROR RTWP NODSR LWPI DSRLWS NO DSR, RESTORE WORKSPACE LNKERR CLR R1 CLEAR FLAG FOR ERROR 0 * = Bad Device Name IOERR SWPB R1 PUT ERROR IN HI BYTE MOVB R1,*R13 STORE ERROR FLAGS IN CALLERS R0 * - 2008.8.15 - even with DATA >A SOCB @H20,R15 SET EQUAL BIT TO INDICATE ERROR * - 2008.8.15 - even with DATA >A RTWP *----------------* * ACCESS ONCE AGAIN THE SAME DSRLNK *----------------* DSRAGN EQU $ DATA DSRLWS DATA LDGETR LDGETR SZCB @H20,R15 Reset Equal Bit in STATUS (V2) LWPI >83E0 LI R0,SAVCRU Get pointer to last used CPU address MOV *R0+,R12 Get CRU addr. MOV *R0+,R9 Get SAVENT (DSR entry address) MOV *R0+,@>8354 Get Device Name length MOV *R0+,@>8356 Get pointer to Device Name or * Subprogram in PAB MOV *R0,R1 Get DSR Version Number SBO >00 Open CARD CB @>4000,@HAA Valid Indentifier? JNE NODSR No, Error Code 0 = * Bad Device Name BL *R9 Execute DSR JMP NODSR Execute this jump if DSR error * and issue Error Code 0 = * Bad Device Name SBZ >00 Otherwise, close CARD * NOW CHECK IF ANY DSR ERROR OCCURRED LWPI DSRLWS Load back LOADER workspace MOV @FLGPTR,R0 Get back pointer to PAB+1 JMP FRMDSR - 2008.8.15 - Keep on as * - 2008.8.15 - with a Normal DSRLNK * DSRLNK code ends here!