mac-rom/Drivers/Sony/SonyWrite.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

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