mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
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.
632 lines
24 KiB
Plaintext
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
|
|
|
|
|