sys7.1-doc-wip/Drivers/Sony/SonyWrite.a
2019-07-27 22:37:48 +08:00

424 lines
15 KiB
Plaintext

;
; File: SonyWrite.a
;
; Contains: This file contains the disk driver routine used to write
; data mark information on twiggy diskettes. This routine nibblizes
; and computes the checksum on the fly, so it may be used for
; one-to-one writing.
;
; Written by: Larry Kenyon
;
; Copyright: © 1982-1990, 1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM9> 1/10/93 RC Added Nops for Smurf
; <SM8> 12/14/92 RC Restore to before PDM D2 Build with Horror Roll-in
; <SM5> 12/7/92 rab Roll in Horror changes. Comments follow…
; <4> 11/14/91 SWC Shortened the WrData patches for SWIM2 to save patch space.
; Converted the SCC polling code to a macro to make it easier to
; overpatch.
; <2> 10/18/91 CMP Overpatched to support SWIM2.
; <SM4> 10/18/92 CCH Added nop's for systems with non-serial writes to IO space.
; <5> 7/14/92 CSS Fixed the comment below so an exact version of this
; file could be copied into SuperMario.
; <4> 4/27/92 JSM Get rid of conditionals: supportsMFM and forROM are always true.
; This file now has no conditionals.
; <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 No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.0> 12/15/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <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 No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <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
; <1.0> 2/12/88 BBM Adding file for the first time into EASE…
; <C437> 11/21/86 SWC Patched WrData to jump to its MFM counterpart if we're running
; in MFM mode.
; <A351> 11/5/86 TJ Text cleanup
; 1/15/85 JTC convert to MDS.
; 8/15/83 LAK A2 now passed in as parameter.
; 7/21/83 LAK No longer fill in Time (in TagData): done in SonyRWT.
; 4/18/83 LAK Rewrote to incorporate SCC channel A polling scheme.
; 11/18/82 LAK Clear D0, D1 at start
; 11/1/82 LAK Added full handshaking for inclusion in ROM, 512-dot version.
;
title 'File: SonyWrite.a'
;_______________________________________________________________________
;
; Routines: WrData
; Larry Kenyon 20/July/82
;
; Arguments: A0.L (input) -- ptr to 512-byte data buffer
; A2.L (input) -- ptr to data mark 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
; TagData (in) -- sector # + 12 bytes of tag data to write
; D0.W (output) --
; 0 = no error
; -9 = write underrun detected
; A4-A6 are preserved
; all other registers are trashed
; Function: This file contains the disk driver routine used to write
; data mark information on twiggy diskettes. This routine nibblizes
; and computes the checksum on the fly, so it may be used for
; one-to-one writing.
;
; Since timing is tight coming into this routine, the disk
; write-protect sense line should be checked by the read/write
; track logic.
;
;
; Modification History:
;
; 01 Nov 82 LAK Added full handshaking for inclusion in ROM, 512-dot version.
; 18 Nov 82 LAK Clear D0, D1 at start
; 18 Apr 83 LAK Rewrote to incorporate SCC channel A polling scheme.
; 21 Jul 83 LAK No longer fill in Time (in TagData): done in SonyRWT.
; 15 Aug 83 LAK A2 now passed in as parameter.
;
; 15 Jan 85 JTC convert to MDS.
;_______________________________________________________________________
; A30230oct86 TJ Removed absolute IWM addresses.
; A351 05Nov86 TJ Text cleanup
;_______________________________________________________________________
;<C437/21nov86> SWC Patched WrData to jump to its MFM counterpart
; if we're running in MFM mode.
;_______________________________________________________________________
BLANKS ON
STRING ASIS
HdrSize EQU 8
MarkTbl DC.B $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern
DC.B $D5,$AA ; actual header ($AD written separately)
WrData
BSR GetDrv1 ;Get the drive offset <C437/21nov86>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/21nov86>
BMI mWrData ;-> yes, do the MFM version <C437/21nov86>
LEA MarkTbl,A2 ;
MOVE.L JWrData,-(SP)
RTS
jtWrData MOVE.L (SP)+,DskRtnAdr ; save return address here
LEA TagData+1,A1 ; data first comes from TagData
MOVE.L #$2010009,D4 ; adjusted byte write counts for 2 buffers
MOVEQ #0,D2 ; clear high byte for indexing
MOVEQ #0,D3 ; D3 also: note D0,D1 cleared later
;_______________________________________________________________________
;
; 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 counts A4 = ptr to Q6L
; D3 = A7A6B7B6C7C6 nibble A3 = ptr to Q6H
; D2 = C5C4C3C2C1C0 nibble A2 = ptr to nibble, mark tables
; D1 = B5B4B3B2B1B0 nibble A1 = ptr to data buffer
; D0 = A5A4A3A2A1A0 nibble A0 = ptr to user buffer (to A1 after 12)
;
;_______________________________________________________________________
; first we write some self-sync bytes, data marks, and sector number
MOVEQ #0,D5 ; zero the initial checksums
MOVEQ #0,D6 ;
MOVEQ #0,D7 ;
MOVEQ #HdrSize-2,D0 ; write 1 byte on each side of loop
MOVEA.L SonyVars,A3 ; <SM5> begin
TST.B mfmMode(A3) ; are we in ISM mode?
MOVEA.L IWM,A3
BPL.S @NotSWIM2 ; -> no, it's an IWM or SWIM
LEA rHandshake(A3),A4 ; point to handshake
LEA wData(A3),A3 ; and write data registers for speed
MOVE.B #$F5,wPhase-wData(A3) ;select another drive addr to avoid
; drive's index crosstalk problem
TST.B rError-wData(A3) ;Clear the error register
MOVE.B #$18,wZeroes-wData(A3) ;Clear the write and action bits
if NonSerializedIO then
nop ; force write to complete <SM5>
endif
MOVE.B #$10,wOnes-wData(A3) ;Set the write bit
if NonSerializedIO then
nop ; force write to complete <SM5>
endif
MOVE.B #$01,wOnes-wData(A3) ;Toggle clFIFO bit to clear out
if NonSerializedIO then
nop ; force write to complete <SM5>
endif
MOVE.B #$01,wZeroes-wData(A3) ; any data in the FIFO
if NonSerializedIO then
nop ; force write to complete <SM5>
endif
TST.B rError-wData(A3) ;Clear the error register again
move.b (A2)+,(A3) ; write first bit slip mark into FIFO
MOVE.B #$08,wOnes-wData(A3);Turn on the ACTION bit and go!
BRA.W WrHead ;
@NotSWIM2
tst.b Q6H(A3) ; first byte written is a bit wierd <A302/30oct86>
move.b (A2)+,Q7H(A3) ; write first bit slip mark <A302/30oct86>
lea Q6H(A3),A3 ; set up Q6H pointer <A302/30oct86>
; <SM5> end
WrHead MOVE.B (A2)+,D1 ; grab nibble early
@1 TST.B (A4) ; check write handshake
BPL.S @1 ;
MOVE.B D1,(A3) ; write out next header nibble
if nonSerializedIO then
nop ; force write to complete
endif
_PollSCC ; poll the SCC modem port <H4><SM5>
@2 SUBQ.W #1,D0 ;
BNE.S WrHead ; leave D0=0, ex = 0
MOVE.B (A2)+,D1 ; grab nibble early
LEA Nibl,A2 ; let A2 point to nibble table
@3 TST.B (A4) ; check write handshake
BPL.S @3 ;
MOVE.B D1,(A3) ; write out next header nibble
if nonSerializedIO then
nop ; force write to complete
endif
MOVEQ #$0B,D1 ; last header byte not yet encoded ($AD)
MOVE.B (A1)+,D2 ; get the sector number
BRA.S WrData2
WrDataSw MOVE.L A0,A1 ; switch to user buffer
WrData1
ADDX.B D2,D7 ; CSumC'' <- ByteC + CSumC' + ex
EOR.B D6,D2 ; ByteC' <- ByteC XOR CSumB'
MOVE.B D2,D3 ; D3 = [00][00][00][00][A7][A6][B7][B6]
; [C7][C7][C5][C4][C3][C2][C1][C0]
LSR.W #6,D3 ; D3 = [00][00][A7][A6][B7][B6][C7][C6]
@1 TST.B (A4) ; check write handshake
BPL.S @1 ;
MOVE.B 0(A2,D3.W),(A3) ; nibblize and write hi-bits out
if nonSerializedIO then
nop ; force write to complete
endif
SUBQ.W #3,D4 ; got 3 more bytes (wipes out ex bit!)
MOVE.B D7,D3 ; D3 <- CSumC
ADD.B D7,D3 ; ex <- CSumC[7]
ROL.B #1,D7 ; CSumC' <- ROL (CSumC)
AND.B #$3F,D0 ; D0 = [00][00][A5][A4][A3][A2][A1][A0]
@2 _PollSCC ; poll the SCC modem port <H4><SM5>
@3 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B 0(A2,D0.W),(A3) ; write low ByteA out
if nonSerializedIO then
nop ; force write to complete
endif
WrData2 MOVE.B (A1)+,D0 ; read next ByteA
ADDX.B D0,D5 ; CSumA' <- ByteA + CSumA + ex
EOR.B D7,D0 ; ByteA' <- ByteA XOR CSumC'
MOVE.B D0,D3 ; D3 = [A7][A6][A5][A4][A3][A2][A1][A0]
ROL.W #2,D3 ;
AND.B #$3F,D1 ; D1 = [00][00][B5][B4][B3][B2][B1][B0]
@1 TST.B (A4) ; check write handshake
BPL.S @1 ;
MOVE.B 0(A2,D1.W),(A3) ; nibblize and write low ByteB out
if nonSerializedIO then
nop ; force write to complete
endif
MOVE.B (A1)+,D1 ; read next ByteB
ADDX.B D1,D6 ; CSumB' <- ByteB + CSumB + ex
EOR.B D5,D1 ; ByteB' <- ByteB XOR CSumA'
MOVE.B D1,D3 ;
ROL.W #2,D3 ;
AND.B #$3F,D2 ; D2 = [00][00][C5][C4][C3][C2][C1][C0]
_PollSCC ; poll the SCC modem port <H4><SM5>
@2 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B 0(A2,D2.W),(A3) ; nibblize and write low ByteC out
if nonSerializedIO then
nop ; force write to complete
endif
MOVE.B (A1)+,D2 ; read next ByteC
TST.W D4 ; reached end of buffer?
BNE.S WrData1 ;
SWAP D4
BNE.S WrDataSw ; br if we are switching to user buffer
; the last 2 data bytes are written out separately since they are odd . . .
; the missing third byte is just zero . . .
WrLast2 CLR.B D3 ; D3 = [00][00][00][00][A7][A6][B7][B6]
; [00][00][00][00][00][00][00][00]
LSR.W #6,D3 ; D3 = [00][00][A7][A6][B7][B6][00][00]
@1 TST.B (A4) ; check write handshake
BPL.S @1 ;
MOVE.B 0(A2,D3.W),(A3) ; nibblize and write hi-bits out
if nonSerializedIO then
nop ; force write to complete
endif
MOVE.B D5,D3 ; start preparing 1st cksum byte
ROL.W #2,D3 ;
MOVE.B D6,D3 ;
ROL.W #2,D3 ;
AND.B #$3F,D0 ; D0 = [00][00][A5][A4][A3][A2][A1][A0]
@2 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B 0(A2,D0.W),(A3) ; write low ByteA out
if nonSerializedIO then
nop ; force write to complete
endif
AND.B #$3F,D1 ; D1 = [00][00][B5][B4][B3][B2][B1][B0]
_PollSCC ; poll the SCC modem port <H4><SM5>
@3 TST.B (A4) ; check write handshake
BPL.S @3 ;
MOVE.B 0(A2,D1.W),(A3) ; nibblize and write low ByteB out
if nonSerializedIO then
nop ; force write to complete
endif
; now we write out the three checksum bytes as 4 nibbles
WrCkSum MOVE.B D7,D3 ; D3 = [0][0][0][0][A7][A6][B7][B6]
; [C7][C7][C5][C4][C3][C2][C1][C0]
LSR.W #6,D3 ; D3 = [0][0][A7][A6][B7][B6][C7][C6]
@1 TST.B (A4) ; check write handshake
BPL.S @1 ;
MOVE.B 0(A2,D3.W),(A3) ; nibblize and write hi-bits out
if nonSerializedIO then
nop ; force write to complete
endif
AND.B #$3F,D5 ; zero high 2 bits
@2 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B 0(A2,D5.W),(A3) ; write CkSumA out
if nonSerializedIO then
nop ; force write to complete
endif
AND.B #$3F,D6 ; zero high 2 bits
_PollSCC ; poll the SCC modem port <H4><SM5>
@3 TST.B (A4) ; check write handshake
BPL.S @3 ;
MOVE.B 0(A2,D6.W),(A3) ; write CkSumB out
if nonSerializedIO then
nop ; force write to complete
endif
AND.B #$3F,D7 ; zero high 2 bits
@4 TST.B (A4) ; check write handshake
BPL.S @4 ;
MOVE.B 0(A2,D7.W),(A3) ; write CkSumC out
if nonSerializedIO then
nop ; force write to complete
endif
; now, finally, write the two bit slip marks and FF byte
MOVE.L SonyVars,A2 ; <SM5> begin
TST.B mfmMode(A2) ;Are we in ISM mode?
BPL.S @NotSWIM2 ; -> no, it's an IWM or SWIM
LEA @TrailMks2,A2
MOVEQ #6-1,D2 ; 2 slip bytes plus four gap bytes
@WrSlipISM MOVE.B (A4),D1 ;
BPL.S @WrSlipISM ;
MOVE.B (A2)+,(A3) ;
_PollSCC ; poll the SCC modem port <H5>
DBRA D2,@WrSlipISM ;
MOVEQ #0,D0 ; assume no underrun
BTST #5,D1 ; any errors?
BEQ.S @5 ; branch if no underrun was detected
MOVEQ #WrUnderrun,D0 ;
@5 MOVE.B #$18,wZeroes-wData(A3) ;Clear the write and action bits
BRA DskRtn ; share code (return via DskRtnAdr)
@TrailMks2 DC.B $DE,$AA,$FF,$FF,$FF,$FF ;make sure enough gap bytes are written
;to ensure that slip bytes get to disk
@NotSWIM2 ; <SM5> end
LEA TrailMks,A2 ; set up for slip bytes
MOVEQ #3,D2 ;
WrSlip MOVE.B (A4),D1
BPL.S WrSlip
MOVE.B (A2)+,(A3)
if nonSerializedIO then
nop ; force write to complete
endif
TST.B (A5) ; SCC data available?
BMI.S @1 ; br if not . . .
MOVE.B (A6),-(SP) ; push it on the stack
@1 DBRA D2,WrSlip
MOVEQ #0,D0 ; assume no underrun
BTST #6,D1 ; any errors?
BNE.S @2 ; branch if no underrun was detected
MOVEQ #WrUnderrun,D0
@2 tst.b Q7L-Q6H(A3) ; get out of write mode after half <A351/05nov86><A302/30oct86>
BRA DskRtn ; share code (return via DskRtnAdr)
TrailMks DC.B $DE,$AA,$FF,$FF
; Normal Nibblizing Table: convert 6 bits into 8-bit code word.
Nibl
DC.B $96,$97,$9A,$9B,$9D,$9E,$9F,$A6
DC.B $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3
DC.B $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC
DC.B $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3
DC.B $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE
DC.B $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC
DC.B $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6
DC.B $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF