; ; 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): ; ; 1/10/93 RC Added Nops for Smurf ; 12/14/92 RC Restore to before PDM D2 Build with Horror Roll-in ; 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. ; 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 by Steve Christensen ; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ ; 11/21/86 SWC Patched WrData to jump to its MFM counterpart if we're running ; in MFM mode. ; 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 ;_______________________________________________________________________ ; 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 TST.B mfmDisk(A1,D1) ;Are we in MFM mode? BMI mWrData ;-> yes, do the MFM version 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 ; 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 endif MOVE.B #$10,wOnes-wData(A3) ;Set the write bit if NonSerializedIO then nop ; force write to complete endif MOVE.B #$01,wOnes-wData(A3) ;Toggle clFIFO bit to clear out if NonSerializedIO then nop ; force write to complete endif MOVE.B #$01,wZeroes-wData(A3) ; any data in the FIFO if NonSerializedIO then nop ; force write to complete 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 move.b (A2)+,Q7H(A3) ; write first bit slip mark lea Q6H(A3),A3 ; set up Q6H pointer ; 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

@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

@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

@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

@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

@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 ; 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
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 ; 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 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