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.
424 lines
15 KiB
Plaintext
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
|
|
|
|
|
|
|