PAGE SBTTL "--- BOOT CODE & RWTS: APPLE II ---" ; --------- ; BOOT CODE ; --------- ; LOADS ALL OF TRACK 0 INTO RAM AT $800 TO $1800, ; THEN JUMPS THROUGH [COLD] ORG ZIP DB $01 ; MAGICAL MYSTERY BYTE ; BOOT BEGINS HERE BOOT: LDA BADDR+HI ; CHECK MSB OF BOOT ADDRESS CMP #$09 ; 1ST ENTRY INTO BOOT? BNE BT0 ; NO, CONTINUE ; CALC ADDRESS OF ROM SECTOR READ ROUTINE LDA BSLOT ; GET SLOT ID * 16 STA DCBSLT ; MAKE IT THE DEFAULT TARGET STA DCBPSL ; AND THE "OLD" SLOT LSR A ; DIVIDE BY 16 LSR A LSR A LSR A ORA #%11000000 ; MAKE IT $C0nn STA I+HI ; USE AS MSB OF ADDRESS LDA #$5C ; LSB IS ALWAYS $5C STA I+LO LDA #1 STA DCBSEC BT0: LDX DCBSEC INC DCBSEC CPX #$10 BCS BT1 LDA ILEAVE,X STA BSECT LDX BSLOT JMP (I) BT1: JSR INIT JMP COLD ; LOAD REMAINDER OF ZIP ; --------------------- ; SECTOR INTERLEAVE MAP ; --------------------- ; USED BY "BOOT" AND "RWTS" ; MUST BE IN 1ST PAGE! ILEAVE: DB $00,$04,$08,$0C,$01,$05,$09,$0D DB $02,$06,$0A,$0E,$03,$07,$0B,$0F ; INFOCOM'S VERSION OF APPLE RWTS (READ/WRITE TRACK/SECTOR) ; HACKED BY ANDREW KALUZNIACKI ; FROM THE DOS RWTS ON APPLE DOS 3.3 ; ------------ ; SPACE FILLER ; ------------ DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00 ; ------------------------------- ; MAIN ENTRY INTO INFO-DOS (IDOS) ; ------------------------------- ; [DCBSEC] SECTOR (0-15), SET BY CALLER ; [DCBTRK] TRACK (0-34), SET BY CALLER ; [DCBDRV] DRIVE (1 OR 2), SET BY CALLER [BOOT DEFAULT] ; [DCBSLT] SLOT*16, SET BY CALLER [BOOT DEFAULT] ; [DCBPSL] SLOT*16 OF LAST USED SLOT, SET BY BOOT ; [DCBPDR] LAST DRIVE USED (1 OR 2), SET BY BOOT ; [DCBCMD] STORAGE FOR COMMAND SENT IN AT CALL TO IDOS ; [DCBERR] IDOS ERROR CODE ; [DCBBFL] DISK BUFFER ADDRESS (LSB) [BOOT = IOBUFF] ; [DCBBFH] DISK BUFFER ADDRESS (MSB) [BOOT = IOBUFF] ; =1 WRITES DISK BUFFER ; =0 READS DISK BUFFER ; [IOBUFF] = 256-BYTE BUFFER FOR DISK I/O ; (OPTIONAL IF [DCBBFL/DCBBFH] ARE SET) ; [BUFFA] ONE PAGE BUFFER ; [BUFFB] $56 BYTE BUFFER ; CARRY CLEAR ON RETURN IF NO ERROR ; IF CARRY SET, ERROR CODE IS IN [DERR]: ; $10 = WRITE PROTECTED ; $40 = DRIVE ERROR ; $80 = READ ERROR ; *** WARNING *** ; IDOS MUST START ON A PAGE BOUNDARY. ; CHANGE ANY CODE BETWEEN [IDOS] AND [INIT] AT YOUR OWN RISK. ; YOU HAVE BEEN WARNED. IDOS: NOP NOP NOP ; DON'T ASK, AND DON'T CHANGE PHP ; SAVE STATUS OF [I] SEI ; DISABLE INTERUPTS JSR DOS ; DO IT (GO TO MAIN ROUTINE) BCS DOSERR ; ERROR OCCURED IF C=1 PLP ; RESTORE [I] CLC ; SET "NO ERROR" RTS ; RETURN FROM CALL DOSERR: PLP ; RESTORE [I] SEC ; INDICATE ERROR RTS ; EXIT ; PRE-NIBBLIZE [IOBUFF] BEFORE WRITING PRENIB: LDX #0 LDY #2 PREN0: DEY LDA (DCBBFL),Y LSR A ROL BUFFB,X LSR A ROL BUFFB,X STA BUFFA,Y INX CPX #$56 BCC PREN0 LDX #0 TYA BNE PREN0 LDX #$55 ; CLEAR BITS 7 AND 6 PREN1: LDA BUFFB,X ; OF TOP NIBBLE BUFFER AND #%00111111 STA BUFFB,X DEX BPL PREN1 RTS ; ------------ ; WRITE SECTOR ; ------------ ; WRITES PRENIBBLIZED DATA AT [BUFFA/BUFFB] TO DISK ; ENTRY: SLOT*16 IN [X] ; EXIT: CARRY SET IF ERROR WRTDTA: STX DTMP4 ; SAVE SLOT ID HERE STX SLTMP2 SEC ; SET CARRY FOR POSSIBLE ERROR LDA Q6H,X ; CHECK FOR WRITE-PROTECT LDA Q7L,X BMI WRT5 ; EXIT W/CARRY SET IF PROTECTED LDA BUFFB ; SAVE 1ST BYTE OF 2NDARY BUFFER STA DTMP3 ; FOR LATER LDA #$FF ; ESTABLISH AUTOSYNC BYTE STA Q7H,X ; SET DRIVE TO WRITE MODE ORA Q6L,X ; WAIT FOR HARDWARE TO SETTLE PHA PLA NOP LDY #4 ; WRITE 5 AUTOSYNC BYTES WRT1: PHA PLA JSR WRBYT2 ; USING 40 uS DELAY DEY BNE WRT1 LDA #$D5 ; WRITE DATA FIELD PROLOGUE: JSR WRBYT1 ; $D5-$AA-$AD LDA #$AA JSR WRBYT1 LDA #$AD JSR WRBYT1 TYA ; A BRIEF DELAY LDY #$56 ; INIT LOOP INDEX BNE WRT3 ; BRANCH ALWAYS ; WRITE [BUFFB] TO DISK WRT2: LDA BUFFB,Y ; GET A BYTE FROM [BUFFB] WRT3: EOR BUFFB-1,Y TAX ; USE IT AS AN INDEX LDA WRTTBL,X ; INTO THE TRANSLATE TABLE LDX DTMP4 ; RESTORE SLOT ID STA Q6H,X ; AND WRITE THE TRANSLATED BYTE LDA Q6L,X DEY ; LOOP TILL BNE WRT2 ; EMPTY ; WRITE [BUFFA] TO DISK LDA DTMP3 ; RESTORE "LOST" [BUFFB] BYTE NOP ; WAIT JUST A MOMENT ... WRT4: EOR BUFFA,Y ; GET A BYTE FROM [BUFFA] TAX ; USE IT AS AN INDEX LDA WRTTBL,X ; INTO THE TRANSLATE TABLE LDX SLTMP2 ; RESTORE SLOT ID STA Q6H,X ; AND WRITE THE TRANSLATED BYTE LDA Q6L,X LDA BUFFA,Y ; GET NEXT BYTE FROM BUFFER INY ; AND LOOP TILL BNE WRT4 ; ALL OF [BUFFA] IS WRITTEN TAX LDA WRTTBL,X LDX DTMP4 ; RESTORE SLOT ID JSR WRBYT3 ; AND WRITE THE LAST [BUFFA] BYTE LDA #$DE ; WRITE DATA FIELD EPILOGUE: JSR WRBYT1 ; $DE-$AA-$EB LDA #$AA JSR WRBYT1 LDA #$EB JSR WRBYT1 LDA #$FF ; WRITE GAP 3 JSR WRBYT1 LDA Q7L,X ; SET DRIVE TO READ MODE WRT5: LDA Q6L,X RTS ; ---------------------------- ; WRITE A BYTE (TIME-CRITICAL) ; ---------------------------- ; ENTRY: BYTE TO WRITE IN [A] ; SLOT*16 IN [X] WRBYT1: CLC ; PROLOGUE, EPILOGUE AND GAP 3 TIMING WRBYT2: PHA ; ENTRY FOR GAP 2 TIMING PLA WRBYT3: STA Q6H,X ORA Q6L,X RTS ; CONVERT RAW DATA TO BINARY IN [IOBUFF] POSTNB: LDY #0 PST0: LDX #$56 PST1: DEX BMI PST0 LDA BUFFA,Y LSR BUFFB,X ROL A LSR BUFFB,X ROL A STA (DCBBFL),Y INY CPY DTMP3 BNE PST1 RTS ; ----------- ; READ SECTOR ; ----------- ; READ RAW SECTOR DATA TO [BUFFA/BUFFB] ; ENTRY: SLOT*16 IN [X] ; EXIT: CARRY SET IF ERROR, ELSE 342 RAW BYTES IN [BUFFA/BUFFB] RDSECT: LDY #$20 RDS1: DEY ; RETURN AN ERROR IF BEQ RDBAD ; NO $D5 FOUND AFTER 32 TRIES ; FETCH & VALIDATE PROLOGUE ($D5-$AA-$AD) RDS2: LDA Q6L,X ; GET A BYTE BPL RDS2 RDS3: EOR #$D5 ; WAS IT $D5? BNE RDS1 ; NO, KEEP LOOKING NOP ; ELSE WAIT A MOMENT ... RDS4: LDA Q6L,X ; GET ANOTHER BYTE BPL RDS4 CMP #$AA ; WAS IT $AA? BNE RDS3 ; CHECK FOR $D5 AGAIN IF NOT LDY #$56 ; ELSE INIT DATA-READ INDEX RDS5: LDA Q6L,X ; GET A BYTE BPL RDS5 CMP #$AD ; WAS IT $AD? BNE RDS3 ; CHECK FOR $D5 IF NOT ; READ RAW DATA INTO [BUFFB] LDA #0 ; CLEAR [A], DELAY ... RDS6: DEY STY DTMP3 ; SAVE INDEX HERE RDS7: LDY Q6L,X ; GET A DATA BYTE BPL RDS7 EOR RDTBL-$96,Y ; TRANSLATE IT LDY DTMP3 ; RESTORE INDEX STA BUFFB,Y ; STORE BYTE IN [BUFFB] BNE RDS6 ; CONTINUE TILL [BUFFB] FULL ; READ RAW DATA INTO [BUFFA] RDS8: STY DTMP3 ; RE-INIT INDEX TO ZERO RDS9: LDY Q6L,X ; GET A DATA BYTE BPL RDS9 EOR RDTBL-$96,Y ; TRANSLATE IT LDY DTMP3 ; RESTORE INDEX STA BUFFA,Y ; SAVE BYTE IN [BUFFA] INY BNE RDS8 ; LOOP TILL [BUFFA] IS FULL ; FETCH & VALIDATE CHECKSUM RDS10: LDY Q6L,X ; GET THE NEXT BYTE BPL RDS10 CMP RDTBL-$96,Y ; TRANSLATE IT BNE RDBAD ; ERROR IF CHECKSUM BAD ; FETCH & VALIDATE EPILOGUE ($DE-$AA-$EB) RDS11: LDA Q6L,X ; GET A BYTE BPL RDS11 CMP #$DE ; IS IT $DE? BNE RDBAD ; ERROR IF NOT NOP ; WAIT ... RDS12: LDA Q6L,X ; GET ANOTHER BYTE BPL RDS12 CMP #$AA ; IS IT $AA? BEQ RDOK ; DATA OKAY IF SO RDBAD: SEC ; ELSE SET CARRY FOR ERROR RTS ; AND SCRAM ; --------------------- ; READ AN ADDRESS FIELD ; --------------------- ; ENTRY: SLOT*16 IN [X] ; EXIT: CARRY SET IF ERROR RDADDR: LDY #$FC ; INIT TIMEOUT COUNTER STY DTMP3 RDA1: INY BNE RDA2 INC DTMP3 ; ERROR IF BEQ RDBAD ; CAN'T FIND ADDRESS HEADER ; FETCH THE ADDRESS FIELD PROLOGUE ($D5-$AA-$96) RDA2: LDA Q6L,X ; GRAB A BYTE BPL RDA2 RDA3: CMP #$D5 ; WAS IT $D5? BNE RDA1 ; NO, KEEP SEARCHING NOP ; ELSE WAIT A FEW MICROSECONDS ... RDA4: LDA Q6L,X ; GET ANOTHER BYTE BPL RDA4 CMP #$AA ; WAS IT $AA? BNE RDA3 ; NO, CHECK IF $D5 LDY #3 ; ELSE INIT DATA-FETCH INDEX RDA5: LDA Q6L,X ; GET A BYTE BPL RDA5 CMP #$96 ; WAS IT $96? BNE RDA3 ; NO, CHECK FOR $D5 ; FETCH THE 4 BYTES OF ADDRESS DATA LDA #0 ; INIT CHECKSUM BYTE RDA6: STA DTMP4 ; UPDATE CHECKSUM RDA7: LDA Q6L,X ; GET A BYTE BPL RDA7 ROL A ; SHIFT IT STA DTMP3 ; AND SAVE 1ST PART HERE RDA8: LDA Q6L,X ; GET ANOTHER BYTE BPL RDA8 AND DTMP3 ; SUPER 1ST PART OF BYTE STA HDRCHK,Y ; STORE IN RESULT TABLE EOR DTMP4 ; COMPUTE CHECKSUM DEY ; GOT 4 BYTES YET? BPL RDA6 ; NO, LOOP BACK TAY ; LOOK AT CHECKSUM BYTE BNE RDBAD ; ERROR IF NON-ZERO ; FETCH & VALIDATE EPILOGUE ($DE-$AA, IGNORE $EB) RDA9: LDA Q6L,X ; GET A BYTE BPL RDA9 CMP #$DE ; WAS IT $DE? BNE RDBAD ; ERROR IF NOT NOP ; ELSE WAIT A MOMENT ... RDA10: LDA Q6L,X ; GET ONE MORE BYTE BPL RDA10 CMP #$AA ; WAS IT $AA BNE RDBAD ; ERROR IF NOT RDOK: CLC ; ELSE CLEAR CARRY FOR SUCCESS RTS ; AND RETURN ; --------------------- ; MOVE ARM TO TRACK [A] ; --------------------- ; ENTRY: SLOT*16 IN [X] ; TARGET TRACK IN [A] ; CURRENT TRACK IN [CTRACK] SEEK: STX SLTMP3 ; SAVE SLOT ID STA TTRK ; AND TARGET TRACK CMP CTRACK ; TARGET SAME AS CURRENT? BEQ SEEKEX ; EXIT NOW IF SO LDA #0 ; INIT STA DTMP3 ; INDEX SK1: LDA CTRACK ; GET CURRENT TRACK STA DTMP4 ; SAVE IT HERE SEC SBC TTRK ; GET TRACK DIFFERENCE BEQ SK6 BCS SK2 EOR #%11111111 INC CTRACK BCC SK3 SK2: ADC #$FE DEC CTRACK SK3: CMP DTMP3 BCC SK4 LDA DTMP3 SK4: CMP #$0C BCS SK5 TAY SK5: SEC JSR SEEK0 LDA DELTB1,Y JSR ARMDEL LDA DTMP4 CLC JSR SEEK1 LDA DELTB2,Y JSR ARMDEL INC DTMP3 BNE SK1 SK6: JSR ARMDEL CLC SEEK0: LDA CTRACK SEEK1: AND #%00000011 ROL A ORA SLTMP3 TAX LDA PH0OFF,X ; MOVE THE ARM LDX SLTMP3 SEEKEX: RTS ; ------------------ ; ARM MOVEMENT DELAY ; ------------------ ; NOTE: THIS ROUTINE MUST BEGIN ON A PAGE BOUNDARY! ; ENTRY: 100uS DELAY INTERVAL IN [A] ; MOTOR TIME COUNT IN [MTIME] ARMDEL: LDX #$11 ARM1: DEX BNE ARM1 INC DCNT BNE ARM2 INC DTMP2 ARM2: SEC SBC #1 BNE ARMDEL RTS ; ------------------------- ; ARM MOVEMENT DELAY TABLES ; ------------------------- DELTB1: DB $01,$30,$28,$24,$20,$1E,$1D,$1C DB $1C,$1C,$1C,$1C DELTB2: DB $70,$2C,$26,$22,$1F,$1E,$1D,$1C DB $1C,$1C,$1C,$1C ; --------------------- ; WRITE TRANSLATE TABLE ; --------------------- WRTTBL: DB $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 DB $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 DB $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC DB $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 DB $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE DB $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC DB $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 DB $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF ; -------------------- ; READ TRANSLATE TABLE ; -------------------- RDTBL: DB $00,$01,$98,$99,$02,$03,$9C,$04 DB $05,$06,$A0,$A1,$A2,$A3,$A4,$A5 DB $07,$08,$A8,$A9,$AA,$09,$0A,$0B DB $0C,$0D,$B0,$B1,$0E,$0F,$10,$11 DB $12,$13,$B8,$14,$15,$16,$17,$18 DB $19,$1A,$C0,$C1,$C2,$C3,$C4,$C5 DB $C6,$C7,$C8,$C9,$CA,$1B,$CC,$1C DB $1D,$1E,$D0,$D1,$D2,$1F,$D4,$D5 DB $20,$21,$D8,$22,$23,$24,$25,$26 DB $27,$28,$E0,$E1,$E2,$E3,$E4,$29 DB $2A,$2B,$E8,$2C,$2D,$2E,$2F,$30 DB $31,$32,$F0,$F1,$33,$34,$35,$36 DB $37,$38,$F8,$39,$3A,$3B,$3C,$3D DB $3E,$3F ; --------------- ; MAIN RWTS ENTRY ; --------------- ; ENTRY: [A]=0 FOR READ, [A]=1 FOR WRITE ; [SLOT] = TARGET SLOT ; [DRIVE] = TARGET DRIVE ; [TRACK] = TARGET TRACK ; [SECTOR] = TARGET SECTOR ; EXIT: CARRY CLEAR IF OKAY ; COMMENTS - LINDE ; ACTUAL VARIABLES ARE: ; [DCBSLT] = SLOT ; [DCBTRK] = TRACK ; [DCBSEC] = SECTOR ; [[DCBDRV] = DRIVE ; FOR TRK, SEC, DRV 1 = 1 (DRIVE 1, SET DCBDRV TO 1) ; FOR SLT - MULTIPLY SLOT BY 16 (SLOT 6, SET DCBSLT TO $60) DOS: STA DCBCMD ; SAVE COMMAND LDA #2 ; ALLOW 2 STA NRECAL ; RECALS ASL A ; AND 4 STA NSEEK ; SEEKS LDX DCBSLT ; GET REQUESTED SLOT ID CPX DCBPSL ; SAME AS LAST SLOT? BEQ SAMESL ; YES, CONTINUE LDX DCBPSL ; WAIT FOR OLD DRIVE TO TURN OFF, UPDATE SLOT ID LDA Q7L,X ; SET OLD SLOT TO READ MODE RW1: LDY #8 ; INIT COUNTER LDA Q6L,X RW2: CMP Q6L,X BNE RW1 DEY BNE RW2 LDX DCBSLT ; GET NEW SLOT ID INTO [X] STX DCBPSL ; MAKE IT THE "OLD" SLOT ; CURRENT SLOT ID IN [X] SAMESL: LDA Q7L,X ; GET DRIVE INTO READ MODE LDA Q6L,X ; READ WITH DELAYS LDY #8 ; TO SEE IF DRIVE IS SPINNING RW4: LDA Q6L,X PHA PLA PHA PLA STX SLTMP1 ; SAVE SLOT HERE CMP Q6L,X BNE RW5 DEY BNE RW4 RW5: PHP ; SAVE TEST RESULT ON STACK LDA DRVON,X ; TURN ON MOTOR LDA #$D8 ; REFRESH STA DTMP2 ; MOTOR TIME CONSTANT ; CHECK DRIVE ID LDA DCBDRV CMP DCBPDR ; HAS DRIVE CHANGED? BEQ RW7 ; NO, CONTINUE STA DCBPDR ; ELSE MAKE NEW DRIVE "OLD" PLP ; SET ZERO FLAG LDY #0 ; OF TEST RESULT PHP ; AND PUSH IT BACK ON STACK RW7: ROR A ; CHECK DRIVE ID BCC RW8 ; CARRY WILL BE CLEAR IF DRIVE = 2 LDA DRV0EN,X ; ELSE SELECT DRIVE #1 BCS RW9 ; BRANCH ALWAYS RW8: LDA DRV1EN,X ; SELECT DRIVE #2 RW9: ROR DRVFLG ; HIGH BIT = 1 FOR DRIVE 1, 0 FOR 2 PLP ; CHECK TEST RESULTS PHP BNE RW11 ; BRANCH IF DRIVE WAS ON LDY #7 ; WAIT FOR CAP DISCHARGE RW10: JSR ARMDEL DEY BNE RW10 LDX SLTMP1 ; RESTORE SLOT ID ; SEEK THE TARGET TRACK RW11: LDA DCBTRK ; GET TARGET TRACK JSR MYSEEK PLP ; WAS DRIVE ON? BNE RW14 ; YES, CONTINUE ; WAIT FOR DRIVE TO COME UP TO SPEED LDY DTMP2 BPL RW14 RW12: LDY #$12 ; WAIT FOR DRIVE TO RW13: DEY ; COME UP TO SPEED BNE RW13 INC DCNT BNE RW12 INC DTMP2 BNE RW12 ; DECODE DISK COMMAND RW14: LDA DCBCMD ; GET COMMAND ROR A ; CARRY = 0 IF "READ" PHP ; SAVE READ/WRITE STATUS ; AND MAINTAIN STACK BCC GETADR ; BRANCH IF "READ" JSR PRENIB ; FETCH AN ADDRESS FIELD GETADR: LDA #48 STA DTMP1 ; INIT RETRY COUNT GTA0: LDX SLTMP1 ; RESTORE SLOT ID JSR RDADDR ; GET AN ADDRESS FIELD BCC RRIGHT ; CONTINUE IF SUCCESSFUL GTA1: DEC DTMP1 ; ELSE UPDATE RETRY COUNT BPL GTA0 ; AND TRY AGAIN ; RECALIBRATE THE ARM GTA2: LDA CTRACK ; SAVE THE PHA ; CURRENT TRACK ID LDA #$60 JSR SETTRK DEC NRECAL ; UPDATE RECAL COUNT BEQ DRVERR ; ERROR IF EMPTY LDA #4 ; RESET STA NSEEK ; SEEK COUNT LDA #0 ; CALIBRATE THE ARM JSR MYSEEK ; TO TRACK #0 PLA ; RESTORE CURRENT TRACK GTA3: JSR MYSEEK ; GO TO IT JMP GETADR ; AND TRY AGAIN ; ADDRESS FIELD FOUND RRIGHT: LDY HDRTRK CPY CTRACK ; ON THE RIGHT TRACK? BEQ RTTRAK ; YES, CONTINUE LDA CTRACK PHA TYA JSR SETTRK PLA DEC NSEEK BNE GTA3 BEQ GTA2 ; ELSE RECALIBRATE ; HANDLE A DRIVE ERROR DRVERR: PLA ; CLEAN UP STACK LDA #$40 ; $40 = DRIVE ERROR EREXT: PLP ; CLEAN UP STATUS REGISTER JMP DERROR ; CHECK FOR PROPER SECTOR (VOLUME CHECK OMITTED) RTTRAK: LDY DCBSEC LDA ILEAVE,Y ; GET INTERLEAVE BYTE CMP HDRSEC ; MATCHED FOUND SECTOR? BNE GTA1 ; NO, TRY AGAIN ; SECTOR FOUND! PLP ; WILL THIS BE READ OR WRITE? BCS DWRITE ; DO "WRITE" IF CARRY SET ; READ A SECTOR JSR RDSECT ; DO THE READ BCC GTA3A ; OK CLC ; RESET FOR NEXT TIME THRU PHP ; AND PUSH FOR NEXT TIME THRU BCC GTA1 ; JMP, ERROR OCCURRED ; CHANGED TO ABOVE 4 LINES 6/11/85, CARRY MUST BE CLEARED SO READS ; PHP ; SAVE STATUS ; BCS GTA1 ; ERROR IF CARRY WAS SET ; PLP ; ELSE DUMP STATUS GTA3A: LDX #$00 STX DTMP3 JSR POSTNB LDX SLTMP1 ; RESTORE SLOT ID DONE: LDA #0 ; 0 = NO ERRORS CLC ; CARRY CLEAR FOR SUCCESS BCC EXIT ; ERROR EXIT DERROR: SEC ; CARRY SET FOR ERROR ; GENERAL EXIT EXIT: STA DCBERR ; SAVE ERROR CODE HERE LDA DRVOFF,X ; STOP THE DRIVE RTS ; BYE! ; WRITE A SECTOR DWRITE: JSR WRTDTA BCC DONE ; ALL'S WELL IF CARRY CLEAR LDA #$10 ; ELSE GET ERROR CODE INTO [A] BNE DERROR ; AND DO AN ERROR EXIT ; --------------------- ; SET UP FOR TRACK SEEK ; --------------------- MYSEEK: ASL A ; TRACK*2 (PHASE OF DISK CARE) JSR DOSEEK LSR CTRACK ; CURRENT TRACK/2 RTS ; -------------- ; EXECUTE A SEEK ; -------------- ; PAGE BOUNDARY SHOULD BEGIN HERE! DOSEEK: STA TTRK JSR XTOY LDA DR1TBL,Y BIT DRVFLG BMI DSE1 LDA DR2TBL,Y DSE1: STA CTRACK LDA TTRK BIT DRVFLG BMI DSE2 STA DR2TBL,Y BPL DSE3 DSE2: STA DR1TBL,Y DSE3: JMP SEEK ; -------------------- ; GET SLOT ID INTO [Y] ; -------------------- XTOY: TXA LSR A LSR A LSR A LSR A TAY RTS ; ------------ ; SET TRACK ID ; ------------ SETTRK: PHA LDA DCBDRV ROR A ROR DRVFLG JSR XTOY PLA ASL A BIT DRVFLG BMI STT1 STA DR2TBL,Y BPL STT2 STT1: STA DR1TBL,Y STT2: RTS ; ----------- ; IDOS TABLES ; ----------- DR1TBL: DB $00,$00,$00,$00 ; (8 BYTES) DB $00,$00,$00,$00 CTRACK EQU DR1TBL ; CURRENT TRACK DR2TBL: DB $00,$00,$00,$00 ; (8 BYTES) DB $00,$00,$00,$00 NSEEK: DB $00 ; SEEK COUNT DTMP1: DB $00 ; RETRY COUNT SLTMP1: DB $00 ; SLOT ID SLTMP2: DB $00 NRECAL: DB $00 ; RECALIBRATE COUNT ; ---------------------- ; MACHINE INITIALIZATION ; ---------------------- INIT: LDA TXTSET ; SET TEXT MODE LDA MIXCLR ; SET NO MIX LDA LOWSCR ; SET PAGE 1 LDA #HIGH IOBUFF ; POINT [DCBBFL/H] TO [IOBUFF] STA DCBBFH LDA #LOW IOBUFF STA DCBBFL LDA #1 STA DCBDRV ; SET DRIVE = 1 STA DCBPDR RTS END