*================================ * PRENIBBLE DATA ($B800-$B829). * CONVERT 256 MEMORY BYTES TO 342 * SIX-BIT NIBBLES AS SHOWN BELOW. *================================ * ON ENTRY: PTR2BUF PTS AT DATA BUF. * ON EXIT: (A) = ?. * (X) = #$FF. * (Y) = #$FF. * (C) = 1. * RWTSBUF1 * BB00: 0 0 00-7 00-6 00-5 00-4 00-3 00-2 * BB01: 0 0 01-7 01-6 01-5 01-4 01-3 01-2 * BB02: 0 0 02-7 02-6 02-5 02-4 02-3 02-2 * . * . * . * BBFF: 0 0 FF-7 FF-6 FF-5 FF-4 FF-3 FF-2 * * RWTSBUF2 * BC00: 0 0 01-0 01-1 AB-0 AB-1 55-0 55-1 * BC01: 0 0 00-0 00-1 AA-0 AA-1 54-0 54-1 * BC02: 0 0 FF-0 FF-1 A9-0 A9-1 53-0 53-1 * . * . * . * BC54: 0 0 AD-0 AD-1 57-0 57-1 01-0 01-1 * BC55: 0 0 AC-0 AC-1 56-0 56-1 00-0 00-1 * WHERE "AC-0" = BIT0 OF MEMORY BYTE * WHICH IS OFFSET * #$AC BYTES INTO * THE DATA SECTOR. * THE FOLLOWING BITS ARE DUPLICATED * IN $BC00-$BC01 & $BC54-$BC55 BUT * ARE IGNORED IN $BC00-$BC01: * 01-0,01-1,00-0,00-1. PRENIBL LDX #0 LDY #2 PRENIB1 DEY LDA (PTR2BUF),Y ;GET BYTE FROM "DATA" BUFFER. LSR ;PUT ITS LWR 2 BITS IN2 RWTSBUF1. ROL RWTSBUF2,X LSR ROL RWTSBUF2,X STA RWTSBUF1,Y ;PUT REMAINING 6 BITS N RWTSBUF1. INX CPX #$56 BCC PRENIB1 LDX #0 TYA BNE PRENIB1 ;REPEAT UNTIL @ BYTE OF RWTSBUF2 ;HAS 6 BITS. LDX #$55 ;MAKE SURE BITS 6 & 7 OF RWTSBUF2 PRENIB2 LDA RWTSBUF2,X ;ARE ZEROES. AND #%00111111 STA RWTSBUF2,X DEX BPL PRENIB2 RTS *==================================== * WRITE SECTOR TO DISK ($B82A-$B8B7). *==================================== * ON ENTRY: (X) = SLOT*16 * ON EXIT: (C) = 1 = WRIT PROT ERR. * IF NO ERROR: (C) = 0 * (A) = ? * (X) = SLOT*16 * (Y) = #$00 WRITESEC SEC ;(C)=1, ASSUME WRITE PROTECTED ;ERROR AS DEFAULT CONDITION. STX FRMTSLOT ;SAVE SLOT*16 IN PAGES 0 & 6. STX SLOTPG6 LDA Q6H,X ;CHK IF DISK IS WRITE PROTECTED. LDA Q7L,X BMI PROTECTD ;BRANCH IF WRITE PROTECTED. LDA RWTSBUF2 ;GET 1RST 2-ENCODED BYTE AND SAVE STA HOLDNIBL ;IT FOR LATER USE. * WRITE 5-SYNC GAP BETWEEN ADDRESS * EPILOGUE & DATA PROLOGUE. LDA #$FF ;(A) = SYNC BYTE. STA Q7H,X ;WRITE 1 SYNC BYTE. ORA Q6L,X PHA ;(3 CYC) PLA ;(4 CYC) NOP ;(2 CYC) LDY #4 ;WRITE 4 MORE SYNCS (2 CYC). WRITE4FF PHA ;(3 CYC) PLA ;(4 CYC) JSR WRITE2 ;(12 CYC BEFORE, 6 AFTER.) DEY ;(2 CYC) BNE WRITE4FF ;(2 OR 3 CYC) * WRITE DATA PROLOGUE ("D5 AA AD"). LDA #$D5 ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) LDA #$AA ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) LDA #$AD ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) * CONVERT & WRITE CONTENTS OF RWTS * BUFFERS TO DISK. (WHEN FORMATTING, * THESE BUFS ARE ZEROED OUT. THE * "$00" BYTES IN BUF ARE LATER TRANS- * LATED TO "$96" BYTES ON THE DISK.) * CONVERT & WRITE 2-ENCODED * NIBBLES FROM RWTSBUF2. * (EOR TO CALC (X) & THEN USE (X) * AS INDEX TO TBL OF DISK BYTES.) * * #0 EOR $BC55 = (X) * $BC55 EOR $BC54 = (X) * $BC54 EOR $BC53 = (X) * . . . . * . . . . * . . . . * $BC01 EOR $BC00 = (X) TYA ;(A) = 0. LDY #$56 ;(DEC #86.) BNE DOEOR ;ALWAYS. GETNIBL LDA RWTSBUF2,Y DOEOR EOR RWTSBUF2-1,Y TAX ;INDEX TO DISK BYTE. LDA DSKNBTBL,X ;GET DISK BYTE. LDX FRMTSLOT ;(X) = SLOT*16. STA Q6H,X ;WRITE BYTE. LDA Q6L,X DEY ;(Y) = $56 --> #$00. BNE GETNIBL ;(WRITE $56 OR DEC #86 BYTES.) * CONVERT & WRITE 6-ENCODED * NIBBLES FROM RWTSBUF1. * * $BC00 EOR $BB00 = (X) * $BB00 EOR $BB01 = (X) * $BB01 EOR $BB02 = (X) * . . . . * . . . . * . . . . * $BBFE EOR $BBFF = (X) LDA HOLDNIBL ;NORMALLY = CONTENTS OF $BC00. NOP SCNDEOR EOR RWTSBUF1,Y TAX ;INDEX TO DISK BYTE. LDA DSKNBTBL,X ;GET DISK BYTE TO WRITE. LDX SLOTPG6 ;(X) = SLOT*16. STA Q6H,X ;WRITE 87TH ---> 341ST BYTES. LDA Q6L,X LDA RWTSBUF1,Y INY ;(Y) = #$00 ---> #$FF. BNE SCNDEOR * CONVERT & WRITE DATA CHECKSUM. * (342ND BYTE, $BBFF ------> (X).) TAX ;INDEX TO TABLE OF DISK BYTES. LDA DSKNBTBL,X ;GET DISK BYTE TO WRITE. LDX FRMTSLOT ;(X) = SLOT*16. JSR WRITE3 ;(5 CYCS BEFORE, 6 AFTER.) * WRITE DATA EPILOGUE ("DE AA EB"). LDA #$DE ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) LDA #$AA ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) LDA #$EB ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) * WRITE A SYNC BYTE. LDA #$FF ;(2 CYC) JSR WRITE1 ;(14 CYCS BEFORE, 6 AFTER.) LDA Q7L,X ;SET READ MODE. PROTECTD LDA Q6L,X RTS *==================================== * WRITE BYTE WITH VARIOUS DELAYS. * (DELAYS PRIOR TO ENTRY & THOSE * SHOWN BELOW RESULT IN WRITING BYTES * EVERY 32 MACHINE CYCLES.) *==================================== WRITE1 CLC ;(2 CYC) WRITE2 PHA ;(3 CYC) PLA ;(4 CYC) WRITE3 STA Q6H,X ;(5 CYC) - SHIFT REGISTER) ORA Q6L,X ;(4 CYC - STROBE LATCH) RTS ;(6 CYC) *================================= * POSTNIBBLE DATA ($B8C2 - $B8DB). * CONVERT 6- & 2-ENCODED BYTES IN * RWTS'S TWO BUFFERS TO NORMAL * MEMORY BYTES (USUALLY PLACED IN * DOS DATA SECTOR BUFFER). *================================= * ON ENTRY: (X) = SLOT*16. * PTR2BUF = PTS TO DATA BUF. * ON EXIT: (A) = ? * (X) = ? * (Y) = BYTE COUNT USED * FOR RWTBUF2. * (C) = 1. POSTNB16 LDY #0 POSTNIB1 LDX #$56 ;(DEC #86.) POSTNIB2 DEX BMI POSTNIB1 LDA RWTSBUF1,Y ;SET (A) = 6-ENCODED BYTE. LSR RWTSBUF2,X ;PUT LWR 2 BITS OF 2-ENCODED BYTE ROL ;INTO ORIGNAL 6-ENCODED BYTE TO LSR RWTSBUF2,X ;CREATE A NORMAL MEMORY BYTE. ROL STA (PTR2BUF),Y ;PUT NORMAL MEMORY BYTE IN RWTS'S INY ;BUF (NORMALLY DOS DATA SEC BUF). CPY PROSCRTH BNE POSTNIB2 RTS *=================================== * READ DATA SECTOR INTO RWTS'S BUFS. *=================================== * CONDITIONS FOR $B8DC - $B943: * ON ENTRY: (X) = SLOT*16 * ON EXIT: (C) = 1 IF ERROR * IF NO ERR: (C) = 0. * (A) = #$AA. * (X) = SLOT*16. * (Y) = #$00. * FIND DATA PROLOGUE ("D5 AA AD"). READATA LDY #32 ;SET (Y) = 32 ATTEMPTS TO FIND REDUCEY DEY ;THE DATA PROLOGUE. BEQ ERRTN ;ERROR - CAN'T FIND DAT PROLOGUE. PRODATD5 LDA Q6L,X ;GET BYTE FROM DATA PROLOGUE. BPL PRODATD5 ;WAIT FOR FULL BYTE. VERSD5 EOR #$D5 ;CHK IF BYTE WAS "D5". BNE REDUCEY ;WASN'T "D5", REDUCE COUNTER. NOP ;STALL 2 CYCLES. PRODATAA LDA Q6L,X ;READ NEXT DATA PROLOGUE BYTE. BPL PRODATAA ;WAIT FOR FULL BYTE. CMP #$AA ;WAS IT AN "AA"? BNE VERSD5 ;NO - GO RESTART SEQUENCE. LDY #$56 ;SET (Y) FOR LATER USE IN READ ;DATA ROUTINE. PRODATAD LDA Q6L,X ;READ NEXT BYTE IN DATA PROLOGUE. BPL PRODATAD ;WAIT FOR FULL BYTE. CMP #$AD ;WAS IT AN "AD"? BNE VERSD5 ;NO - GO RESTART SEQUENCE. * READ 1RST 86 BYTES OF DATA INTO * RWTSBUF2 ($BC55 --> $BC00). * * USE DISK BYTE AS INDEX TO THE * NDX2NIBL TABLE WHICH CONTAINS * OFFSETS THAT WE WOULD BE USING * IF WE WERE ACCESSING A TABLE * OF DISK BYTES WHEN WRITING. * (IE. WE ARE JUST DOING OPPOSITE * OF WRITING.) * EOR VALUE FROM NDX2NIBL TABLE * WITH PREVIOUS EOR RESULT. (ON * ENTRY, USE #$00 FOR PREVIOUS * EOR RESULT.) LDA #0 ;INITIALIZE (A) FOR LATER EORING. RDUCY DEY ;REDUCE INDEX TO RWTSBUF2. STY PROSCRTH ;SAVE INDEX. RDSKBYT LDY Q6L,X ;(Y) = DISK BYTE. BPL RDSKBYT ;WAIT FOR FULL BYTE. EOR NDX2NIBL-$96,Y ;USE (Y) AS INDEX TO TABLE OF ;2-ENCODED NIBBLES. LDY PROSCRTH ;RETRIEVE INDEX TO SECOND BUF. STA RWTSBUF2,Y ;STORE 2-ENCODED NIBL N RWTSBUF2. BNE RDUCY ;Z-FLG CONDITIONED FRM THE "LDY". * READ REST OF SEC INTO RWTSBUF1 * ($BB00 --> $BBFF). * * USE DISK BYTE AS INDEX TO THE * NDX2NIBL TABLE WHICH CONTAINS * OFFSETS THAT WE WOULD BE USING * IF WE WERE ACCESSING A TABLE * OF DISK BYTES WHEN WRITING. * (IE. WE ARE JUST DOING OPPOSITE * OF WRITING.) * EOR VALUE FROM NDX2NIBL TABLE * WITH PREVIOUS EOR RESULT. SAVYNDX STY PROSCRTH ;SAVE INDEX TO RWTSBUF1. RDSKBYT2 LDY Q6L,X ;(Y) = DISK BYTE. BPL RDSKBYT2 ;WAIT FOR FULL BYTE. EOR NDX2NIBL-$96,Y ;GET 6-ENCODED NIBL FRM TBL. LDY PROSCRTH ;GET INDEX TO RWTSBUF1. STA RWTSBUF1,Y ;STORE 6-ENCODED NIBL N RWTSBUF1. INY BNE SAVYNDX ;MORE DISK BYTES TO READ. * READ DATA CHECKSUM. RDCHECK LDY Q6L,X ;GET DATA CHECKSUM BYTE FROM DSK. BPL RDCHECK ;WAIT FOR FULL BYTE. CMP NDX2NIBL-$96,Y ;DOES CONVERTED CHKSUM EQUAL ;THE VALUE IN $BBFF? ;REMEMBER: VAL IN $BBFF IS RESULT ;OF PREVIOUS CUMMULATIVE EORING. ;THERE4, THIS COMPARISON WITH (A) ;DETECTS ANY (NON-CANCELLING) ;ERROR(S) THAT MAY HAVE OCCURRED ;IN THE ENTIRE SECTOR!!! BNE ERRTN ;ERROR -DIDN'T MATCH WITH CHKSUM. ;HACKERS OFTEN CHANGE THESE TWO ;BYTES 2 "CLC" AND "RTS" INSTRUCS ;IN ORDER TO DEFEAT DATA CHECKSUM ;AND IGNORE THE DATA EPILOGUE. * READ 1RST TWO BYTES (ONLY) OF * DATA EPILOGUE ("DE AA EB"). EPIRDDE LDA Q6L,X ;READ 1RST BYTE OF DATA EPILOGUE. BPL EPIRDDE ;WAIT FOR FULL BYTE. CMP #$DE ;IS IT A "DE"? BNE ERRTN ;NO - GOT AN ERROR. NOP ;STALL 2 CYCLES. EPIRDAA LDA Q6L,X ;READ 2ND BYTE OF DATA EPILOGUE. BPL EPIRDAA ;WAIT FOR FULL BYTE. CMP #$AA ;IS IT AN "AA"? BEQ GOODRTN ;YES - GOT A GOOD READ. ERRTN SEC ;SIGNAL BAD READ. RTS ;HACKERS OFTEN CHANGE THE "SEC" 2 ;"CLC" TO DEFEAT ERROR CHECKING. *==================================== * READ ADDRESS ROUTINE ($B944-$B99F). *==================================== * ON ENTRY: (X) = SLOT*16. * ON EXIT: (C) = 1 IF ERROR. * IF NO ERRS: (A) = #$AA. * (Y) = #$00. * (X) = SLOT*16. * $2C = CHECKSUM VAL FOUND. * $2D = SEC # FOUND. * $2E = TRK # FOUND. * $2F = VOL # FOUND. * READ THE ADDRESS HEADER. RDADDR LDY #$FC ;SET 772 CHANCES TO FIND CORRECT STY PROSCRTH ;ADR PROLOGUE (#$FCFC-#$10000). KICKNTR INY BNE TRYD5 INC PROSCRTH BEQ ERRTN ;ERROR - CAN'T FIND PROLOGUE. * FIND ADR PROLOGUE ("D5 AA 96"). TRYD5 LDA Q6L,X BPL TRYD5 ;WAIT FOR A FULL BYTE. VERSUSD5 CMP #$D5 ;WAS IT "D5"? BNE KICKNTR ;NO - TRY AGAIN. NOP ;WAIT 2 CYCLES. TRYAA LDA Q6L,X BPL TRYAA ;WAIT FOR FULL BYTE. CMP #$AA ;WAS IT "AA"? BNE VERSUSD5 ;NO - RETRY SEQUENCE. LDY #3 ;SET (Y) 4 LATER READING OF VOL, ;TRK, SEC & CHKSUM INFO FROM THE ;ADRRESS FIELD. TRY96 LDA Q6L,X BPL TRY96 ;WAIT FOR A FULL BYTE. CMP #$96 ;WAS IT "96"? BNE VERSUSD5 ;NO - RETRY SEQUENCE. * READ ODD-EVEN ENCODED VOL, TRK, * SEC & CHECKSUM FROM ADR FIELD. * (DURING READING, CALC A RUNNING * CHECKSUM.) * FROM: BYTE1: 1 B7 1 B5 1 B3 1 B1 * BYTE1: B6 1 B4 1 B2 1 B0 1 * --------------------------------- * TO: BYTE: B7 B6 B5 B4 B3 B2 B1 B0 LDA #0 ;INTIALIZE FOR RUNNING CHECKSUM. CALCK STA CKSUMCAL GETHDR LDA Q6L,X ;GET ODD-ENCODED BYTE. BPL GETHDR ;WAIT FOR A FULL BYTE. ROL ;SHIFT BITS, PUT (C)=1 IN BIT0. STA PROSCRTH ;SAVE SHIFTED VERSION. RDHDR LDA Q6L,X ;GET EVEN-CODED BYTE. BPL RDHDR ;WAIT FOR A FULL BYTE. AND PROSCRTH ;MERGE & CREATE NORM MEMORY BYTE. STA: CKSUMDSK,Y ;STORE INFO READ FROM ADDR FIELD ;IN Z-PAGE: ;2F = VOL FND, 2E = TRK FND, ;2D = SEC FND, 2C = CHECKSUM FND. ;(NOTE "STA:" FORCES 3-BYT CODE.) EOR CKSUMCAL ;UPDATE RUNNING CHECKSUM. DEY BPL CALCK TAY ;PUT CHECKSUM FOUND IN (Y). BNE ERRTN ;IF CHKSUM FOUND < > 0 THEN ERR. ;HACKERS OFTEN CHANGE THESE TWO ;BYTES 2 "CLC" AND "RTS" INSTRUCS ;IN ORDER 2 DEFEAT THE ADR CHKSUM ;AND IGNORE THE ADR EPILOGUE. * READ 1RST 2 BYTES (ONLY) OF * ADDRESS EPILOGUE ("DE AA EB"). TRYEPIDE LDA Q6L,X ;GET 1RST BYTE. BPL TRYEPIDE ;WAIT FOR A FULL BYTE. CMP #$DE ;WAS IT A "DE"? BNE ERRTN ;NO - TRY AGAIN. NOP ;STALL 2 CYCLES. TRYEPIAA LDA Q6L,X ;GET 2ND BYTE. BPL TRYEPIAA ;WAIT FOR A FULL BYTE. CMP #$AA ;WAS IT AN "AA"? BNE ERRTN ;NO - RETRY SEQUENCE. GOODRTN CLC ;SIGNAL GOOD READ. RTS *====================================== * MOVE DISK ARM TO A GIVEN HALFTRACK * POSITION ($B9A0-$B9FF). *====================================== * ON ENTRY: (X) = SLOT*16 * (A) = DESTINATION HALFTRK. * PRESTRK = CURRENT HALFTRK. * ON EXIT: (A) = ? * (X) = SLOT*16. * (Y) = ? * DESTRK = FINAL HALFTRK. * PRESTRK = FINAL HALFTRK. * HOLDPRES = PREVIOUS HALFTRK. SEEKABS STX SLT16ZPG ;SAVE SLOT*16 IN ZERO PAGE. STA DESTRK ;SAVE DESTINATION HALFTRK#. CMP PRESTRK ;DESTINATION 1/2TRK=PRES 1/2TRK? BEQ ARRIVED ;YES-WE'RE ALREADY THERE, SO XIT. LDA #0 ;INIT COUNTER 4 # OF TRKS MOVED. STA STPSDONE * SAVE CURRENT HALFTRK POS'N AND CALC # * OF HALFTRKS NEED TO MOVE MINUS 1. SAVCURTK LDA PRESTRK ;SAVE CURRENT HALFTRK POSITON. STA HOLDPRES SEC ;CALC (PRESTRK-DESTRK). SBC DESTRK BEQ ATDESTN ;AT DESTINATION SO GO SHUTDOWN. BCS MOVDOWN ;PRES 1/2TRK > DESTINATION 1/2TRK ;SO WANT 2 MOVE 2 LOWER 1/2TRK#. * WANT TO MOVE TO HIGHER HALFTRK#. * (PRESTRK - DESTRK = NEG RESULT.) EOR #$FF ;CONVERT NEG TO POS. INC PRESTRK ;MOVING UP,SO INC CURRENT HALFTRK ;POS'N FOR NEXT TIME AROUND. BCC CKDLYNDX ;ALWAYS. * WANT TO MOVE TO LOWER HALFTRK#. * (PRESTRK - DESTRK = POS RESULT.) MOVDOWN ADC #$FE ;SIMULATE A SUBTRATION OF 1. ;ACTUALLY ADDING MINUS 1 (#$FF) ;CAUSE (C)=1. WANT (A) TO EQUAL ;1 LESS THAN # OF HALFTRKS 2 MOV. DEC PRESTRK ;MOVING DOWN, REDUCE PRES HALFTRK ;NUMBER FOR NEXT TIME AROUND. * CHECK TO SEE WHICH INDEX TO USE * TO ACCESS THE DELAY TABLE. IF * WE ARE WITHIN 12 STEPS OF THE * DESTINATION OR START POS'NS, USE * CLOSEST DISTANCE TO START OR END * POS'N TO INDEX THE DELAY TABLES. * DELAY TABLES ARE ONLY 12 BYTES * LONG, SO IF MORE THAN 12 STEPS * AWAY FROM BOTH START & DEST'N, * USE LAST INDEX (Y=12) TO ACCESS * THE TABLE. * CHECK IF CLOSER TO DEST'N OR * START POS'N. CKDLYNDX CMP STPSDONE ;COMPARE # OF HALFTRKS ALREADY ;MOVED VS # HALFTRKS NEED 2 MOVE. BCC CLSR2ND ;CLOSER TO DEST'N THAN START. * CLOSER TO START. LDA STPSDONE ;(A) = DISTANCE FROM START POS'N. * ENTRY PT IF CLOSER TO END. CLSR2ND CMP #12 ;ARE WE WITHIN 12 STEPS OF START ;OR DESTINATION POS'N? BCS TURNON ;WE ARE AT OR BEYOND 12 STEPS FRM ;START OR DEST'N POS'N SO USE OLD ;INDEX TO ACCESS DELAY TABLE. PRESNDX TAY ;USE PRES DISTANCE 2 INDEX TABLE. TURNON SEC ;(C)=1 SO GET ODD INDEX TO BASE ;ADR SO MAGNET WILL BE TURNED ON. JSR ONOROFF ;TURN MAGNET ON TO SUCK STEPPER ;MOTOR 2 CORRECT HALFTRACK POS'N. LDA ONTABLE,Y ;GET TIME TO LEAVE MAGNET ON. JSR DELAY ;DELAY TO GIVE DRIVE TIME TO ACT ;BEFORE MAGNET TURNED OFF AGAIN ;CAUSE COMPUTER IS TOO FAST FOR ;PERIPHERAL & WANT SMOOTH MOV'T. LDA HOLDPRES ;(A) = LAST HALFTRK POS'N. CLC ;CLR (C) SO INDEX WILL COME OUT ;EVEN & THERE4 MAGNET WILL BE ;TURNED OFF. JSR ENTRYOFF ;TURN OFF THE MAGNET ASSOC WITH ;PREVIOUS POS'N. LDA OFFTABLE,Y ;GET TIME TO LEAVE MAGNET OFF. JSR DELAY ;LEAVE MAGNET OFF FOR A WHILE TO ;GIVE ARM TIME TO BE PROPERLY ;ALIGNED. (NEED TIME TO SUCK IT ;OVER & ALSO TO DECREASE BOUNCE ;OR OVER SHOOT.) INC STPSDONE BNE SAVCURTK ;ALWAYS. *---------------------------------- * ARRIVED AT DESTINATION HALFTRACK. *---------------------------------- ATDESTN JSR DELAY ;WAIT ON PERIPHERAL AGAIN. * TURN LAST-USED MAGNET OFF SO EXIT * WITH ALL PHASES (IE.MAGNETS) OFF. * NOTE: THIS IS VERY IMPORTANT * CAUSE MAG1ON IS WIRED INTO THE * WRITE-PROTECT SWITCH!!! CLC ;CLR (C) SO NDX WILL COME OUT AS ;EVEN & THERE4 MAGNET WILL BE ;TURNED OFF. *--------------------------------- * TURN MAGNET ON OR OFF. *--------------------------------- ONOROFF LDA PRESTRK ;USE HALFTRK POS'N 2 INDEX MAGNET ENTRYOFF AND #%00000011 ;ONLY KEEP LWR 2 BITS OF HALFTRK# ;BECAUSE ONLY 4 MAGNETS (0,1,2,3) ROL ;MULTIPLY HALFTRK * 2 & ADD (C). ;IF (C)=0, RESULT EVEN, MAG OFF ;IF (C)=1, RESULT ODD, MAGNET ON. ORA SLT16ZPG ;MERGE INDEX 2 MAGNET WITH SLOT#. TAX ;USE (X) TO INDEX MAGNET ON/OFF. LDA MAG0FF,X ;USE MAGNET-0-OFF AS BASE ADR. LDX SLT16ZPG ;RESTORE (X) = SLOT*16. ARRIVED RTS *================================= * FREE SPACE ($B9FD-$B9FF). *================================= HEX AAA0A0 ;UNUSED. *================================== * MAIN DELAY ROUTINE IN DOS. * AMT OF DELAY = 100*(A) MICROSECS. *================================== DELAY LDX #17 DLY1 DEX BNE DLY1 INC MTRTIME BNE DLY2 INC MTRTIME+1 DLY2 SEC SBC #1 BNE DELAY RTS *================================= * DELAY TIMES FOR STEPPER MOTOR * MOVEMENTS. (VALUE * 100 = DELAY * IN MICROSECONDS.) *================================= *--------------------------------- * TIMES TO LEAVE MAGNET ON. * ($BA11 - $BA1C) *--------------------------------- ONTABLE HEX 01302824201E1D1C1C1C1C1C *--------------------------------- * TIMES TO LEAVE MAGNET OFF. * ($BA1D - $BA28) *--------------------------------- OFFTABLE HEX 702C26221F1E1D1C1C1C1C1C *================================= * TABLE OF DISK BYTES. * ($BA29 - $BA68) *================================= DSKNBTBL HEX 96979A9B9D9E9F HEX A6A7ABACADAEAF HEX B2B3B4B5B6B7B9BABBBCBDBEBF HEX CBCDCECF HEX D3D6D7D9DADBDCDDDEDF HEX E5E6E7E9EAEBECEDEEEF HEX F2F3F4F5F6F7F9FAFBFCFDFEFF *================================= * CHECK IF USING APPEND CMD. * (RECENT PATCH, $BA69-$BA75) *================================= * RAN OUT OF DATA SO BETTER CHECK * IF WE ARE APPENDING. CKIFAPND LDX NDX2CMD ;GET COMMAND INDEX. CPX #$1C ;ARE WE APPENDING? BEQ RTNCKAPN ;YES - LEAVE APPEND FLAG ON. LDX #0 ;NO - MAKE SURE APPEND FLG OFF. STX APPNDFLG RTNCKAPN RTS *================================= * CLOBBER THE 80-COLUMN CARD. * (RECENT PATCH, $BA76-$BA83) *================================= CONTCLOB LDA #$FF ;SET MODE FLAG FOR CARD. STA $4FB ;SCRATCH PAD MEMORY FOR SLOT3. STA $C00C ;TURN OFF THE ALTERNATE CHAR SET. STA $C00E JMP INIT ;SIMULATE A TEXT STATEMENT. *================================= * FREE SPACE * ($BA84 - $BA95) *================================= DS 18 *================================== * TABLE OF BYTES USED WHEN READING. * ($BA96 - $BAFF) * - USED TO TRANSLATE A DISK BYTE * TO A 2- OR 6-ENCODED NIBBLE * NEEDED FOR THE RWTS BUFFERS). *================================== * NUMBERS > $3F REPRESENT ILLEGAL * DISK BYTES VALUES THAT ARE SIMPLY * USED AS SPACERS IN TABLE. NDX2NIBL HEX 0001 ; VALID INDICES. HEX 9899 ; 2 SPACERS. HEX 0203 ; VALID INDICES. HEX 9C ; 1 SPACER. HEX 040506 ; VALID INDICES. HEX A0A1A2A3A4A5 ; 6 SPACERS. HEX 0708 ; VALID INDICES. HEX A8A9AA ; 3 SPACERS. HEX 090A0B0C0D ; VALID INDICES. HEX B0B1 ; 2 SPACERS. HEX 0E0F10111213 ; VALID INDICES. HEX B8 ; 1 SPACER. HEX 1415161718191A ; VALID INDICES. HEX C0C1C2C3C4C5 ; 6 SPACERS. HEX C6C7C8C9CA ; 5 SPACERS. HEX 1B ; VALID INDEX. HEX CC ; 1 SPACER. HEX 1C1D1E ; VALID INDICES. HEX D0D1D2 ; 3 SPACERS. HEX 1F ; VALID INDEX. HEX D4D5 ; 2 SPACERS. HEX 2021 ; VALID INDICES. HEX D8 ; 1 SPACER. HEX 22232425262728 ; VALID INDICES. HEX E0E1E2E3E4 ; 5 SPACERS. HEX 292A2B ; VALID INDICES. HEX E8 ; 1 SPACER. HEX 2C2D2E2F303132 ; 7 INDICES. HEX F0F1 ; 2 SPACERS. HEX 333435363738 ; VALID INDICES. HEX F8 ; 1 SPACER. HEX 393A3B3C3D3E3F ; VALID INDICES. *================================= * BUFFER ($BB00-BBFF) OF 6-ENCODED * NIBBLES (IE. 00XXXXXX, WHERE * X = 0 OR 1, BITS 6 & 7 ARE * ALWAYS 0). * USED AS A TRANSITION BUFFER * BETWEEN NORMAL MEMORY BYTES * AND DISK BYTES. *================================= RWTSBUF1 DS 256 *================================== * BUFFER ($BC00-$BC55) OF 2-ENCODED * NIBBLES. *================================== * NIBBLES ARE OF THE FORM: * 0 0 JJ-0 JJ-1 KK-0 KK-1 LL-0 LL-1 * WHERE BITS 6 & 7 ARE ALWAYS 0. * HOWEVER THE OTHER BITS REPRESENT * A MIXTURE OF BITS FROM DIFFERENT * ORIGINAL MEMORY BYTES. * (IE. JJ-0 REPRESENTS BIT 0 FROM * ORIGINAL MEMORY BYTE JJ.) RWTSBUF2 DS 86 *====================================== * WRITE ADDRESS HEADER ($BC56-$BCC3). * (ONLY USED BY RWTS'S FORMAT COMMAND). *====================================== * ON ENTRY: (X) = SLOT*16. * (Y) = # OF SELF SYNCS * TO WRITE. * HOLDAA = #$AA. * FRMTSEC = SEC #. * FRMTVOL = VOL #. * FRMTKCTR = TRK #. * ON EXIT: (A) = ? * (X) = SLOT*16. * (Y) = #$00. * (C) = 0 IF NOT PROTECTED. * = 1 IF WRITE PROTECTED. WRITADR SEC ;(C)=1, ASSUME ERROR AS DEFAULT. LDA Q6H,X ;CHK IF DISK IS WRITE PROTECTED. LDA Q7L,X BMI SET4RD ;BRANCH IF WRITE PROTECTED. * NOT WRITE PROTECTED SO PREP TO * WRITE A GAP OF 40-CYCLE SYNC * BYTES BTWN SECS. (THIS ROUTINE * WRITES 2 DIF SIZES OF GAPS. GAP1 * PRECEEDS SEC $00. IT INITIALLY * CONSISTS OF 128 SELF-SYNC BYTES * BUT IS LATER PARTIALLY OVER- * WRITTEN BY SEC $0F. GAP3 OCCURS * BTWN THE ADDR FIELD OF THE * PRECEEDING SEC & THE DATA FIELD * OF THE NEXT SEC. ITS LENGTH * VARIES WITH THE TRK # AND THE * SPEED OF THE SPECIFIC DRIVE * BEING USED.) LDA #$FF ;(A) = SYNC BYTE. STA Q7H,X ;SET WRITE MODE. CMP Q6L,X PHA ;(3 CYC) PLA ;(4 CYC) WRTSYNC JSR WTADDRTN ;(12 CYC) JSR WTADDRTN ;(12 CYC) STA Q6H,X ;(5 CYC) CMP Q6L,X ;(4 CYC), WRITE BYTE. NOP ;(2 CYC) DEY ;(2 CYC) BNE WRTSYNC ;(3 CYC ON BRNCH, 2 ON FALL THRU) * WRITE ADDRESS PROLOGUE. * ("D5 AA 96", 32-CYCLE BYTES.) LDA #$D5 ;(2 CYC) JSR WRBYTE3 ;(24 CYC BEFORE, 6 AFTER) LDA #$AA ;(2 CYC) JSR WRBYTE3 ;(24 CYC BEFORE, 6 AFTER) LDA #$96 ;(2 CYC) JSR WRBYTE3 ;(24 CYC BEFORE, 6 AFTER) * WRITE VOL, TRK & SECTOR AS * ODD/EVEN ENCODED BYTES. * (32 CYCLES BETWEEN BYTES.) LDA FRMTVOL ;(A) = VOLUME #, (3 CYC). JSR WRBYTE1 ;WRITE BYTES FOR VOLUME. ;(JSR INSTRUCTION = 6 CYC.) LDA FRMTKCTR ;WRITE BYTES FOR TRK. ;(3 CYC + 6 FROM BEFORE.) JSR WRBYTE1 ;(6 CYC + 17 MORE CYC, WITH ;6 RESIDUAL CYC.) LDA FRMTSEC ;WRITE BYTES FOR SEC. JSR WRBYTE1 ;(CYCLES AS PER ABOVE.) * CALCULATE ADDRESS CHECKSUM. LDA FRMTVOL ;(3 CYC + 6 FROM BEFORE) EOR FRMTKCTR ;(3 CYC) EOR FRMTSEC ;(3 CYC) PHA ;SAVE CKSUM ON STK (3 CYC). * ODD ENCODE THE ADDRESS CHECKSUM. LSR ;(2 CYC) ORA HOLDAA ;(3 CYC) STA Q6H,X ;(5 CYC - WRITE BYTE) LDA Q6L,X ;(4 CYC) * EVEN ENCODE THE ADDRESS CHECKSUM. PLA ;(3 CYC) ORA #%10101010 ;(2 CYC) JSR WRBYTE2 ;(26 CYC BEFORE WRITE, 6 AFTER) * WRITE ADDRESS EPILOGUE. * ("DE AA EB", 32-CYCLE BYTES.) LDA #$DE ;(2 CYC + 6 LEFT OVER FRM B4.) JSR WRBYTE3 ;(24 CYC BEFORE WRITE, 6 AFTER) LDA #$AA ;(2 CYC + 6 LEFT OVER FROM B4) JSR WRBYTE3 ;(24 CYC B4 WRITE, 6 LFT OVER) LDA #$EB ;(2 CYC + 6 LEFT OVER FROM B4) JSR WRBYTE3 ;(24 CYC BEFORE WRITE, 6 AFTER) CLC SET4RD LDA Q7L,X ;SET READ MODE. LDA Q6L,X WTADDRTN RTS *================================= * WRITE DOUBLE AND SINGLE BYTE * SUBR'TNS WITH DIFFERENT DELAYS. *================================= * NOTE: A "JSR" INSTRUCTION * REQUIRES 6 CYCLES. THEREFORE * 6 CYCLES + ANY OTHER OVERHEAD * SHOULD BE ADDED TO THE SUBRTNS * GIVEN BELOW IN ORDER TO ARRIVE * AT A 32-CYCLE COUNT BETWEEN @ * BYTE WRITTEN. WRBYTE1 PHA ;(3 CYC) * CALC & WRITE ODD-ENCODED BYTE. LSR ;(2 CYC) ORA HOLDAA ;(3 CYC) STA Q6H,X ;(5 CYC) CMP Q6L,X ;(4 CYC) * CALC & WRITE EVEN-ENCODED BYTE. PLA ;(4 CYC) NOP ;(2 CYC) NOP ;(2 CYC) NOP ;(2 CYC) ORA #$AA ;(2 CYC) WRBYTE2 NOP ;(2 CYC) WRBYTE3 NOP ;(2 CYC) PHA ;(3 CYC) PLA ;(4 CYC) STA Q6H,X ;(5 CYC) CMP Q6L,X ;(4 CYC) RTS ;(6 CYC LEFT OVER AFTER WRITE) *================================= * FREE SPACE * ($BCDF - $BCFF) *================================= DS 33 ;UNUSED GARBAGE - CONSIDER FREE.