💾 Archived View for spam.works › mirrors › textfiles › apple › ANATOMY › rwts.s.txt captured on 2023-06-16 at 21:11:46.
View Raw
More Information
-=-=-=-=-=-=-
- *********************************
- *
- R . W . T . S . *
- *
- from the D O S - Source 1982 *
- *
- *********************************
-
-
-
SLOTZ = $27
CSUM = $27
PRIOR = $27
WTEMP = $26
TO = $26
IDX = $26
COUNT = $26
LAST = $26
TRKCNT = $26
VOLFND = $2F
TRKFND = $2E
SECFND = $2D
SLOTEMP = $2B
TRKN = $2A
PTRSDEST = $36
DRIVNO = $35
BUFADR = $3E
DEVCTBL = $3C
MONTIMEH = $47
MONTIMEL = $46
SYNCNT = $45
TRACK = $44
VOLUME = $41
IOBPH = $49
IOBPL = $48
DRV0TRK = $478
CURTRK = $478
SEEKCNT = $4F8
DRV1TRK = $4F8
RETRYCNT = $578
SLOT = $5F8
SLOTABS = $678
RECALCNT = $6F8
CLOSEALL = $A316
RSET0 = $A75B
TEMP1 = $AA63
BYTVAL = $AA70
RUNINTRC = $AAB7
SAVFMW = $AE7E
SETERROR = $B385
STKSAVE = $B39B
RESTART = $B744
ROM = $C081
PHASEOFF = $C080
SETWRT = $C08F
SETRD = $C08E
WRTDAT = $C08D
RDDATA = $C08C
DRVSL2 = $C08B
DRVSL1 = $C08A
DRVON = $C089
DRVOFF = $C088
BASIC = $E000
SETVID = $FE93
ORG $B800
-
- PRENIBBLIZE ROUTINE
-
- CONVERTS 256 BYTES POINTED AT BY
- BUFADR TO 342 6-BIT NIBBLES
- OF THE FORM 00XXXXXX
-
PRENIB16 LDX #0
LDY #2
PRENIB1 DEY
LDA (BUFADR),Y
-
- Shift H.O. two bytes into
- NBUF2.
-
LSR
ROL NBUF2,X
LSR
ROL NBUF2,X
-
- Put L.O. six bits (shifted left)
- into NBUF1.
-
STA NBUF1,Y
INX
CPX #$56
BCC PRENIB1
LDX #0
TYA
BNE PRENIB1
-
-
- strip H.O. two bits of NBUF2.
-
LDX #$55
PRENIB2 LDA NBUF2,X
AND #$3F
STA NBUF2,X
DEX
BPL PRENIB2
RTS
ORG $B82A
-
- Write subroutine
-
- Writes prenibbilized data in
- NBUF1 and NBUF2 to disk.
-
- note: this stuff is all time
- critical.
-
- watch page boundries, don't
- remove NOP's, etc.
-
-
-
WRITE16 SEC ;anticipate write protect
STX SLOTZ
STX SLOTABS
LDA WRTDAT,X
LDA SETRD,X ;sense write protect
BMI WEXIT
LDA NBUF2
STA WTEMP
LDA #$FF ;sync byte
STA SETWRT,X ;write 1st nibble
ORA RDDATA,X
PHA
PLA
NOP
LDY #4
WSYNC PHA
PLA
JSR WNIBL7
DEY
BNE WSYNC
LDA #$D5 ;first data mark
JSR WNIBL9
LDA #$AA ;2nd data mark
JSR WNIBL9
LDA #$AD ;3rd data mark
JSR WNIBL9
TYA ;clear checksum
LDY #$56 ;NBUF2 index
BNE WDATA1 ;always taken
WDATA LDA NBUF2,Y ;get prior 6-bit nibble
WDATA1 EOR NBUF2-1,Y ;and XOR with current nibble
TAX
LDA NIBL,X
LDX SLOTZ
STA WRTDAT,X ;write nibble
LDA RDDATA,X
DEY ;next nibble
BNE WDATA
-
-
-
- now handle NBUF1.
-
-
- get prior nibble
-
LDA WTEMP
NOP
-
- loop to write out data in NBUF1
-
WDATA2 EOR NBUF1,Y
TAX
LDA NIBL,X
LDX SLOTABS
STA WRTDAT,X ;write nibble
LDA RDDATA,X
LDA NBUF1,Y
INY
BNE WDATA2
TAX
LDA NIBL,X
LDX SLOTZ
JSR WNIBL
LDA #$DE ;DM4, bit slip mark
JSR WNIBL9
LDA #$AA ;DM5, bsm
JSR WNIBL9
LDA #$EB ;DM6, bsm
JSR WNIBL9
-
- All done, close up the shop!
-
LDA #$FF
JSR WNIBL9
LDA SETRD,X
-
- and back to the read mode
-
WEXIT LDA RDDATA,X
RTS
ORG $B8B8
-
-
- WNIBL9 9 cycles, then write
-
WNIBL9 CLC
-
- WNIBL7 7 cycles, then write
-
WNIBL7 PHA
PLA
WNIBL STA WRTDAT,X
ORA RDDATA,X
RTS
ORG $B8C2
-
- Post nibblize routine.
-
- converts 342 nibbles of the form
-
- 00xxxxxx
-
- to eight bit bytes.
-
- The nibbles are stored in NBUF1
- and NBUF2, the 8-bit bytes will
- be stored at (BUFADR).
-
-
POSTNB16 LDY #0
POST1 LDX #$56
POST2 DEX
BMI POST1
-
- get byte and shift in L.O. two
- bits from NBUF2
-
LDA NBUF1,Y
LSR NBUF2,X
ROL
LSR NBUF2,X
ROL
STA (BUFADR),Y
INY
CPY TO
BNE POST2
RTS
ORG $B8DC
-
- READ routine, reads a sector
- from the disk and stores the
- data in NBUF1 and NBUF2.
-
READ16 LDY #$20
RSYNC DEY
BEQ RDERR
-
- wait until a byte is recieved
- from the disk drive.
-
RSYNC1 LDA RDDATA,X
BPL RSYNC1
-
- byte recieved, check for DM1
-
RSYNC2 EOR #$D5
BNE RSYNC
NOP
-
- get next byte and check for
- DM2
-
RSYNC3 LDA RDDATA,X
BPL RSYNC3
CMP #$AA
BNE RSYNC2
LDY #$56
RSYNC4 LDA RDDATA,X
BPL RSYNC4
CMP #$AD
BNE RSYNC2
-
- Read the data from the sector
-
LDA #0 ;init checksum
RDATA DEY
STY IDX
RDATA1 LDY RDDATA,X
BPL RDATA1
EOR MSWAIT,Y
LDY IDX
STA NBUF2,Y
BNE RDATA
RDATA2 STY IDX
RDATA3 LDY RDDATA,X
BPL RDATA3
EOR MSWAIT,Y
LDY IDX
STA NBUF1,Y
INY
BNE RDATA2
-
- get and check the checksum byte
-
RDATA4 LDY RDDATA,X
BPL RDATA4
CMP MSWAIT,Y
BNE RDERR
RDATA5 LDA RDDATA,X
BPL RDATA5
CMP #$DE
BNE RDERR
NOP
RDATA6 LDA RDDATA,X
BPL RDATA6
CMP #$AA
BEQ RDADRX
RDERR SEC
RTS
ORG $B944
-
- Read address field.
-
- Reads starting address marks
- ($D5, $AA, $96), address info
- (volume/track/sector/checksum),
- and closing address marks
- ($DE, $AA)
-
RDADR16 LDY #$FC
STY COUNT
RDASYN INY
BNE RDASYN1
INC COUNT
BEQ RDERR
-
- Read first address mark ($D5)
-
RDASYN1 LDA RDDATA,X
BPL RDASYN1
RDASYN2 CMP #$D5
BNE RDASYN
NOP
RDASYN3 LDA RDDATA,X
BPL RDASYN3
CMP #$AA
BNE RDASYN2
LDY #3
RDASYN4 LDA RDDATA,X
BPL RDASYN4
CMP #$96
BNE RDASYN2
-
- init checksum and read the
- address data field (four bytes)
-
LDA #0
RDAFLD STA CSUM
RDAFLD1 LDA RDDATA,X
BPL RDAFLD1
ROL
STA LAST
RDAFLD2 LDA RDDATA,X
BPL RDAFLD2
AND LAST
-
- store the data byte, update
- checksum, and repeat until
- entire address field is read.
-
STA SLOTEMP+1,Y
EOR CSUM
DEY
BPL RDAFLD
-
- Checksum (in acc) must be 0.
-
TAY
BNE RDERR
-
- Read first epilogue byte ($DE)
-
RDAFLD3 LDA RDDATA,X
BPL RDAFLD3
CMP #$DE
BNE RDERR
NOP
-
- Read second epilogue byte ($AA)
-
RDAFLD4 LDA RDDATA,X
BPL RDAFLD4
CMP #$AA
BNE RDERR
RDADRX CLC
RTS
ORG $B9A0
-
- SEEKABS routine, moves the
- disk head over the desired
- track.
-
SEEKABS STX SLOTEMP
STA TRKN
CMP DRV0TRK
BEQ RTS0
LDA #0
STA TRKCNT
MOVHEAD LDA DRV0TRK
STA PRIOR
SEC
SBC TRKN
BEQ ISTHERE
BCS MOVHEAD1
EOR #$FF
INC DRV0TRK
BCC MOVHEAD2
MOVHEAD1 ADC #$FE
DEC DRV0TRK
MOVHEAD2 CMP TRKCNT
BCC MOVHEAD3
LDA TRKCNT
MOVHEAD3 CMP #$C
BCS MOVHEAD4
TAY
MOVHEAD4 SEC
JSR CHKPOS
LDA ONTBL,Y
JSR MSWAIT
LDA PRIOR
CLC
JSR CHKPOS2
LDA OFFTBL,Y
JSR MSWAIT
INC TRKCNT
BNE MOVHEAD
ISTHERE JSR MSWAIT
CLC
CHKPOS LDA DRV0TRK
CHKPOS2 AND #3
ROL
ORA SLOTEMP
TAX
LDA PHASEOFF,X
LDX SLOTEMP
RTS0 RTS
TAX
LDY #$A0
ORG $BA00
-
- Head move delay subroutine
- delays ACC*100 usec
-
-
MSWAIT LDX #$11
MSWAIT1 DEX ;delay 86 usec
BNE MSWAIT1
INC MONTIMEL
BNE MSWAIT2
INC MONTIMEH
MSWAIT2 SEC
SBC #1
BNE MSWAIT
RTS
ORG $BA11
ONTBL HEX 0130
HEX 2824201E1D1C1C1C1C1C
OFFTBL HEX 702C26221F1E1D1C1C1C1C1C
NIBL HEX 96979A9B9D9E9FA6A7ABACADAEAFB2B3
HEX B4B5B6B7B9BABBBCBDBEBFCBCDCECFD3
HEX D6D7D9DADBDCDDDEDFE5E6E7E9EAEBEC
HEX EDEEEFF2F3F4F5F6F7F9FAFBFCFDFEFF
DS 45
HEX 0001989902039C040506A0A1A2A3A4A5
HEX 0708A8A9AA090A0B0C0DB0B10E0F1011
HEX 1213B81415161718191AC0C1C2C3C4C5
HEX C6C7C8C9CA1BCC1C1D1ED0D1D21FD4D5
HEX 2021D822232425262728E0E1E2E3E429
HEX 2A2BE82C2D2E2F303132F0F133343536
HEX 3738F8393A3B3C3D3E3F
ORG $BB00
-
-
- nibble buffers, must be in this
- order!
-
NBUF1 DS $100
NBUF2 DS $56
ORG $BC56
-
-
- Write an address field routine
-
-
WRADR16 SEC ;assume W/P error
LDA WRTDAT,X
LDA SETRD,X
BMI WPERROR
LDA #$FF
STA SETWRT,X
CMP RDDATA,X
PHA
PLA
FRMSYNC JSR WAIT12
JSR WAIT12
STA WRTDAT,X
CMP RDDATA,X
NOP
DEY
BNE FRMSYNC
LDA #$D5
JSR WBYTE9
LDA #$AA
JSR WBYTE9
LDA #$96
JSR WBYTE9
-
- output volume track sector
- and checksum
-
LDA VOLUME
JSR WBYTE
LDA TRACK
JSR WBYTE
LDA BUFADR+1
JSR WBYTE
LDA VOLUME
EOR TRACK
EOR BUFADR+1
PHA
LSR
ORA BUFADR
STA WRTDAT,X
LDA RDDATA,X
PLA
ORA #$AA
JSR WBYTE11
-
- output data marks 4,5, and 6
-
LDA #$DE
JSR WBYTE9
LDA #$AA
JSR WBYTE9
LDA #$EB
JSR WBYTE9
CLC
WPERROR LDA SETRD,X
LDA RDDATA,X
WAIT12 RTS
ORG $BCC4
-
- Write a byte as two four bit
- nibbles to the disk.
-
WBYTE PHA
LSR
ORA BUFADR
STA WRTDAT,X
CMP RDDATA,X
PLA
NOP
NOP
NOP
ORA #$AA
WBYTE11 NOP
WBYTE9 NOP
PHA
PLA
STA WRTDAT,X
CMP RDDATA,X
RTS
-
-
- FORCE RWTS TO PAGE BOUNDRY
-
DS 33
ORG $BD00
RWTS = *
-
- upon entry, A & Y point at IOB
-
STY IOBPL
STA IOBPH
-
- set up for one recal and 4 seeks
-
LDY #2
STY RECALCNT
LDY #4
STY SEEKCNT
LDY #1
LDA (IOBPL),Y
TAX
-
-
- see if slot # was changed
-
LDY #$F
CMP (IOBPL),Y
BEQ SAMESLOT
-
- if so, turn off old drive
-
TXA
PHA
LDA (IOBPL),Y
TAX
PLA
PHA
STA (IOBPL),Y
LDA SETRD,X
-
- delay until data is constant
-
STILLON LDY #8
LDA RDDATA,X
NOTSURE CMP RDDATA,X
BNE STILLON
DEY
BNE NOTSURE
PLA
TAX
SAMESLOT LDA SETRD,X
LDA RDDATA,X
LDY #8
NOTSURE1 LDA RDDATA,X
PHA
PLA
PHA
PLA
STX SLOT
CMP RDDATA,X
BNE NOTSURE2
DEY
BNE NOTSURE1
NOTSURE2 PHP
LDA DRVON,X
-
- move necessary pointers to
- page zero
-
LDY #6
PTRMOVE LDA (IOBPL),Y
STA PTRSDEST,Y
INY
CPY #$A
BNE PTRMOVE
LDY #3
LDA (DEVCTBL),Y
STA MONTIMEH
LDY #2
LDA (IOBPL),Y
LDY #$10
CMP (IOBPL),Y
BEQ PTRMOVE1
STA (IOBPL),Y
PLP
LDY #0
PHP
PTRMOVE1 ROR
BCC PTRMOVE2
LDA DRVSL1,X
BCS DRVSEL
PTRMOVE2 LDA DRVSL2,X
-
- save which drive is being used
-
DRVSEL ROR DRIVNO
PLP
PHP
BNE NOWAIT
LDY #7
-
- wait 100 usec for old drive's
- timing capacitor to discharge
-
STEPWAIT JSR MSWAIT
DEY
BNE STEPWAIT
LDX SLOT
NOWAIT LDY #4
LDA (IOBPL),Y
JSR MYSEEK
PLP
BNE TRYTRK
LDY MONTIMEH
BPL TRYTRK
-
- wait for motor to come up to
- speed.
-
MOTOROF LDY #$12
MOTOROF1 DEY
BNE MOTOROF1
INC MONTIMEL
BNE MOTOROF
INC MONTIMEH
BNE MOTOROF
-
- disk is now up to speed.
- if not format operation,
- position the head over the
- proper track
-
TRYTRK LDY #$C
LDA (IOBPL),Y
BEQ GALLDONE
CMP #4
BEQ FORMDSK
ROR
PHP ;save R/W status
BCS TRYTRK2
-
- if a read operation, must
- prenibblize first.
-
JSR PRENIB16
-
-
- set up for a maximum of 48
- retries.
-
TRYTRK2 LDY #$30
STY RETRYCNT
TRYADR LDX SLOT
JSR RDADR16
BCC RDRIGHT
TRYADR2 DEC RETRYCNT
BPL TRYADR
RECAL LDA CURTRK
PHA
LDA #$60
JSR SETTRK
DEC RECALCNT
BEQ DRVERROR
LDA #4
STA SEEKCNT
LDA #0
JSR MYSEEK
PLA
RESEEK JSR MYSEEK
JMP TRYTRK2
ORG $BDED
-
- We have just read an address
- field, now check for desired
- track, sector, and volume
-
RDRIGHT LDY TRKFND
CPY CURTRK
BEQ RTTRK
LDA CURTRK
PHA
TYA
JSR SETTRK
PLA
DEC SEEKCNT
BNE RESEEK
BEQ RECAL
DRVERROR PLA
LDA #$40
JMPTO1 PLP
JMP HNDLERR
GALLDONE BEQ ALLDONE
FORMDSK JMP DSKFORM
ORG $BE10
-
- Drive is on the right track,
- now check for a vol mismatch
-
RTTRK LDY #3
LDA (IOBPL),Y ;get desired volume
PHA
-
- Save volume actually found in
- RWTS IOB.
-
LDA VOLFND
LDY #$E
STA (IOBPL),Y
-
- If volume specified was zero,
- no error.
-
PLA
BEQ CRCTVOL
-
- Otherwise, check for a volume
- mismatch error.
-
CMP VOLFND
BEQ CRCTVOL
LDA #$20
BNE JMPTO1
-
- now check for the correct sector
-
CRCTVOL LDY #5
LDA (IOBPL),Y ;get the sector #
-
- Convert to a "soft" sector
- number by applying the software
- interleave.
-
TAY
LDA INTRLEAV,Y
-
- Are we at that sector yet?
-
CMP SECFND
BNE TRYADR2
-
- If so, see if we are doing a
- read or a write.
-
PLP
BCC WRIT
-
- Reading, so read in the 256
- bytes of data that follow.
-
JSR READ16
PHP
BCS TRYADR2
PLP
LDX #0
STX TO
-
- Convert the nibbles to bytes.
-
JSR POSTNB16
LDX SLOT
ALLDONE CLC
DFB $24 ;BIT L38
HNDLERR SEC ;OPCODE SKIPPED BY BIT L38
LDY #$D
STA (IOBPL),Y
LDA DRVOFF,X
RTS
ORG $BE51
-
- Performing a write, write the
- data (already nibblized) to
- the following data sector.
-
WRIT JSR WRITE16
BCC ALLDONE
LDA #$10
BCS HNDLERR
-
-
- MYSEEK is the seek routine,
- it seeks track 'N' in slot
- X/16
-
- If DRIVNO is negative - drive 0
- If DRIVNO is positive - drive 1
-
MYSEEK PHA
LDY #1
LDA (DEVCTBL),Y
ROR
PLA
BCC SEEK1
ASL
JSR SEEK1
LSR CURTRK
RTS
SEEK1 STA TRKN
JSR XTOY
LDA DRV0TRK,Y
BIT DRIVNO
BMI WASDO
LDA DRV1TRK,Y
WASDO STA DRV0TRK
LDA TRKN
BIT DRIVNO
BMI ISDRV0
STA DRV1TRK,Y
BPL GOSEEK
ISDRV0 STA DRV0TRK,Y
GOSEEK JMP SEEKABS
XTOY TXA
LSR
LSR
LSR
LSR
TAY
RTS
ORG $BE95
-
- This routine sets the slot
- dependant track location
-
SETTRK PHA
LDY #2
LDA (IOBPL),Y
ROR
ROR DRIVNO
JSR XTOY
PLA
ASL
BIT DRIVNO
BMI ONDRV0
STA DRV1TRK,Y
BPL RTS3
ONDRV0 STA DRV0TRK,Y
RTS3 RTS
ORG $BEAF
-
- This is the disk formatter
- routine.
-
DSKFORM LDY #3
LDA (IOBPL),Y
STA VOLUME
-
- Save timing constant in zero
- page (for time critical section)
-
LDA #$AA
STA BUFADR
LDY #$56
-
- Set up to start a track zero.
-
LDA #0
STA TRACK
DSKFORM1 STA NBUF2-1,Y
DEY
BNE DSKFORM1
DSKFORM2 STA NBUF1,Y
DEY
BNE DSKFORM2
-
- Pretend we are at track 40
- (acc=2*maxtracks)
-
LDA #$50
JSR SETTRK
-
- Start with 40 bytes of self
- sync bytes.
-
LDA #$28
STA SYNCNT
-
- Got to the track and format it.
-
NXTTRK LDA TRACK
JSR MYSEEK
JSR DISKF2
-
- Init in case of DISK I/O error.
-
LDA #8
BCS HNDERR
LDA #$30
STA RETRYCNT
-
- Verify the track just formatted.
-
NOGOOD SEC
DEC RETRYCNT
BEQ HNDERR
JSR RDADR16
BCS NOGOOD ;something wrong?
LDA SECFND
BNE NOGOOD
-
- Read the data and see if it's
- ok.
-
JSR READ16
BCS NOGOOD
-
- A-OK, move on to the next track.
-
INC TRACK
LDA TRACK
CMP #$23
BCC NXTTRK
-
- Force error flag (carry) off.
-
CLC
BCC DONEDSK
HNDERR LDY #$D
STA (IOBPL),Y
SEC
DONEDSK LDA DRVOFF,X
RTS
ORG $BF00
-
- Format the current track.
-
DISKF2 LDA #0 ;init sector #
STA BUFADR+1
LDY #$80 ;begin track with 128 sync bytes
BNE TRKFRM1
TRKFRM LDY SYNCNT
TRKFRM1 JSR WRADR16 ;write an address field
BCS DELAY12
JSR WRITE16
BCS DELAY12
-
- Increment the sector number
- and see if it is 16 yet.
-
INC BUFADR+1
LDA BUFADR+1
CMP #$10
BCC TRKFRM
LDY #$F
STY BUFADR+1
-
- mark the current track as
- formatted.
-
LDA #$30
STA RETRYCNT
INITMAP STA SECMAP,Y
DEY
BPL INITMAP
LDY SYNCNT
DELAY JSR DELAY12
JSR DELAY12
JSR DELAY12
PHA
PLA
NOP
DEY
BNE DELAY
JSR RDADR16
BCS DOAGAIN
LDA SECFND
BEQ ITSGOOD
LDA #$10
CMP SYNCNT
LDA SYNCNT
SBC #1
STA SYNCNT
CMP #5
BCS DOAGAIN
SEC
RTS
NXTSEC JSR RDADR16
BCS NXTTRY
ITSGOOD JSR READ16
BCC MARKMAP
NXTTRY DEC RETRYCNT
BNE NXTSEC
DOAGAIN JSR RDADR16
BCS ERRCNT
LDA SECFND
CMP #$F
BNE ERRCNT
JSR READ16
BCC DISKF2
ERRCNT DEC RETRYCNT
BNE DOAGAIN
SEC
DELAY12 RTS
MARKMAP LDY SECFND
LDA SECMAP,Y
BMI NXTTRY
LDA #$FF
STA SECMAP,Y
DEC BUFADR+1
BPL NXTSEC
LDA TRACK
BNE TRKDONE
LDA SYNCNT
CMP #$10
BCC DELAY12
DEC SYNCNT
DEC SYNCNT
TRKDONE CLC
RTS
ORG $BFA8
-
- SECMAP- used to mark initialized
- sectors.
-
SECMAP HEX FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-
-
- Interleave remapping table
-
INTRLEAV HEX 000D0B09070503010E0C0A080604020F
ORG $BFC8
-
-
- DOS 3.3 patches. WARNING! These
- are addressed by object code
- and should not be moved without
- careful thought.
-
JSR SETVID
LDA ROM
LDA ROM
LDA #0
STA BASIC
JMP RESTART
DS 3
ORG $BFDC
STA TEMP1
STA BYTVAL
STA BYTVAL+1
RTS
JSR RSET0
STY RUNINTRC
RTS
JSR SAVFMW
LDX STKSAVE
TXS
JSR CLOSEALL
TSX
STX STKSAVE
LDA #9
JMP SETERROR