918 lines
24 KiB
Plaintext
918 lines
24 KiB
Plaintext
*================================
|
|
* 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.
|
|
|