* RANDOM - RANDOM FILE MANAGER FOR SK*DOS * (C) 1985 BY PETER A. STARK * SYSTEM EQUATES CAC0 SIRFCB EQU $CAC0 CC02 TTYEOL EQU $CC02 CC0E SYSMTH EQU $CC0E CC10 SYSYR EQU $CC10 CC20 ERRTYP EQU $CC20 CC2B MEMEND EQU $CC2B CD03 WARMS EQU $CD03 CD1E PSTRNG EQU $CD1E CD27 NXTCH EQU $CD27 CD57 INTIME EQU $CD57 D406 FMS EQU $D406 DD40 VECTRS EQU $DD40 DD66 FMS0R EQU VECTRS+$26 DD68 FMS0W EQU VECTRS+$28 DD6A F0PUT EQU VECTRS+$2A DD6C F0FERA EQU VECTRS+$2C DD6E FMS9 EQU VECTRS+$2E DD70 FMS10 EQU VECTRS+$30 DD72 GRABIT EQU VECTRS+$32 DD74 SUMNAM EQU VECTRS+$34 * FILE CONTROL BLOCK EQUATES 0000 FCBFUN EQU 0 FUNCTION CODE 0001 FCBERR EQU 1 ERROR CODE 0002 FCBRW EQU 2 READ/WRITE/UPDATE STATUS 0003 FCBDRV EQU 3 DRIVE NUMBER 0004 FCBNAM EQU 4 FILE NAME (8 CHARS) 0011 FCBFTR EQU 17 FIRST TRACK OF FILE 0013 FCBLTR EQU 19 LAST TRACK OF FILE 0015 FCBSIZ EQU 21 2-BYTE FILE SIZE IN SECTORS 0017 FCBRAN EQU 23 RANDOM INDICATOR (0=SEQ) 0018 FCBTIM EQU 24 POSSIBLE TIME BYTE 0019 FCBMON EQU 25 MONTH 001B FCBYR EQU 27 YEAR 001E FCBCTR EQU 30 CURRENT TRACK IN BUFFER 0020 FCBCRN EQU 32 2-BYTE CURRENT RECORD NUMBER 0022 FCBDPT EQU 34 DATA POINTER TO NEXT BYTE (4-255) 0023 FCBRIN EQU 35 RANDOM FILE INDEX POINTER (4-255) 002F FCBDIT EQU 47 DIRECTORY TRACK (0- ) 0031 FCBDIB EQU 49 DIRECTORY STARTING BYTE INDEX 003B FCBSCF EQU 59 SPACE COMPR FLAG (0=COMPR, FF=NO) 003C FCBSPT EQU 60 SECTORS PER TRACK (FOR RANDOM) 003D FCBTMP EQU 61 TEMPORARY STORAGE 003F FCBUPD EQU 63 GLOBAL UPDATED FILE FLAG 0040 FCBDAT EQU 64 BEGINNING OF DATA C100 ORG $C100 C100 20 01 START BRA START1 C102 02 FCB 2 VERSION * START BY CHECKING WHETHER RANDOM HAS ALREADY BEEN LOADED C103 CE DD40 START1 LDU #VECTRS C106 EC C4 LDD 0,U CHECK FLAG C108 1083 5241 CMPD #$5241 IS IT ALREADY INSTALLED? C10C 26 2C BNE NORAN NO * YES, ALREADY LOADED C10E 8E C117 LOADED LDX #YESMSG C111 BD CD1E JSR PSTRNG PRINT "RAN PREV LOADED" C114 7E CD03 JMP WARMS C117 52 41 4E 44 YESMSG FCC 'RANDOM HAS BEEN PREVIOUSLY LOADED.',4 C11B 4F 4D 20 48 C11F 41 53 20 42 C123 45 45 4E 20 C127 50 52 45 56 C12B 49 4F 55 53 C12F 4C 59 20 4C C133 4F 41 44 45 C137 44 2E 04 * IS THIS THE CORRECT VERSION OF SK*DOS? C13A 1083 2525 NORAN CMPD #$2525 IS IT CORRECT VERSION? C13E 27 33 BEQ CHKHYP YES, GO CHECK ASTERISK IN PROMPT * NO, INCORRECT VERSION - CAN'T LOAD C140 8E C149 LDX #BVEMSG C143 BD CD1E JSR PSTRNG PRINT "BAD VERSION" C146 7E CD03 JMP WARMS C149 54 48 49 53 BVEMSG FCC 'THIS IS NOT THE CORRECT VERSION OF SK*DOS',4 C14D 20 49 53 20 C151 4E 4F 54 20 C155 54 48 45 20 C159 43 4F 52 52 C15D 45 43 54 20 C161 56 45 52 53 C165 49 4F 4E 20 C169 4F 46 20 53 C16D 4B 2A 44 4F C171 53 04 * CHECK HYPHEN IN PROMPT C173 7F C21C CHKHYP CLR ASTER ERASE ASTERISK ADDRESS MEMORY C176 7F C21D CLR ASTER+1 C179 8E CD80 LDX #$CD80 POINT TO SK*DOS C17C 108E C1B3 LDY #PROMPT POINT TO PROMPT STRING C180 EC 84 MLOOP LDD 0,X GET 'SK' BYTES FROM SK*DOS C182 10A3 A4 CMPD 0,Y CHECK AGAINST PROMPT STRING C185 26 23 BNE NMATCH IF NO MATCH C187 A6 03 LDA 3,X CHECK 'D' C189 A1 23 CMPA 3,Y C18B 26 1D BNE NMATCH C18D EC 04 LDD 4,X CHECK 'OS' C18F 10A3 24 CMPD 4,Y C192 26 16 BNE NMATCH C194 EC 06 LDD 6,X CHECK ': ' C196 10A3 26 CMPD 6,Y C199 26 0F BNE NMATCH * WHEN MATCH IS FOUND, SAVE ADDRESS OF ASTERISK C19B 30 02 LEAX 2,X POINT TO ASTERISK C19D BF C21C STX ASTER SAVE ADDRESS OF ASTERISK C1A0 A6 84 LDA 0,X GET THE ASTERISK C1A2 81 3D CMPA #'= BETTER NOT BE EQUALS C1A4 1027 FF66 LBEQ LOADED IF IT IS, THEN ALREADY LOADED C1A8 20 12 BRA LODRAN ELSE GO LOAD RANDOM ROUTINES * WHEN NO MATCH IS FOUND, STEP TO NEXT C1AA 30 01 NMATCH LEAX 1,X C1AC 8C CE80 CMPX #$CE80 CHECK IF TOO FAR C1AF 26 CF BNE MLOOP NO C1B1 20 09 BRA LODRAN GO LOAD IF NOTHING FOUND C1B3 53 4B 2A 44 PROMPT FCC 'SK*DOS: ' C1B7 4F 53 3A 20 C1BB 20 * NOT PREVIOUSLY LOADED, BUT CORRECT VERSION C1BC FC CC2B LODRAN LDD MEMEND GET CURRENT MEMEND C1BF 83 C818 SUBD #CEND C1C2 C3 C21E ADDD #CSTART COMPUTE NEW C1C5 C4 F0 ANDB #$F0 16-BYTE BOUNDARY C1C7 1F 02 TFR D,Y POINT Y TO IT C1C9 83 0001 SUBD #1 MEMEND IS ONE LESS C1CC FD CC2B STD MEMEND SET NEW MEMEND * MOVE RANDOM TO ITS PLACE C1CF 8E C21E LDX #CSTART POINT TO BEGINNING C1D2 A6 80 RANMOV LDA 0,X+ C1D4 A7 A0 STA 0,Y+ MOVE A BYTE C1D6 8C C610 CMPX #CLAST AT LAST INSTRUCTION? C1D9 26 F7 BNE RANMOV NO, DO NEXT * NOW ALL IS MOVED, SET UP VECTORS C1DB C6 0C LDB #12 NUMBER OF VECTORS C1DD 33 42 LEAU 2,U POINT U TO FIRST VECTOR C1DF BE CC2B LDX MEMEND AND WHERE THEY POINT C1E2 30 01 LEAX 1,X POINT TO ACTUAL BEGINNING C1E4 86 7E LDA #$7E JMP INSTRUCTION C1E6 A7 C0 VECLOO STA 0,U+ PUT IN JUMP C1E8 AF C1 STX 0,U++ AND ADDRESS C1EA 30 03 LEAX 3,X NEXT ADDRESS C1EC 5A DECB CHECK COUNTER C1ED 26 F7 BNE VECLOO AND REPEAT C1EF CC C815 LDD #BLANK3 CALCULATE WHERE 3 BLANKS WILL GO C1F2 83 C21E SUBD #CSTART C1F5 F3 CC2B ADDD MEMEND C1F8 C3 0001 ADDD #1 THIS IS ITS ADDRESS C1FB 1F 01 TFR D,X POINT TO IT C1FD 6F 80 CLR 0,X+ C1FF 6F 80 CLR 0,X+ ZERO THREE BYTES C201 6F 80 CLR 0,X+ C203 BE CC2B LDX MEMEND POINT TO TOP OF USABLE MEM C206 30 01 LEAX 1,X THEN TO BEGINNING OF RANDOM PROGRAM C208 AD 84 JSR 0,X GO INITIALIZE * NOW SET UP FLAGS AND * AND CHANGE ASTERISK TO EQUALS IF ALL OK SO FAR C20A CC 5241 LDD #$5241 LETTERS RA C20D FD DD40 STD VECTRS STORE INTO SK*DOS C210 BE C21C LDX ASTER GET ADDRESS OF ASTERISK C213 27 04 BEQ DONE DO NOTHING IF ZERO C215 86 3D LDA #'= ELSE GET EQUALS C217 A7 84 STA 0,X PUT IT IN C219 7E CD03 DONE JMP WARMS AND QUIT C21C 0000 ASTER FDB 0 MEMORY FOR ADDRESS OF ASTERISK * RANDOM CODE FOLLOWS C21E CSTART EQU * RANDOM CODE FOLLOWS * VECTORS TO ROUTINES, STARTING AT MEMEND+1 >C21E 16 0026 LBRA RANCLS INITIALIZE RANDOM ROUTINES >C221 16 0030 LBRA RAN0R RANDOM READ >C224 16 0041 LBRA RAN0W1 RANDOM WRITE PART 1 >C227 16 0047 LBRA RAN0W2 RANDOM WRITE PART 2 C22A 16 00A0 LBRA RAN0W3 RANDOM WRITE PART 3 C22D 16 01DB LBRA RAN3 RANDOM OPEN FILE FOR UPDATE C230 16 025F LBRA RAN4 RANDOM CLOSE FILE C233 16 0207 LBRA RAN17 GET RANDOM BYTE C236 16 0212 LBRA RAN18 PUT RANDOM BYTE C239 16 02BF LBRA RAN21 POSITION TO RECORD N C23C 16 0234 LBRA RAN22 BACKUP ONE RECORD C23F 16 0355 LBRA RAN23 POSITION / EXTEND FILE C242 A7 84 DOFMS STA FCBFUN,X STORE INTO FUNCTION CODE AND ... C244 7E D406 JMP FMS ...GO TO FMS * RANCLS - GO CLEAR FILE MAP MEMORY ON FMSCLS C247 6F 8D 03C5 RANCLS CLR FCBADD,PCR C24B 6A 8D 03C1 DEC FCBADD,PCR MAKE IT FFXX C24F 6F 8D 03C2 CLR FMTRSE,PCR AND TRACK 00 C253 39 RTS C254 6D 88 17 RAN0R TST FCBRAN,X CHECK IF RANDOM C257 27 0E BEQ RF0REX NO, JUST EXIT C259 6D 02 TST FCBRW,X HAS IT BEEN UPDATED? C25B 2A 6E BPL RF0KEX NO, JUST CONTINUE C25D A6 02 LDA FCBRW,X GET STATUS BYTE C25F 84 0F ANDA #$0F ERASE UPDATE FLAG C261 A7 02 STA FCBRW,X PUT IT BACK C263 AD 9F DD70 JSR [FMS10] YES, WRITE IT BACK C267 39 RF0REX RTS THEN RETURN * FMS0 WRITE * PART 1 OF FMS0 - WRITE: * SPACE COMPRESSION IS NOT ALLOWED ON RANDOM FILES * IF FILE IS RANDOM, THEN KILL SPACE COMPRESSION * WE COME HERE DIRECTLY AFTER A TST FCBRAN,X INSTRUCTION C268 27 06 RAN0W1 BEQ NOTW1R IF IT IS NOT RANDOM C26A C6 FF LDB #$FF IT IS A RANDOM FILE C26C E7 88 3B STB FCBSCF,X TURN OFF SPACE COMPRESSION C26F 5F CLRB CLEAR ERROR FLAG C270 39 NOTW1R RTS AND RETURN * PART 2 OF FMS0 - WRITE: * ON FIRST WRITE TO A NEW FILE, GET SECTORS PER TRACK, * SET UP TWO EMPTY FILE MAP SECTORS, AND PUT FIRST SECTOR * INTO FILE MAP C271 6D 88 17 RAN0W2 TST FCBRAN,X IS IT RANDOM? C274 26 01 BNE ISR0W2 YES C276 39 R0W2EX RTS NO, EXIT C277 A6 03 ISR0W2 LDA FCBDRV,X GET DRIVE NUMBER C279 B7 CAC3 STA SIRFCB+FCBDRV PUT INTO SIR FCB C27C AD 9F DD74 JSR [SUMNAM] C280 26 F4 BNE R0W2EX EXIT ON ERROR C282 B6 CADB LDA SIRFCB+27 GET SECTORS PER TRACK C285 A7 88 3C STA FCBSPT,X PUT INTO FCB C288 31 88 40 LEAY FCBDAT,X POINT TO DATA AREA C28B 5F CLRB C28C 6F A0 ISR0E2 CLR 0,Y+ ERASE FIRST SECTOR C28E 5A DECB C28F 26 FB BNE ISR0E2 C291 AD 9F DD72 JSR [GRABIT] GET SECOND SECTOR C295 26 DF BNE R0W2EX C297 EC 88 13 LDD FCBLTR,X GET ITS TR-SEC C29A ED 88 40 STD FCBDAT,X PUT IT INTO FIRST SECTOR C29D AD 9F DD70 JSR [FMS10] WRITE 1ST TO DISK C2A1 26 D3 BNE R0W2EX C2A3 EC 88 13 LDD FCBLTR,X C2A6 ED 88 1E STD FCBCTR,X SECOND IS NOW CURRENT C2A9 AD 9F DD72 JSR [GRABIT] GET THIRD SECTOR C2AD 26 C7 BNE R0W2EX C2AF EC 88 13 LDD FCBLTR,X GET ITS TR-SEC C2B2 ED 88 40 STD FCBDAT,X PUT INTO SECOND C2B5 AD 9F DD70 JSR [FMS10] WRITE SECOND SECTOR C2B9 26 BB BNE R0W2EX C2BB EC 88 13 LDD FCBLTR,X C2BE ED 88 1E STD FCBCTR,X THIRD IS NOW CURRENT C2C1 CC 0002 LDD #2 C2C4 ED 88 15 STD FCBSIZ,X SET FILE SIZE C2C7 8D 12 BSR PUTINM PUT CURRENT SECTOR INTO MAP C2C9 26 AB BNE R0W2EX C2CB 4F RF0KEX CLRA CLEAR ERROR FLAG C2CC 39 RTS AND RETURN TO FMS0 * PART 3 OF FMS0 - WRITE * EACH TIME A SECTOR IS WRITTEN, UPDATE THE FILE MAP * TO INCLUDE THE NEW ONE C2CD 6D 88 17 RAN0W3 TST FCBRAN,X IS IT RANDOM? C2D0 26 01 BNE ISR0W3 YES C2D2 39 R0W3EX RTS NO, RETURN C2D3 8D 06 ISR0W3 BSR PUTINM UPDATE MAP, IGNORE ERRORS C2D5 32 62 LEAS 2,S REMOVE JSR ADDRESS C2D7 6E 9F DD6C JMP [F0FERA] AND RETURN * PUTINM - SUBROUTINE TO PUT CURRENT SECTOR INTO MAP C2DB EC 88 1E PUTINM LDD FCBCTR,X C2DE ED 88 3D STD FCBTMP,X SAVE CURRENT TRACK AS TEMP C2E1 17 00BD LBSR RDFMAP READ FILE MAP C2E4 26 4F BNE PUTEX IF ERROR * CHECK FIRST ENTRY C2E6 31 8D 0333 ROWUP1 LEAY FILMAP,PCR Y-> FIRST ENTRY C2EA EC A4 LDD 0,Y CHECK IT C2EC 27 4E BEQ MAKNEW EMPTY, PUT NEW IN * FIND LAST NON-EMPTY C2EE EC 23 FINLAS LDD 3,Y CHECK NEXT C2F0 27 04 BEQ GOTLAS NOW ON LAST ENTRY C2F2 31 23 LEAY 3,Y NOT LAST, GO TO NEXT C2F4 20 F8 BRA FINLAS ELSE CHECK NEXT * CALCULATE NEXT SECTOR AFTER LAST ENTRY C2F6 EC A4 GOTLAS LDD 0,Y GET TRACK AND SECTOR C2F8 34 02 PSHS A TRACK ON STACK C2FA A6 22 LDA 2,Y GET COUNT C2FC 81 FF CMPA #255 IS IT FULL? C2FE 26 04 BNE NOTFUL NO, CONTINUE C300 35 02 PULS A YES, FIX STACK AND THEN C302 20 19 BRA GO2NEW START NEW ENTRY C304 5C NOTFUL INCB BUMP SECTOR # C305 E1 88 3C CMPB FCBSPT,X PAST END OF TRACK?> C308 23 04 BLS ONTRAK NO, STILL ON TRACK C30A C6 01 LDB #1 YES, START NEW TRACK C30C 6C E4 INC 0,S C30E 4A ONTRAK DECA BUMP COUNTER C30F 26 F3 BNE NOTFUL C311 35 02 PULS A GET BACK TRACK * D NOW HAS TRACK AND SECTOR AFTER LAST ENTRY C313 10A3 88 3D CMPD FCBTMP,X IS IT SAME AS CURRENT? C317 26 04 BNE GO2NEW NO, GO MAKE A NEW ENTRY C319 6C 22 INC 2,Y YES, BUMP COUNTER TO PUT IT IN C31B 20 28 BRA PUTBAK * GO TO A NEW ENTRY, BUT CHECK IF FULL C31D 31 23 GO2NEW LEAY 3,Y GO TO NEXT ENTRY C31F 34 10 PSHS X SAVE X C321 30 8D 04F0 LEAX FMP504,PCR POINT TO FILE MAP + 504 C325 34 10 PSHS X SAVE ADDRESS ON STACK C327 10AC E1 CMPY 0,S++ PAST END? C32A 35 10 PULS X RESTORE X C32C 25 0E BLO MAKNEW IF OK C32E C6 17 ERR23 LDB #23 ELSE IT'S ERROR 23 C330 F7 CC20 STB ERRTYP C333 E7 01 STB FCBERR,X ALSO INTO FCB C335 EC 88 3D PUTEX LDD FCBTMP,X C338 ED 88 1E STD FCBCTR,X RESTORE CURRENT TRACK C33B 39 RTS * MAKE A NEW ENTRY WITH COUNT OF 1 C33C EC 88 3D MAKNEW LDD FCBTMP,X GET CURRENT TRACK-SEC C33F ED A4 STD 0,Y PUT IN MAP C341 C6 01 LDB #1 C343 E7 22 STB 2,Y * NOW FIGURE OUT WHICH SECTOR WAS MODIFIED AND WRITE IT BACK C345 30 8D 03D0 PUTBAK LEAX FMP252,PCR POINT TO BEG OF SECOND SECTOR C349 34 10 PSHS X SAVE ON STACK C34B 10AC E1 CMPY 0,S++ COMPARE IT C34E 25 25 BLO WRITE1 WRITE FIRST * WRITE OUT SECOND SECTOR ONLY C350 30 8D 03C5 LEAX FILMAP+252,PCR FILE MAP C354 10AE 8D 02B7 LDY FCBADD,PCR ADDRESS OF FCB C359 31 A8 40 LEAY FCBDAT,Y POINT TO DATA AREA OF FCB C35C EC 8D 02B7 LDD HDR2,PCR FIRST TWO BYTES OF HEADER C360 ED A1 STD 0,Y++ PUT INTO FCB C362 6F A0 CLR 0,Y+ ALWAYS ZERO RECORD COUNT C364 6F A0 CLR 0,Y+ C366 C6 FC LDB #252 C368 A6 80 MOVE2 LDA 0,X+ GET A BYTE C36A A7 A0 STA 0,Y+ PUT IT IN C36C 5A DECB C36D 26 F9 BNE MOVE2 REPEAT UNTIL DONE C36F AE 8D 029D LDX FCBADD,PCR POINT TO FCB C373 20 1E BRA WRITIT GO WRITE IT * WRITE FIRST SECTOR ONLY C375 30 8D 02A0 WRITE1 LEAX HDR1,PCR FILE MAP C379 10AE 8D 0292 LDY FCBADD,PCR ADDRESS OF FCB C37E 31 A8 40 LEAY 64,Y DATA AREA C381 5F CLRB COUNTER = 256 C382 A6 80 MOVE1 LDA 0,X+ C384 A7 A0 STA 0,Y+ PUT IT IN C386 5A DECB C387 26 F9 BNE MOVE1 REPEAT UNTIL DONE C389 AE 8D 0283 LDX FCBADD,PCR POINT TO FCB C38D EC 88 11 LDD FCBFTR,X T-S OF MAP C390 ED 88 1E STD FCBCTR,X C393 AD 9F DD70 WRITIT JSR [FMS10] WRITE IT BACK C397 26 9C BNE PUTEX C399 EC 88 3D LDD FCBTMP,X C39C ED 88 1E STD FCBCTR,X RESTORE CURRENT TRACK C39F 4F CLRA CLEAR ERROR C3A0 39 RTS * RDFMAP SUBROUTINE - READS FILE MAP * INTO MEMORY IF NOT ALREADY THERE. ON ENTRY AND * EXIT, X-> TO FCB C3A1 A6 03 RDFMAP LDA FCBDRV,X DRIVE NUMBER C3A3 10AE 88 11 LDY FCBFTR,X FIRST TR-SEC C3A7 AC 8D 0265 CMPX FCBADD,PCR CHECK IF THERE? C3AB 26 0D BNE RFMNO NO C3AD A1 8D 0261 CMPA FMDRV,PCR CHECK AGAIN C3B1 26 07 BNE RFMNO NO C3B3 10AC 8D 025D CMPY FMTRSE,PCR CHECK ONE MORE TIME C3B8 27 17 BEQ RFMEX YES! * IF NOT YET IN MEMORY, READ IT C3BA AF 8D 0252 RFMNO STX FCBADD,PCR STORE DATA C3BE A7 8D 0250 STA FMDRV,PCR C3C2 10AF 8D 024E STY FMTRSE,PCR C3C7 10AF 88 1E STY FCBCTR,X 1ST SECTOR OF MAP C3CB AD 9F DD6E JSR [FMS9] READ IT C3CF 27 01 BEQ RFMNOK IF OK C3D1 39 RFMEX RTS IF NOT OK C3D2 31 8D 0243 RFMNOK LEAY HDR1,PCR POINT TO FILE MAP C3D6 5F CLRB COUNTER = 256 C3D7 30 88 40 LEAX FCBDAT,X POINT TO DATA C3DA A6 80 RDFML1 LDA 0,X+ GET A BYTE C3DC A7 A0 STA 0,Y+ PUT INTO MAP C3DE 5A DECB C3DF 26 F9 BNE RDFML1 C3E1 AE 8D 022B LDX FCBADD,PCR BACK TO FCB C3E5 EC 88 40 LDD FCBDAT,X POINTER TO SECOND C3E8 ED 88 1E STD FCBCTR,X IS CURRENT C3EB AD 9F DD6E JSR [FMS9] READ SECOND SECTOR C3EF 26 E0 BNE RFMEX IF ERROR C3F1 30 88 40 LEAX FCBDAT,X POINT TO DATA C3F4 EC 81 LDD 0,X++ FIRST TWO BYTES OF HEADER C3F6 ED 8D 021D STD HDR2,PCR SAVE THEM C3FA 30 02 LEAX 2,X SKIP NEXT TWO BYTES C3FC C6 FC LDB #252 COUNTER C3FE A6 80 RDFML2 LDA 0,X+ GET A BYTE C400 A7 A0 STA 0,Y+ PUT INTO MAP C402 5A DECB C403 26 F9 BNE RDFML2 REPEAT UNTIL DONE C405 AE 8D 0207 LDX FCBADD,PCR POINT BACK TO FCB C409 4F CLRA CLEAR ERROR CONDITION C40A 39 RTS AND THEN EXIT * RAN3 - OPEN FOR UPDATE * RETURNS FCBFUN=0, READY TO READ C40B 34 06 RAN3 PSHS A,B C40D 86 01 LDA #1 CHANGE OP CODE 3 TO OP CODE 1 C40F 17 FE30 LBSR DOFMS GO OPEN FILE FOR READ C412 27 06 BEQ OPUPOK IF NO ERROR C414 86 03 RAN3ER LDA #3 CHANGE OP CODE 1 TO OP CODE 3 C416 A7 84 STA FCBFUN,X C418 35 86 RAN3EX PULS A,B,PC AND QUIT ON ERROR C41A 86 03 OPUPOK LDA #3 CHANGE OP CODE 1 TO OP CODE 3 C41C A7 84 STA FCBFUN,X C41E 6D 88 17 TST FCBRAN,X IS IT RANDOM? C421 26 09 BNE FINRA3 YES, FINISH C423 C6 13 LDB #19 NO, ERROR 19 C425 F7 CC20 STB ERRTYP C428 E7 01 STB FCBERR,X AND INTO FCB C42A 35 86 PULS A,B,PC AND EXIT * IF NO ERROR, CONTINUE C42C 86 03 FINRA3 LDA #3 SIGNIFY OPEN FOR UPDATE BUT NOT YET UPDATED C42E A7 02 STA FCBRW,X C430 6F 84 CLR FCBFUN,X CHANGE OP CODE TO 0 C432 BD D406 JSR FMS GO READ ONE BYTE FROM FILE C435 26 DD BNE RAN3ER EXIT ON ERROR C437 6A 88 22 DEC FCBDPT,X THEN UNDO THE BYTE JUST READ C43A 4F CLRA CLEAR ERROR FLAG C43B 35 86 PULS A,B,PC * RAN 17 - GET RANDOM BYTE FROM FILE C43D 34 14 RAN17 PSHS B,X C43F E6 88 23 LDB FCBRIN,X GET RANDOM POINTER C442 30 88 40 LEAX FCBDAT,X POINT TO DATA AREA C445 3A ABX ADD POINTER TO X C446 A6 84 LDA 0,X GET BYTE FROM FCB C448 5F CLRB CLEAR ERROR FLAG C449 35 94 PULS B,X,PC AND RETURN * RAN18 - PUT RANDOM BYTE INTO FILE C44B 34 14 RAN18 PSHS B,X C44D E6 02 LDB FCBRW,X CHECK FOR UPDATE STATUS C44F C4 7F ANDB #$7F C451 C1 03 CMPB #3 CHECK FOR 3 OR 83 C453 26 15 BNE ERR1 ERROR 1 IF NOT OPEN FOR UPDATE C455 E6 88 23 LDB FCBRIN,X GET RANDOM POINTER C458 30 88 40 LEAX FCBDAT,X POINT TO DATA AREA C45B 3A ABX ADD POINTER TO X C45C A7 84 STA 0,X PUT BYTE INTO FCB C45E AE 61 LDX 1,S POINT BACK TO FCB C460 C6 83 LDB #$83 SIGNAL UPDATED SECTOR C462 E7 02 STB FCBRW,X PUT BACK C464 E7 88 3F STB FCBUPD,X ALSO SIGNAL GLOBAL UPDATE C467 5F CLRB CLEAR ERROR C468 35 94 PULS B,X,PC AND RETURN C46A C6 01 ERR1 LDB #1 C46C F7 CC20 STB ERRTYP C46F E7 01 STB FCBERR,X ALSO INTO FCB C471 35 94 PULS B,X,PC AND RETURN * RAN 22 - BACKUP ONE RECORD C473 6D 88 17 RAN22 TST FCBRAN,X CHECK IF RANDOM C476 26 0B BNE RAN22A YES, OK TO DO C478 34 02 ERR19 PSHS A C47A 86 13 LDA #19 ERROR 19 - FILE NOT RANDOM C47C A7 01 STA FCBERR,X C47E B7 CC20 STA ERRTYP STORE ERROR C481 35 82 PULS A,PC AND EXIT C483 34 06 RAN22A PSHS A,B C485 EC 88 20 LDD FCBCRN,X CURRENT RECORD NUMBER C488 83 0001 SUBD #1 BACKUP ONE C48B ED 88 20 STD FCBCRN,X C48E 35 06 PULS D C490 20 69 BRA RAN21 GO SEEK TO IT * RAN 4 - CLOSE FILE * WHEN DOING RANDOM FILE, WRITE CURRENT SECTOR OUT IF * MODIFIED, AND DELETE FILE MAP FROM MEMORY C492 6D 88 17 RAN4 TST FCBRAN,X IS IT RANDOM? C495 27 4F BEQ R4RTS NO, EXIT C497 AC 8D 0175 RAN4B CMPX FCBADD,PCR CHECK IF THE SAME C49B 26 03 BNE RAN4C DIFFERENT C49D 17 FDA7 LBSR RANCLS CLEAR MAP MEMORY C4A0 8D 45 RAN4C BSR WRUPDA WRITE OUT SECTOR IF UPDATED C4A2 26 42 BNE R4RTS IF ERROR C4A4 6D 88 3F TST FCBUPD,X HAS FILE BEEN UPDATED? C4A7 27 3C BEQ RAN4EX NO, SO QUIT * IF FILE HAS BEEN UPDATED, THEN ALSO CHANGE DATE C4A9 86 01 LDA #1 C4AB 17 FD94 LBSR DOFMS GO OPEN FILE FOR READING C4AE 26 36 BNE R4RTS QUIT ON ERROR C4B0 86 04 LDA #4 C4B2 17 FD8D LBSR DOFMS IMMEDIATELY CLOSE IT AGAIN C4B5 26 2F BNE R4RTS QUIT ON ERROR C4B7 EC 88 2F LDD FCBDIT,X TR-SEC OF DIRECTORY ENTRY C4BA ED 88 1E STD FCBCTR,X CURRENT TR-SEC C4BD AD 9F DD6E JSR [FMS9] GO READ DIRECTORY SECTOR C4C1 26 23 BNE R4RTS ON ERROR C4C3 E6 88 31 LDB FCBDIB,X POINT TO DIRECTORY ENTRY C4C6 1F 12 TFR X,Y Y-> TO FCB C4C8 30 88 40 LEAX FCBDAT,X POINT TO DATA AREA OF FCB C4CB 3A ABX X-> FILE NAME IN FCB C4CC 1E 12 EXG X,Y EXCHANGE THEM C4CE FC CC0E LDD SYSMTH TODAY'S DATE C4D1 ED A8 15 STD FCBMON-FCBNAM,Y C4D4 B6 CC10 LDA SYSYR C4D7 A7 A8 17 STA FCBYR-FCBNAM,Y C4DA 4F CLRA C4DB BD CD57 JSR INTIME POSSIBLY INPUT TIME CODE ALSO C4DE A7 A8 14 STA FCBTIM-FCBNAM,Y C4E1 6E 9F DD70 JMP [FMS10] WRITE IT BACK TO DISK AND RETURN C4E5 4F RAN4EX CLRA CLEAR ERROR CONDITION C4E6 39 R4RTS RTS AND THEN EXIT * IF CURRENT SECTOR HAS BEEN UPDATED, WRITE IT OUT C4E7 6D 02 WRUPDA TST FCBRW,X UPDATED SECTOR? C4E9 2A 0E BPL WRUPEX NO, EXIT C4EB A6 02 LDA FCBRW,X GET STATUS BYTE C4ED A7 88 3F STA FCBUPD,X SET FILE UPDATE FLAG C4F0 84 0F ANDA #$0F ERASE UPDATED FLAG C4F2 A7 02 STA FCBRW,X PUT IT BACK C4F4 AD 9F DD70 JSR [FMS10] WRITE SECTOR BACK OUT AND RETURN C4F8 39 RTS C4F9 4F WRUPEX CLRA CLEAR ERROR FLAG C4FA 39 RTS * RAN 21 - POSITION TO RECORD N C4FB 6F 84 RAN21 CLR FCBFUN,X READY TO READ NEXT C4FD 6D 88 17 TST FCBRAN,X IS IT RANDOM? C500 1027 FF74 LBEQ ERR19 NO C504 34 36 PSHS A,B,X,Y SAVE REGISTERS C506 8D DF BSR WRUPDA WRITE OUT CURRENT IF UPDATED C508 26 1F BNE R21RTS IF ERROR C50A EC 88 20 RN2123 LDD FCBCRN,X GET DESIRED REC NO C50D 26 1C BNE GETREC WANT REAL RECORD * IF CRN=0, MEANS WANT MAP ONLY C50F EC 88 11 LDD FCBFTR,X POINT TO IT C512 ED 88 1E RAN21A STD FCBCTR,X IS CURRENT C515 AD 9F DD6E JSR [FMS9] GO READ IT C519 26 0E BNE R21RTS C51B 86 04 LDA #4 C51D A7 88 22 STA FCBDPT,X DATA POINTER = 4 C520 EC 88 42 LDD FCBDAT+2,X GET RECORD NUMBER C523 10A3 88 20 CMPD FCBCRN,X CHECK IT C527 26 65 BNE ERR25 IF DOESN'T MATCH C529 35 B6 R21RTS PULS A,B,X,Y,PC RESTORE REGISTERS AND EXIT * IF CRN>0, MEANS GET A REAL RECORD C52B C3 0002 GETREC ADDD #2 TOTAL NUMBER OF SECTORS IN FILE C52E 10A3 88 15 CMPD FCBSIZ,X COMPARE WITH ACTUAL FILE SIZE C532 22 3F BHI ERR24 BAD IF TOO LARGE C534 17 FE6A LBSR RDFMAP READ FILE MAP C537 26 F0 BNE R21RTS C539 31 8D 00E0 LEAY FILMAP,PCR POINT TO IT C53D EC 88 20 LDD FCBCRN,X GET DESIRED RECORD NUMBER * NOW LOOP THROUGH MAP UNTIL WE FIND IT C540 6D 22 CKNEXT TST 2,Y CHECK COUNT C542 27 2F BEQ ERR24 BAD NUMBER C544 E0 22 SUBB 2,Y SUBTRACT FROM D C546 82 00 SBCA #0 C548 81 FF CMPA #$FF BELOW ZERO? C54A 27 0A BEQ GET21 YES, GO GET IT C54C 1083 0000 CMPD #0 ZERO? C550 27 04 BEQ GET21 0000 IS OK ALSO C552 31 23 NOTZER LEAY 3,Y ELSE GO TO NEXT ENTRY C554 20 EA BRA CKNEXT * NOW CALCULATE NEXT ENTRY C556 EB 22 GET21 ADDB 2,Y FIX D C558 A6 A4 LDA 0,Y GET TRACK C55A 34 02 PSHS A ON STACK C55C A6 21 LDA 1,Y SECTOR C55E 5A ONEMOR DECB BUMP COUNTER C55F 27 0C BEQ NOWON C561 4C INCA BUMP SECTOR C562 A1 88 3C CMPA FCBSPT,X PAST END OF TRACK? C565 23 F7 BLS ONEMOR NO C567 86 01 LDA #1 YES, START NEXT TRACK C569 6C E4 INC 0,S NEXT TRACK C56B 20 F1 BRA ONEMOR REPEAT UNTIL DONE C56D 1F 89 NOWON TFR A,B C56F 35 02 PULS A D NOW HAS TRACK AND SECTOR ADDRESS C571 20 9F BRA RAN21A GO GET IT AND QUIT * ON TOO LARGE RECORD, RETURN FILE MAP FOR COMPATIBILITY C573 EC 88 11 ERR24 LDD FCBFTR,X ON REC TOO LARGE, POINT TO MAP C576 ED 88 1E STD FCBCTR,X C579 30 88 40 LEAX FCBDAT,X POINT TO DATA AREA C57C 31 8D 0099 LEAY HDR1,PCR AND TO HEADER AND DATA C580 5F CLRB COUNTER = 256 C581 A6 A0 E24MOV LDA 0,Y+ GET A BYTE OF DATA C583 A7 80 STA 0,X+ PUT INTO FCB C585 5A DECB C586 26 F9 BNE E24MOV C588 AE 62 LDX 2,S POINT BACK TO FCB C58A 86 18 LDA #24 REC NO TOO LARGE C58C 20 02 BRA ERR25A C58E 86 19 ERR25 LDA #25 REC NO DOESN'T MATCH C590 A7 01 ERR25A STA FCBERR,X C592 B7 CC20 STA ERRTYP C595 35 B6 PULS A,B,X,Y,PC AND QUIT * RAN 23 - POSITION TO RECORD N, BUT EXTEND FILE IF PAST END C597 6D 88 17 RAN23 TST FCBRAN,X IS IT RANDOM? C59A 1027 FEDA LBEQ ERR19 NO C59E 17 FF5A LBSR RAN21 TRY TO POSITION C5A1 26 01 BNE RAN23A IF THERE WAS AN ERROR C5A3 39 R23RTS RTS ELSE JUST EXIT IF SECTOR WAS FOUND C5A4 34 02 RAN23A PSHS A C5A6 A6 01 LDA FCBERR,X CHECK TYPE OF ERROR C5A8 81 18 CMPA #24 REQUESTED TOO LARGE? C5AA 35 02 PULS A C5AC 26 F5 BNE R23RTS NO, SOME OTHER KIND OF ERROR C5AE 34 36 PSHS A,B,X,Y C5B0 EC 88 20 LDD FCBCRN,X GET DESIRED RECORD NUMBER C5B3 ED 8D 005C STD CRNTMP,PCR TEMPORARILY SAVE IT C5B7 1083 A758 CMPD #42840 CHECK MAXIMUM SIZE C5BB 22 B6 BHI ERR24 BAD NUMBER * OK, WE NEED TO EXTEND THE FILE. FIRST GO READ LAST SECTOR C5BD EC 88 13 LDD FCBLTR,X LAST TR-SEC C5C0 ED 88 1E STD FCBCTR,X CURRENT TR-SEC C5C3 86 09 LDA #9 C5C5 A7 88 3F STA FCBUPD,X MARK FILE AS UPDATED C5C8 17 FC77 LBSR DOFMS GO READ IT C5CB 26 41 BNE R23EXI EXIT ON ERROR C5CD 86 02 LDA #2 C5CF A7 02 STA FCBRW,X STATUS BECOMES WRITE C5D1 A7 88 3F STA FCBUPD,X SET FILE UPDATE FLAG C5D4 6F 88 22 CLR FCBDPT,X POINT PAST END OF SECTOR C5D7 EC 88 42 LDD FCBDAT+2,X CURRENT RECORD NUMBER C5DA ED 88 20 STD FCBCRN,X * NOW START WRITING EMPTY SECTORS C5DD 4F R23SKP CLRA OP 0 AND WRITE A ZERO C5DE 17 FC61 LBSR DOFMS GO WRITE C5E1 26 2B BNE R23EXI EXIT ON ERROR C5E3 EC 88 20 LDD FCBCRN,X GET CURRENT RECORD NUMBER C5E6 10A3 8D 0028 CMPD CRNTMP,PCR COMPARE WITH DESIRED SECTOR C5EB 27 09 BEQ R23DON FINSH UP WHEN DONE C5ED 86 0F LDA #15 ELSE SKIP SECTOR C5EF 17 FC50 LBSR DOFMS SKIP SECTOR C5F2 26 1A BNE R23EXI ON ERROR C5F4 20 E7 BRA R23SKP * WHEN DONE, CLOSE AND REOPEN FILE C5F6 86 04 R23DON LDA #4 C5F8 17 FC47 LBSR DOFMS CLOSE THE FILE C5FB 26 11 BNE R23EXI EXIT ON ERROR C5FD 86 03 LDA #3 C5FF 17 FC40 LBSR DOFMS REOPEN FILE FOR UPDATING C602 26 0A BNE R23EXI EXIT ON ERROR C604 EC 8D 000B LDD CRNTMP,PCR C608 ED 88 20 STD FCBCRN,X RESTORE DESIRED RECORD NUMBER C60B 17 FEFC LBSR RN2123 SEEK BACK TO DESIRED SECTOR C60E 35 B6 R23EXI PULS A,B,X,Y,PC C610 CLAST EQU * MARKS LAST INSTRUCTION * DATA AREA C610 FCBADD RMB 2 ADDRESS OF FCB C612 FMDRV RMB 1 FILE MAP DRIVE C613 CRNTMP RMB 2 TEMPORARY CURRENT RECORD NUMBER C615 FMTRSE RMB 2 FILE MAP TR-SEC C617 HDR2 RMB 2 SECOND SECTOR HEADER C619 HDR1 RMB 4 FIRST SECTOR HEADER C61D FILMAP RMB 504 LATEST FILE MAP C815 BLANK3 RMB 3 MUST BE AFTER FILMAP, WILL BE 0! C719 FMP252 EQU FILMAP+252 BEGINNING OF SECOND SECTOR C815 FMP504 EQU FILMAP+504 END OF SECOND SECTOR C818 CEND EQU * END OF RANDOM ROUTINES END START