mac-rom/Drivers/Sony/SonyRead.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

632 lines
24 KiB
Plaintext

;
; File: SonyRead.a
;
; Contains: This file contains disk driver routines used to read
; sector information from twiggy diskettes.
;
; Written by: Larry Kenyon
;
; Copyright: © 1982-1992 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM6> 12/14/92 RC Restore Pre-PDM D2 with Horror rollin
; <SM4> 12/7/92 rab Roll in Horror changes. Comments followÉ
; <H5> 6/19/92 CMP Patched SetUpPoll to set A6 to point to a bogus set of
; "registers" so that no SCC polling is done if there is no
; PollProc installed. This is because on DB Lite with LocalTalk
; connected to the internal serial port, we get so much poll data
; that we corrupt the heap.
; <H4> 11/14/91 SWC Converted the SCC polling code to a macro (in SonyHdr.a) so it's
; easier to overpatch. Also cleaned up comments.
; <6> 7/14/92 CSS Fixed the comment below so an exact version of this
; file could be copied into SuperMario.
; <5> 4/27/92 JSM Get rid of conditionals: hasHarpoVIA is always false,
; supportsMFM and forROM are always true. This file now has no
; conditionals.
; <4> 1/21/91 SWC Cleaned up header comments.
; <3> 9/21/90 BG Removed <2>. 040s are behaving more reliably now.
; <2> 6/18/90 CCH Added NOPs for flaky 68040's.
; <2.4> 5/23/89 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.3> 4/29/89 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.2> 4/10/89 gmr No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.1> 2/21/89 GGD Added extra VIA accesses in read code to allow time for a new
; bit to shift in, and clear the data latch, so that a previous
; data byte doesn't get interpreted as a new byte on fast
; processors (25mhz). Changed bit number of SCC/VIA direction bit
; save in chipState.
; <2.0> 12/15/88 GGD Changed some machine based conditionals to feature based.
; Modified nibble timeout code in RdAddr to be processor speed
; independent.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.9> 9/29/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.8> 9/19/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.7> 8/16/88 GGD Changed usages of absolute VIA/SCC hardware addresses in
; SetUpPoll, to use low mem hw base addresses instead. Changed
; vBufA to vBufD for HcMac. Saved and changed VIA Buf B Direction
; bit in SetUpPoll for HcMac.
; <1.7> 8/9/88 Saved and changed VIA Buf B Direction bit in SetUpPoll for HcMac.
; <1.7> 8/5/88 GGD Changed usages of absolute VIA/SCC hardware addresses in
; SetUpPoll, to use low mem hw base addresses instead. Changed
; vBufA to vBufD for HcMac.
; <1.6> 7/15/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.5> 6/15/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.4> 5/25/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.3> 5/24/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.2> 5/3/88 GGD No changes, entire sony driver checked out and in as a group.
; <1.1> 4/18/88 GGD Merged in MFM support <C437> by Steve Christensen Renamed
; RdVerify to RVerify to eleminate the name conflict with the
; RdVerify equate in SysEqu.a (removes an ASM warning)
; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ
; <C965> 11/13/87 MSH Time-out loop in RdAddr was too short because we are so fast.
; <C907> 10/8/87 MSH Port to HcMac (Laguna).
; <C437> 11/21/86 SWC Patched RdAddr and RdData to jump to their MFM counterparts if
; we're running in MFM mode.
; <A351> 11/5/86 TJ Text cleanup
; <A302> 10/30/86 TJ Removed IWM absolute addresses.
; <C55> 6/25/86 RDC Increased no-nibble timeout for NuMac
; 11/2/85 LAK Use NewIntf instead of Sides when adjusting MustFndCnt.
; 7/29/85 RDC Changed interrupt level settings to use equates
; 7/24/85 LAK Convert back to WorkShop.
; 1/15/85 JTC convert to MDS.
; 10/26/84 LAK Patched RdAddr to compensate for missed nibbles after write
; (during erase) and increased no-nibble timeout.
; 8/18/83 LAK Addresses of AdrMks and DtaMks tables are passed thru vectors.
; 8/11/83 LAK Sets head select according to SideTrack.
; 8/4/83 LAK Added verify-only read (does it if lowmem var DskVerify is
; non-zero).
; 4/17/83 LAK Rewrote both RdAddr and RdData to incorporate SCC channel A
; polling scheme.
; 12/17/82 LAK Changed nibble "must-find" count to 1500 from 3000.
; 11/18/82 LAK Added head select setup and a search for some nibbles to avoid
; long delays on blank tracks
;
title 'File: SonyRead.a'
eject
;_______________________________________________________________________
;
; Routine: RdAddr,SetUpPoll,RdAddrSetup
; Arguments: A5.L (input) -- ptr to 6522 A-reg (has head sel, wait/req)
; A6.L (input) -- ptr to SCC A-channel data register
; A2.L (input) -- pointer to AdrMks table
; D0.W (output) --
; 0-1499 = no error, 1500 - nybbles before address mark
; -66 = no transitions found
; -67 = no address mark found (no header read)
; -68 = bad data nybble (header read aborted)
; -69 = bad checksum (header read but is inconsistent)
; -70 = bad bit slip marks (header read but may be bad)
; D1.W (output) -- <side><track> (low-order 12 bits)
; D2.W (output) -- <sector>
; D3.W (output) -- <volume>
; A3.L (output) -- ptr to <DNib-$96> (denibblizing table)
; A4.L (output) -- DiskQ6L pointer
; D4,D5,A0,A2 are trashed
; D6-D7 and A1,A5-A6 are preserved
; Function: This routine reads the next address mark that spins by. On exit,
; the attributes of the mark are passed back as:
;
; D1 = <side> <track>
; D2 = <sector>
; D3 = <volume>
;
; The disk should be up to speed with the correct head
; selected, and interrupts should be disabled.
;
; 'Nibble must find' count may have to be tuned.
;_______________________________________________________________________
BLANKS ON
STRING ASIS
AdrMks DC.B $D5,$AA,$96,$DE,$AA,$FF
; code-saving proc called by RdAddrSetUp and FigTrkSpeed
SetUpPoll MOVE.L JSetUpPoll,-(SP)
RTS
BogusSCC DCB.B 6,0 ; this is the bogus SCC register set <SM4>
jtSetUpPoll ; <SM4>
TST.L PollProc ; check to see if there is a pollproc <SM4>
BEQ.S @1 ; -> no, point A6 to a bogus place <SM4>
MOVEA.L SCCRd,A6 ; get SCC read base address <SM4>
BRA.S @2 ; <SM4>
@1 LEA BogusSCC,A6 ; fake SCC base address into A6 <SM4>
@2 ; <SM4>
ADDQ.L #AData,A6 ; SCC A-reg data <1.7>
MOVEA.L VIA,A5 ; get VIA base address <1.7>
ADDA.W #VBufD,A5 ; 6522 disk-reg has head sel, wait/req <1.7>
ORI #HiIntMask,SR ; no ints from now on! <29Jul85>
MOVE.L SP,PollStack ; init PollStack at current stack level
ADD.L D0,PollStack ; compensate for 1 or 2 levels
RTS
RdAddrSetup MOVEQ #8,D0 ; init PollStack 8 bytes down
BSR.S SetUpPoll
MOVEQ #RdDtaAdr,D0 ; assume side 0
BTST #3,SideTrack(A1) ; side 1?
BEQ.S @1 ; br if not
MOVEQ #RdDta1Adr,D0 ; set for side 1
@1 BSR AdrDisk
RdAddr
BSR GetDrv1 ;Get the drive offset <C437/21nov86>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/21nov86>
BMI mRdAddr ;-> yes, do the MFM version <C437/21nov86>
LEA AdrMks,A2 ; point to our mark table
MOVE.L JRdAddr,-(SP)
RTS
jtRdAddr
; When reading immediatly after a write, the drive may suppress read data for
; up to 620µsec, so we will wait at least that long for the first byte to be valid.
; We look for 3 bytes @16µsec per byte brings the total wait to 668µsec.
; There is an access to the VIA in the loop, which must synchronize with the 783khz
; clock (1.2765µsec per access), so we compute the timeout for the fastest processor
; which would be 668/1.2765 = 523 iterations, and add in another 10% for good measure
; to get 575. It doesn't hurt for it to be too big on slower processors, it would just
; take longer to get noNybErr which should never occur unless there is a hardware error.
MOVEQ #3,D3 ; try for 3 bytes
MOVE.W #575,D2 ; setup loop timeout count <2.0>
MOVEQ #0,D5 ; D5 is used for offsets, so clear it
movea.l IWM,A4 ; <A302/30oct86><2.0>
adda.w #Q6L,A4 ; A4 points to shiftreg for speed <A302/30oct86><2.0>
MOVE.L (SP)+,DskRtnAdr ; return address
@1 _PollSCC ; poll the SCC modem port <H4><SM4>
@2 MOVE.B (A4),D5 ; read a nibble
DBRA D2,@3 ; if no timeout yet, see if it was valid
MOVEQ #NoNybErr,D0 ; set CCR
BRA RdAddrXit
@3 BPL.S @1 ; try again if no nibble
SUBQ.W #1,D3 ; leave D3=0
BNE.S @1 ; if we can find 3, should be ok
MOVE.W #MustFindCt,D0 ; D0 holds nibble must find count
TST.B NewIntf(A1,D1) ; new interface drive? <02Nov85>
BEQ.S @4
MOVE.W #MustFindCt-32,D0
@4 LEA (DNib-$96),A3 ; A3 points to denibblizing table
RdAddr1 MOVE.L A2,A0 ; point to our mark table
MOVEQ #3,D1 ;
@1 MOVE.B (A4),D5 ;
BPL.S @1 ;
_PollSCC ; poll the SCC modem port <H4><SM4>
@2 DBRA D0,@3 ;
MOVEQ #NoAdrMkErr,D0 ; after 1500 tries report error
BRA.W RdAddrXit
@3 CMP.B (A0)+,D5 ;
BNE.S RdAddr1 ;
SUBQ.W #1,D1 ;
BNE.S @1 ; leave D1=0 (returns <side><track>)
; We found an address mark header so retrieve the information from the mark.
_PollSCC ; poll the SCC modem port <H4><SM4>
RdAddrMk MOVE.B (A4),D5 ; read track number byte
BPL.S RdAddrMk ;
MOVE.B 0(A3,D5.W),D1 ; denibblize it
MOVE.B D1,D4 ; init the checksum
ROR.W #6,D1 ; make room for 6 bits of side . . .
_PollSCC ; poll the SCC modem port <H4><SM4>
@2 MOVE.B (A4),D5 ; read sector number byte
BPL.S @2 ;
MOVEQ #0,D2 ; zero extend the sector number <2.0>
MOVE.B 0(A3,D5.W),D2 ; denibblize it
EOR.B D2,D4 ; calculate the checksum
_PollSCC ; poll the SCC modem port <H4><SM4>
@3 MOVE.B (A4),D5 ; read side number byte
BPL.S @3 ;
MOVE.B 0(A3,D5.W),D1 ; denibblize it
EOR.B D1,D4 ; calculate the checksum
ROL.W #6,D1 ; D1,bits 0-11 = <side><track>
_PollSCC ; poll the SCC modem port <H4><SM4>
@4 MOVE.B (A4),D5 ; read volume number byte
BPL.S @4 ;
MOVE.B 0(A3,D5.W),D3 ; denibblize it
EOR.B D3,D4 ; calculate the checksum
_PollSCC ; poll the SCC modem port <H4><SM4>
@5 MOVE.B (A4),D5 ; read checksum nibble
BPL.S @5 ;
MOVE.B 0(A3,D5.W),D5 ; denibblize it
EOR.B D5,D4
BNE.S BadCkSum ; report bad checksum
MOVEQ #1,D4 ; 2 bit slip marks
RdAddrEnd
_PollSCC ; poll the SCC modem port <H4><SM4>
@1 MOVE.B (A4),D5 ; get first trail nibble <2.1>
BPL.S @1 ; <2.1>
CMP.B (A0)+,D5 ; trail mark ok?
BNE.S NoSlip ; br if not
DBRA D4,RdAddrEnd
RdAddrXit BRA DskRtn ; return with D0 positive, BPL for ok
BadCkSum MOVEQ #BadCkSmErr,D0
BRA.S RdAddrXit
NoSlip MOVEQ #BadBtSlpErr,D0
BRA.S RdAddrXit
eject ; <A351/05nov86>
;_______________________________________________________________________
;
; Routine: RdData
; Arguments: A0.L (input) -- ptr to 512-byte data buffer
; A3.L (input) -- ptr to <DNib-$96> (denibblizing table)
; A4.L (input) -- DiskQ6L pointer
; A5.L (input) -- ptr to 6522 A-reg (has head sel, wait/req)
; A6.L (input) -- ptr to SCC channel A data register
;
; D0.W (output) --
; 0 = no error
; -71 = no data mark found
; -72 = bad checksum
; -73 = bad bit slip marks
; A3-A6 are preserved
; all other registers are trashed
; Function: This routine reads the next data mark that spins by. The 524
; bytes of data are split as follows: the first 12 bytes are put
; into TagData, the remaining 512 bytes into the buffer at (A0).
; This routine denibblizes and computes the checksum on the fly,
; so it may be used for one-to-one reading.
;
; The disk should be up to speed with the correct head
; selected, and interrupts should be disabled. This routine
; should be called immediately after RdAddr for disk reads.
;
; To do:
;
; Currently (on the SCC version Macintosh), there is no time to check each
; nibble when denibblizing data nibbles for $FF mappings; this should be added
; when this routine is put in ROM or run on a faster processor.
;
; An optimization could be added for missed address marks: if the calling
; routine is after a particular sector number and already knows which track
; it is on, this routine could be modified to check for that sector in the
; byte just before the encoded data, and return immediately on no match . . .
;_______________________________________________________________________
DtaMks DC.B $D5,$AA,$AD,$DE,$AA,$FF
RdData
BSR GetDrv1 ;Get the drive offset <C437/21nov86>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/21nov86>
BMI mRdData ;-> yes, do the MFM version <C437/21nov86>
LEA DtaMks,A1
MOVE.L JRdData,-(SP)
RTS
jtRdData MOVE.L (SP)+,DskRtnAdr ; save return address here
MOVEQ #48,D2 ; D2 holds nibble must find count
MOVEQ #0,D3 ; clear D3 for use as an index
MOVEQ #-64,D0 ; $C0 used to mask off bits 0-5
MOVE.L #$1FE000A,D4 ; byte read counts for 2 buffers
MOVEQ #0,D5 ; init CkSumA
MOVEQ #0,D6 ; init CkSumB
MOVEQ #0,D7 ; init CkSumC
; try to find a valid header until we've timed out
RdData1 MOVE.L A1,A2 ; address of address marks
MOVEQ #3,D1
@1 MOVE.B (A4),D3
BPL.S @1
_PollSCC ; poll the SCC modem port <H4><SM4>
@2 DBRA D2,@3
MOVEQ #NoDtaMkErr,D0 ; after 48 tries report error
BRA.S RdAddrXit
@3 CMP.B (A2)+,D3
BNE.S RdData1
SUBQ.W #1,D1
BNE.S @1 ; leave D1=0
; We found a data mark header so retrieve the information from the mark.
@4 MOVE.B (A4),D3 ; read the encoded sector number
BPL.S @4 ;
LEA TagData+1,A1 ; A1 points to buffer for extra bytes
MOVE.B 0(A3,D3.W),(A1)+ ;
;_______________________________________________________________________
;
; We found the header so the actual info is about to spin by. There are 699
; nibbles followed by 3 checksum nibbles. We use a four nibble loop for the
; data nibbles . . . the first 12 bytes go into a separate buffer, then 512
; bytes are placed in the user's buffer.
;
; D7 = CkSumC A7 = stack (where poll data is pushed)
; D6 = CkSumB A6 = ptr to SCC chan A data reg
; D5 = CkSumA A5 = ptr to 6522 A-reg
; D4 = loop counters A4 = ptr to Q6L (IWM)
; D3 = buffer A3 = ptr to denibblizing table
; D2 = buffer A2 = ptr to trail mark table
; D1 = buffer for odd bits A1 = ptr to data buffer
; D0 = $C0 mask A0 = ptr to user buffer
;_______________________________________________________________________
RdData2 _PollSCC ; poll the SCC modem port <H4><SM4>
@0 MOVE.B (A4),D3 ; read a nibble
BPL.S RdData2 ;
MOVE.B 0(A3,D3.W),D1 ; D1 = [00][00][A7][A6][B7][B6][C7][C6]
ROL.B #2,D1 ; D1 = [A7][A6][B7][B6][C7][C6][00][00]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [A7][A6][00][00][00][00][00][00]
@1 MOVE.B (A4),D3 ; read a nibble
BPL.S @1 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteA' (no time for bad nibs)
MOVE.B D7,D3 ;
ADD.B D7,D3 ; ex <- CkSumC[7]
ROL.B #1,D7 ; CkSumC' <- ROL (CkSumC)
EOR.B D7,D2 ; ByteA <- ByteA' XOR CkSumC'
MOVE.B D2,(A1)+ ; store first byte
ADDX.B D2,D5 ; CkSumA',ex <- CkSumA + ByteA + ex
ROL.B #2,D1 ; D1 = [B7][B6][C7][C6][00][00][A7][A6]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [B7][B6][00][00][00][00][00][00]
@2 MOVE.B (A4),D3 ; read a nibble
BPL.S @2 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteB' (no time for bad nibs)
EOR.B D5,D2 ; D2 = ByteB
MOVE.B D2,(A1)+ ; store second byte
ADDX.B D2,D6 ; CkSumB',ex <- CkSumB + ByteB + ex
ROL.B #2,D1 ; D1 = [C7][C6][0][0][A7][A6][B7][B6]
AND.B D0,D1 ; D1 = [C7][C6][0][0][0][0][0][0]
_PollSCC ; poll the SCC modem port <H4><SM4>
@3 MOVE.B (A4),D3 ; read a nibble
BPL.S @3 ;
OR.B 0(A3,D3.W),D1 ; D1 = ByteC' (no time for bad nibs)
EOR.B D6,D1 ; D1 = ByteC
MOVE.B D1,(A1)+ ; store third byte
ADDX.B D1,D7 ; CkSumC'' <- CkSumC' + ByteC + ex
SUBQ.W #3,D4 ; decrement counter by 3 bytes
BPL.S RdData2 ; loop (careful->subq changes ex bit)
SWAP D4 ; first time thru switch counters, buffers
TST.B DskVerify ; doing a read verify?
BEQ.S RdData3A ; br if not
BRA.S RdVer1 ; br if so (only verify, don't read)
RdData3 _PollSCC ; poll the SCC modem port <H4><SM4>
RdData3A MOVE.B (A4),D3 ; read a nibble
BPL.S RdData3 ;
MOVE.B 0(A3,D3.W),D1 ; D1 = [00][00][A7][A6][B7][B6][C7][C6]
ROL.B #2,D1 ; D1 = [A7][A6][B7][B6][C7][C6][00][00]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [A7][A6][00][00][00][00][00][00]
@1 MOVE.B (A4),D3 ; read a nibble
BPL.S @1 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteA' (no time for bad nibs)
MOVE.B D7,D3 ;
ADD.B D7,D3 ; ex <- CkSumC[7]
ROL.B #1,D7 ; CkSumC' <- ROL (CkSumC)
EOR.B D7,D2 ; ByteA <- ByteA' XOR CkSumC'
MOVE.B D2,(A0)+ ; store first byte
ADDX.B D2,D5 ; CkSumA',ex <- CkSumA + ByteA + ex
ROL.B #2,D1 ; D1 = [B7][B6][C7][C6][00][00][A7][A6]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [B7][B6][00][00][00][00][00][00]
@2 MOVE.B (A4),D3 ; read a nibble
BPL.S @2 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteB' (no time for bad nibs)
EOR.B D5,D2 ; D2 = ByteB
MOVE.B D2,(A0)+ ; store second byte
ADDX.B D2,D6 ; CkSumB',ex <- CkSumB + ByteB + ex
TST.W D4 ; check counter
BEQ.W RdCkSum ; we are done when counter is 0
ROL.B #2,D1 ; D1 = [C7][C6][0][0][A7][A6][B7][B6]
AND.B D0,D1 ; D1 = [C7][C6][0][0][0][0][0][0]
_PollSCC ; poll the SCC modem port <H4><SM4>
@3 MOVE.B (A4),D3 ; read a nibble
BPL.S @3 ;
OR.B 0(A3,D3.W),D1 ; D1 = ByteC' (no time for bad nibs)
EOR.B D6,D1 ; D1 = ByteC
MOVE.B D1,(A0)+ ; store third byte
ADDX.B D1,D7 ; CkSumC'' <- CkSumC' + ByteC + ex
SUBQ.W #3,D4 ; decrement counter by 3 bytes
BRA.S RdData3 ; loop (careful->subq changes ex bit)
RVerify _PollSCC ; poll the SCC modem port <H4><SM4>
RdVer1 MOVE.B (A4),D3 ; read a nibble
BPL.S RVerify ; <1.1/12feb88>
MOVE.B 0(A3,D3.W),D1 ; D1 = [00][00][A7][A6][B7][B6][C7][C6]
ROL.B #2,D1 ; D1 = [A7][A6][B7][B6][C7][C6][00][00]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [A7][A6][00][00][00][00][00][00]
@1 MOVE.B (A4),D3 ; read a nibble
BPL.S @1 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteA' (no time for bad nibs)
MOVE.B D7,D3 ;
ADD.B D7,D3 ; ex <- CkSumC[7]
ROL.B #1,D7 ; CkSumC' <- ROL (CkSumC)
EOR.B D7,D2 ; ByteA <- ByteA' XOR CkSumC'
CMP.B (A0)+,D2 ; check first byte
BNE.S @4 ; (to RdVerErr) exit on errors
ADDX.B D2,D5 ; CkSumA',ex <- CkSumA + ByteA + ex
ROL.B #2,D1 ; D1 = [B7][B6][C7][C6][00][00][A7][A6]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [B7][B6][00][00][00][00][00][00]
@2 MOVE.B (A4),D3 ; read a nibble
BPL.S @2 ;
OR.B 0(A3,D3.W),D2 ; D2 = ByteB' (no time for bad nibs)
EOR.B D5,D2 ; D2 = ByteB
CMP.B (A0)+,D2 ; compare second byte
BNE.W RdVerErr ; exit on errors
ADDX.B D2,D6 ; CkSumB',ex <- CkSumB + ByteB + ex
TST.W D4 ;
BEQ.S RdCkSum ; we are done when counter is 0
ROL.B #2,D1 ; D1 = [C7][C6][0][0][A7][A6][B7][B6]
AND.B D0,D1 ; D1 = [C7][C6][0][0][0][0][0][0]
_PollSCC ; poll the SCC modem port <H4><SM4>
@3 MOVE.B (A4),D3 ; read a nibble
BPL.S @3 ;
OR.B 0(A3,D3.W),D1 ; D1 = ByteC' (no time for bad nibs)
EOR.B D6,D1 ; D1 = ByteC
CMP.B (A0)+,D1 ; compare third byte
@4 BNE.S RdVerErr ; exit on errors
ADDX.B D1,D7 ; CkSumC'' <- CkSumC' + ByteC + ex
SUBQ.W #3,D4 ; decrement counter by 3 bytes
BRA.S RVerify ; loop (careful->subq changes ex bit) <1.1/12feb88>
; now read the four checksum nibbles and compare . . .
RdCkSum _PollSCC ; poll the SCC modem port <H4><SM4>
@0 MOVE.B (A4),D3 ; read a nibble
BPL.S @0 ;
MOVE.B 0(A3,D3.W),D1 ; D1 = [00][00][A7][A6][B7][B6][C7][C6]
BMI.S DCkSumBad ; branch if bad nibble
ROL.B #2,D1 ; D1 = [A7][A6][B7][B6][C7][C6][00][00]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [A7][A6][00][00][00][00][00][00]
@1 MOVE.B (A4),D3 ; read a nibble
BPL.S @1 ;
MOVE.B 0(A3,D3.W),D3 ; D3 = [0][0][A5][A4][A3][A2][A1][A0]
BMI.S DCkSumBad ; br if bad nibble
OR.B D3,D2 ; D2 = CkSumA
CMP.B D2,D5 ; check against calculated value
BNE.S DCkSumBad ; br if bad
ROL.B #2,D1 ; D1 = [B7][B6][C7][C6][00][00][A7][A6]
MOVE.B D1,D2 ;
AND.B D0,D2 ; D2 = [B7][B6][00][00][00][00][00][00]
@2 MOVE.B (A4),D3 ; read a nibble
BPL.S @2 ;
MOVE.B 0(A3,D3.W),D3 ; D3 = [0][0][B5][B4][B3][B2][B1][B0]
BMI.S DCkSumBad ; branch if bad nibble
OR.B D3,D2 ; D2 = CkSumB
CMP.B D2,D6 ; check against calculated value
BNE.S DCkSumBad ; br if bad
ROL.B #2,D1 ; D1 = [C7][C6][00][00][A7][A6][B7][B6]
AND.B D0,D1 ; D1 = [C7][C6][00][00][00][00][00][00]
_PollSCC ; poll the SCC modem port <H4><SM4>
@3 MOVE.B (A4),D3 ; read a nibble
BPL.S @3 ;
MOVE.B 0(A3,D3.W),D3 ; D3 = [00][00][C5][C4][C3][C2][C1][C0]
BMI.S DCkSumBad ; branch if bad nibble
OR.B D3,D1 ; D1 = CkSumC
CMP.B D1,D7 ; check against calculated value
BEQ.S RdSlip ;
DCkSumBad MOVEQ #BadDCkSum,D0 ; bad checksum
BRA.S RdDataXit
RdVerErr MOVEQ #DataVerErr,D0
BRA.S RdDataXit
; finally we must read the bit slip marks before giving our stamp of approval
RdSlip MOVEQ #1,D4 ; 2 bit slip marks
@1 MOVE.B (A4),D3 ; get next trail nibble
BPL.S @1 ;
_PollSCC ; poll the SCC modem port <H4><SM4>
@2 CMP.B (A2)+,D3 ; trail mark ok?
BNE.S NoDSlip ; br if not
DBRA D4,@1
MOVEQ #0,D0 ; report success!!!
RdDataXit BRA DskRtn ; return with D0 positive, BPL for ok
NoDSlip MOVEQ #BadDBtSlp,D0 ; bad slip nibbles is error code 3 . . .
BRA.S RdDataXit
; Denibblizing Table (nibbles $96 thru $FF converted to $00 thru $3F)
; $FF means illegal nibble: if we checked for illegal nibbles (currently we
; don't have time for it), this table could be extended down to $80 . . .
DNib
DC.B $00,$01,$FF,$FF,$02,$03 ; $96,$97, , ,$9A,$9B
DC.B $FF,$04,$05,$06,$FF,$FF ; ,$9D,$9E,$9F, ,
DC.B $FF,$FF,$FF,$FF,$07,$08 ; , , , ,$A6,$A7
DC.B $FF,$FF,$FF,$09,$0A,$0B ; , , ,$AB,$AC,$AD
DC.B $0C,$0D,$FF,$FF,$0E,$0F ; $AE,$AF, , ,$B2,$B3
DC.B $10,$11,$12,$13,$FF,$14 ; $B4,$B5,$B6,$B7, ,$B9
DC.B $15,$16,$17,$18,$19,$1A ; $BA,$BB,$BC,$BD,$BE,$BF
DC.B $FF,$FF,$FF,$FF,$FF,$FF ; , , , , ,
DC.B $FF,$FF,$FF,$FF,$FF,$1B ; , , , , ,$CB
DC.B $FF,$1C,$1D,$1E,$FF,$FF ; ,$CD,$CE,$CF,
DC.B $FF,$1F,$FF,$FF,$20,$21 ; ,$D3, , ,$D6,$D7
DC.B $FF,$22,$23,$24,$25,$26 ; ,$D9,$DA,$DB,$DC,$DD
DC.B $27,$28,$FF,$FF,$FF,$FF ; $DE,$DF,
DC.B $FF,$29,$2A,$2B,$FF,$2C ; ,$E5,$E6,$E7, ,$E9
DC.B $2D,$2E,$2F,$30,$31,$32 ; $EA,$EB,$EC,$ED,$EE,$EF
DC.B $FF,$FF,$33,$34,$35,$36 ; , ,$F2,$F3,$F4,$F5
DC.B $37,$38,$FF,$39,$3A,$3B ; $F6,$F7, ,$F9,$FA,$FB
DC.B $3C,$3D,$3E,$3F ; $FC,$FD,$FE,$FF