mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +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.
1418 lines
55 KiB
Plaintext
1418 lines
55 KiB
Plaintext
;
|
||
; File: SonyIOP.a
|
||
;
|
||
; Contains: 3.5" Floppy / HD-20 Disk Driver (for machines with an IOP)
|
||
;
|
||
; Written by: Gary G. Davidian 08-Sep-87
|
||
;
|
||
; Copyright: © 1987-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; This file is used in these builds: Mac32
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM6> 5/19/93 GMR Modified the icon control calls to get the info from universal
|
||
; tables, instead of the driver.
|
||
; <SM5> 12/14/92 RC Restore Pre-PDM D2 with Horror roll in
|
||
; <SM3> 12/9/92 rab Fixed a bug I introduced rolling in IOPRcvCallFromIOPPatch. Left
|
||
; out branch to @postEvent if DiskInsert was allowed.
|
||
; <SM2> 12/7/92 rab Roll in Horror changes. Comments followÉ
|
||
; <2> 4/2/91 BG Add changes to cause floppies not to work when running on an
|
||
; Eclipse and the keyswitch is set to SECURE.
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Pre-SuperMario ROM comments begin here.
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; <2> 1/21/91 SWC Checked out and in to build a BBS header (had an EASE-style
|
||
; comment header).
|
||
; <2.8> 12/11/89 GGD NEEDED FOR ZONE-5 Added support for the Disk Duplicator and the
|
||
; GetRawDataCC call for copy protection support. Mode the control
|
||
; and status dispatching tables more easily patchable. Modified
|
||
; Prime and Control to jump through existing vectors to allow for
|
||
; easier patching. Optimized a few routines for space to get all
|
||
; of this to fit in the overpatch area.
|
||
; <2.7> 11/2/89 GGD NEEDED FOR ZONE-5 Change MaxDriveNumber from 15 to 4 to be more
|
||
; compatible with the Mac IIci.
|
||
; <2.6> 7/12/89 GGD Added conditionals around the overpatch padding so that it can
|
||
; be easily located.
|
||
; <2.5> 6/23/89 GGD Removed updating of IOResult in Open call, since no pointer to
|
||
; the IOPB was around, and it was trashing a pointer in SonyVars.
|
||
; Added some padding in preparation for the F19 overpatch. Needed
|
||
; for AURORA and F19 ROMs.
|
||
; <2.4> 5/23/89 GGD Commented out duplicate equates. Modified to co-exist with
|
||
; standard Sony driver to support universal ROM. Re-named
|
||
; conflicting labels. Now uses ICON information from SonyIcon,
|
||
; instead of including them here.
|
||
; <2.3> 4/29/89 GGD No changes to this file, entire Sony Driver is checked out and
|
||
; in as a group.
|
||
; <2.2> 2/21/89 GGD Fixed assembly error, branch displacement didn't reach.
|
||
; <2.1> 2/21/89 GGD Fixed GetFormatList call to return offLinErr if disk is not in
|
||
; drive, or format has not been determined yet, to be compatible
|
||
; with non-IOP Sony Driver. Return paramErr if format list space
|
||
; is empty.
|
||
; <2.0> 2/19/89 GGD No changes except version number, to be in sync with the rest of
|
||
; the Sony Driver files.
|
||
; <1.1> 11/11/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; <1.0> 10/7/88 rwh new to EASE today
|
||
; <xxxx> 6/13/88 GGD Modified to use the new interface to the IOPMgr
|
||
; <xxxx> 9/8/87 GGD Created today.
|
||
;
|
||
;_______________________________________________________________________
|
||
;
|
||
; This module implements the 680XX side of the SONY Driver for CPUs that
|
||
; have a Input / Output Processor (IOP) (called a PIC by HW) based SWIM driver.
|
||
; It receives requests by way of the Device Manager, and translates them
|
||
; into the appropriate messages to be passed to the IOP based SWIM driver
|
||
; by way of the IOP Manager.
|
||
;_______________________________________________________________________
|
||
|
||
TITLE 'SONY Driver - 3.5" / HD-20 Disk Driver'
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
MACHINE MC68020
|
||
PRINT NOMDIR
|
||
|
||
; There is some software that depends upon things not documented in
|
||
; Inside Macintosh, so we will mark those changes that were made
|
||
; to assure compatibility with un-documented features, by using
|
||
; the following conditional assembly switch
|
||
|
||
Compatibility equ 1 ; include changes needed for compatibility
|
||
|
||
macro
|
||
assert &boolExpr
|
||
if not(&Eval(&boolExpr)) then
|
||
aerror &concat('Assertion Failed - ',&boolExpr)
|
||
endif
|
||
endm
|
||
TITLE 'SONY Driver - IOP Message Formats'
|
||
|
||
SwimMsgNumber equ 2 ; message number used for xmt and rcv msgs
|
||
|
||
; HOST -> IOP Request encodings
|
||
|
||
xmtReqInitialize equ $01 ; Initialize Driver
|
||
xmtReqShutDown equ $02 ; Shut Down driver
|
||
xmtReqStartPolling equ $03 ; Start Polling Drives
|
||
xmtReqStopPolling equ $04 ; Stop Polling Drives
|
||
xmtReqSetHFSTagAddr equ $05 ; Set HFS tag host address
|
||
xmtReqDriveStatus equ $06 ; Drive Status
|
||
xmtReqEject equ $07 ; Eject
|
||
xmtReqFormat equ $08 ; Format disk
|
||
xmtReqFormatVerify equ $09 ; Verify disk formatting
|
||
xmtReqWrite equ $0A ; Write blocks to disk
|
||
xmtReqRead equ $0B ; Read blocks from disk
|
||
xmtReqReadVerify equ $0C ; Read and compare blocks from disk
|
||
xmtReqCacheControl equ $0D ; track cache control
|
||
xmtReqTagBufferControl equ $0E ; tag buffer control
|
||
xmtReqGetIcon equ $0F ; get media or drive Icon
|
||
xmtReqDiskDupInfo equ $10 ; get Disk Duplicator information <2.8>
|
||
xmtReqGetRawData equ $11 ; Read RAW disk data (for copy protection) <2.8>
|
||
|
||
; IOP -> HOST Request encodings
|
||
|
||
rcvReqDiskInserted equ $01 ; Disk Inserted event
|
||
rcvReqDiskEjected equ $02 ; Disk Ejected event
|
||
rcvReqDiskStatusChanged equ $03 ; Disk Status Changed
|
||
|
||
|
||
; HOST <-> IOP Message Formats
|
||
|
||
SwimIopMsg record 0,increment
|
||
ReqKind ds.b 1 ; Kind of request
|
||
DriveNumber ds.b 1 ; Drive number
|
||
ErrorCode ds.w 1 ; returned error code
|
||
|
||
DriveKinds equ 4 ; head of list of existing drives kinds
|
||
|
||
org 4 ; additional parameters for some calls
|
||
AdditionalParam ds.l 1 ; control / status csParam (only first 4 bytes passed)
|
||
|
||
org 4 ; drive status parameters
|
||
DriveStatus ds.b 0 ; start of data for drive status control call
|
||
Track ds.w 1 ; current track location
|
||
WriteProtected ds.b 1 ; bit7=1=write protected
|
||
DiskInPlace ds.b 1 ; 0 = no disk place, 1 or 2 = disk in place
|
||
Installed ds.b 1 ; 0 = don't know, 1=installed, $FF=not installed
|
||
Sides ds.b 1 ; bit7=0=single sided, bit7=1=double sided
|
||
; drive queue element is not returned from IOP
|
||
TwoSidedFormat ds.b 1 ; $FF=2-sided disk, $00=1-sided disk
|
||
NewInterface ds.b 1 ; $00=old drive interface (400K), $FF=new (800K and later)
|
||
DiskErrors ds.w 1 ; disk error count
|
||
|
||
DriveInfo ds.b 0 ; start of data for drive info control call
|
||
ds.b 2 ; unused for now
|
||
DriveAttributes ds.b 1 ; disk drive attributes
|
||
DriveType ds.b 1 ; type of disk drive
|
||
|
||
ExtDriveStatus ds.b 0 ; start of data for extended drive status control call
|
||
MfmDrive ds.b 1 ; $FF=SuperDrive, otherwise zero
|
||
MfmDisk ds.b 1 ; $FF=MFM disk in drive, otherwise zero
|
||
MfmFormat ds.b 1 ; $FF=1440K, $00=720K
|
||
DiskController ds.b 1 ; $FF=SWIM, $00=IWM
|
||
|
||
CurrentFormat ds.w 1 ; bit mask of current format
|
||
FormatsAllowed ds.w 1 ; bit mask of allowable formats
|
||
|
||
FixedDiskSize ds.l 1 ; size of current drive, if fixed media drive. (HD-20)
|
||
|
||
IconFlags ds.b 1 ; bit 0 - call for Media Icon, bit 1 - call for Drive Icon
|
||
ds.b 1 ; (1 spare byte left)
|
||
|
||
org 4 ; data transfer parameters
|
||
BufferAddr ds.l 1 ; main CPU ram address
|
||
BlockNumber ds.l 1 ; disk starting block number
|
||
BlockCount ds.l 1 ; number of blocks to transfer
|
||
MfsTagData ds.b 12 ; MFS Tag Data
|
||
|
||
org 4 ; format parameters <2.8> start
|
||
FormatKind ds.w 1 ; index into list of possible formats, to select desired format
|
||
HdrFmtKind ds.b 1 ; format byte to write in sector headers (0=use default)
|
||
SectInterleave ds.b 1 ; interleave factor (0=use default)
|
||
FmtDataAddr ds.l 1 ; ptr to buffer of sector data to write while formatting (0=no buffer)
|
||
FmtTagAddr ds.l 1 ; ptr to buffer of sector tags to write while formatting (0=no buffer)
|
||
|
||
org 4 ; disk duplicator info parameters
|
||
DupVersion ds.w 1 ; disk duplicator version number
|
||
*HdrFmtKind ds.b 1 ; format byte read from last sector headers
|
||
|
||
org 4 ; disk duplicator info parameters
|
||
RawClockAddr ds.l 1 ; Buffer for packed MFM clock bits
|
||
RawDataAddr ds.l 1 ; Buffer for RAW data bytes
|
||
RawByteCount ds.l 1 ; Number of RAW bytes to read
|
||
RawSearchMode ds.w 1 ; RAW Read search mode
|
||
RawCylinder ds.w 1 ; RAW Read cylinder number
|
||
RawHead ds.b 1 ; RAW Read head number
|
||
RawSector ds.b 1 ; RAW Read sector number <2.8> end
|
||
|
||
ds.b MaxIOPMsgLen-* ; fill out the message
|
||
SwimIopMsgSize equ *
|
||
endr
|
||
TITLE 'SONY Driver - Global Data and Equates'
|
||
|
||
|
||
; Driver Control codes.
|
||
|
||
;killCode equ 1 ; KillIO code (in SysEqu.a)
|
||
;verifyCC equ 5 ; 'verify' control code
|
||
;formatCC equ 6 ; 'format' control code
|
||
;ejectCode equ 7 ; control call eject code (in SysEqu.a)
|
||
;tgBuffCode equ 8 ; set tag buffer code (in SysEqu.a)
|
||
;TCacheCC equ 9 ; 'track cache' control
|
||
;iconCC equ 21 ; 'get icon' control code
|
||
;iconLogCC equ 22 ; 'get logical icon' code
|
||
;infoCC equ 23 ; 'get drive info' code
|
||
;FmtCopyCC equ $5343 ; one-pass format/copy/verify for disk duplicator <2.8>
|
||
;GetRawDataCC equ 18244 ; 'get raw track data' code <2.8>
|
||
|
||
TotalControlCalls equ 11 ; 11 currently defined
|
||
MaxControlCalls equ TotalControlCalls+4 ; allow 4 extra for expansion
|
||
|
||
|
||
; Driver Status codes.
|
||
|
||
;FmtLstCode equ 6 ; Returns a list of disk formats
|
||
;drvStsCode equ 8 ; status code for drive status (in SysEqu.a)
|
||
;MFMStsCode equ 10 ; 'Get MFM status' status code
|
||
;DupVerSts equ $4456 ;disk duplicator version supported (to match features) <2.8>
|
||
;FmtByteSts equ $5343 ;return address header format byte <2.8>
|
||
|
||
TotalStatusCalls equ 5 ; 5 currently defined
|
||
MaxStatusCalls equ TotalStatusCalls+4 ; allow 4 extra for expansion
|
||
|
||
|
||
; Driver Reference Numbers
|
||
|
||
SonyRefNum equ SonyRfN ; driver refnum for floppy disk drives
|
||
HD20RefNum equ DCDRfN ; driver refnum for HD-20 disk drives
|
||
|
||
|
||
; Disk Drive Kinds
|
||
|
||
noDriveKind equ 0 ; no drive connected
|
||
unknownDriveKind equ 1 ; unspecified drive kind
|
||
SSGCRDriveKind equ 2 ; single sided 400K GCR disk drive
|
||
DSGCRDriveKind equ 3 ; double sided 400K/800K GCR disk drive
|
||
DSMFMGCRDriveKind equ 4 ; double sided 400K/800K GCR, 720K, 1440K MFM disk drive
|
||
HD20DriveKind equ 7 ; HD20 20MB hard disk
|
||
|
||
RemovableDrives equ (1<<SSGCRDriveKind)+\
|
||
(1<<DSGCRDriveKind)+\
|
||
(1<<DSMFMGCRDriveKind)+\
|
||
(1<<5)+\ ; for possible future expansion
|
||
(1<<6)+\ ; for possible future expansion
|
||
(1<<8)+\ ; for possible future expansion
|
||
(1<<9)+\ ; for possible future expansion
|
||
(1<<10)+\ ; for possible future expansion
|
||
(1<<11) ; for possible future expansion
|
||
FixedDrives equ (1<<HD20DriveKind)+\
|
||
(1<<12)+\ ; for possible future expansion
|
||
(1<<13)+\ ; for possible future expansion
|
||
(1<<14)+\ ; for possible future expansion
|
||
(1<<15) ; for possible future expansion
|
||
MissingDrives equ $FFFF-RemovableDrives-FixedDrives
|
||
|
||
; Storage Allocation
|
||
|
||
if Compatibility then
|
||
; The BLESSER calls the sony driver for drive status using a drive num that might not be
|
||
; a sony drive number (like 8, which it got from the file system from the first SCSI drive)
|
||
; The Mac IIci return an error for drives above 4 (2 floppy, 2 DCD). The BLESSER is in error
|
||
; by calling the wrong driver, and also because it doesn't check the drive installed field
|
||
; in the status that is returned. In any case, this is being change to match the Mac IIci
|
||
; exactly, in cause it might cause other compatibility problems.
|
||
MaxDriveNumber equ 4 ; support logical drive numbers in range 0..4 <2.7>
|
||
else
|
||
MaxDriveNumber equ 15 ; support logical drive numbers in range 0..15
|
||
endif
|
||
MaxDrives equ 6 ; support up to 6 physical disk drives
|
||
|
||
DriverVars record 0,decrement ; global variables used by driver
|
||
DCEpointer ds.l 1 ; pointer to device control entry
|
||
MediaIconPtr ds.l 1 ; pointer to Media Icon <2.4>
|
||
Drive1PhysIcon ds.l 1 ; pointer to Physical Drive Icon for drive 1 <2.4>
|
||
Drive2PhysIcon ds.l 1 ; pointer to Physical Drive Icon for drive 2 <2.4>
|
||
xmtReq ds IOPRequestInfo ; parameter block for CPU to IOP requests
|
||
xmtMsg ds SwimIopMsg ; copy of CPU to IOP message
|
||
xmtWaiterPC ds.l 1 ; PC of xmt msg completion routine
|
||
rcvReq ds IOPRequestInfo ; parameter block for IOP to CPU requests
|
||
rcvMsg ds SwimIopMsg ; copy of IOP to CPU message
|
||
|
||
ds.b MaxControlCalls*8
|
||
ds.w 1 ; default error if not found (ControlErr)
|
||
ds.w 1 ; number of Control Calls defined - 1 <2.8>
|
||
ControlCallInfo ds.l 1 ; pointer to control call dispatching table <2.8>
|
||
|
||
ds.b MaxStatusCalls*8
|
||
ds.w 1 ; default error if not found (StatusErr)
|
||
ds.w 1 ; number of Status Calls defined - 1 <2.8>
|
||
StatusCallInfo ds.l 1 ; pointer to status call dispatching table <2.8>
|
||
|
||
IconBufferSize equ ((32*32)/8)*2+32 ; room for Icon data, mask, and name string
|
||
IconBuffer ds.b IconBufferSize
|
||
|
||
ErrorCodeSave ds.w 1 ; temp storeage for error code in Prime
|
||
DriverVarsSize equ 0-* ; size of global variables used by driver
|
||
endr
|
||
|
||
PerDriveInfo record 0,increment ; drive specific variables
|
||
WriteProtected ds.b 1 ; bit7=1=write protected
|
||
DiskInPlace ds.b 1 ; 0 = no disk place, 1 or 2 = disk in place
|
||
Installed ds.b 1 ; 0 = don't know, 1=installed, $FF=not installed
|
||
Sides ds.b 1 ; bit7=0=single sided, bit7=1=double sided
|
||
DriveQElement ds.b dQDrvSz2+2
|
||
PerDriveInfoSize equ * ; size of drive specific variables
|
||
endr
|
||
|
||
DriveInfos record 0,increment ; drive specific variables for all drives
|
||
DriveInfoPtrs ds.l MaxDriveNumber+1 ; 0 based list of pointers to PerDriveInfo
|
||
FirstDriveInfo ds.b MaxDrives*PerDriveInfo.PerDriveInfoSize
|
||
DriveInfosSize equ * ; size of all drive specific variables
|
||
endr
|
||
|
||
with DriverVars,DriveInfos
|
||
TITLE 'SONY Driver - Open processing'
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: IopDiskOpen
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to Device Control Entry (DCE)
|
||
; Outputs: D0 - Result Code (noErr/openErr)
|
||
; Destroys:
|
||
; Calls: none
|
||
; Called by: Device Manager
|
||
;
|
||
; Function: Driver initialization routine
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
IopDiskOpen ; all regs saved by Device Manager
|
||
move.l #DriverVarsSize+DriveInfosSize,d0
|
||
_NewPtr ,SYS,CLEAR ; allocate memory for globals
|
||
adda.w #DriverVarsSize,a0 ; DriverVars are negative to the pointer
|
||
move.l a0,SonyVars ; and keep pointer in low memory
|
||
move.l a1,DCEpointer(a0) ; save a copy of the DCE pointer
|
||
move.b #Version,DCtlQueue+1(a1) ; put our version number in
|
||
movea.l a0,a1 ; a1 <- SonyVars
|
||
|
||
; Initialize the ICON pointers
|
||
|
||
move.l UnivInfoPtr,a2 ; <SM6>
|
||
adda.l ProductInfo.IconInfoPtr(a2),a2 ; point to icon info table for this machine <SM6>
|
||
move.l 0(a2),d0 ; offset to media icon <2.4>
|
||
bsr.s @getIconPtr ; get the icon pointer <2.4>
|
||
move.l a3,MediaIconPtr(a1) ; save it <2.4>
|
||
move.l 4(a2),d0 ; offset to primary drive icon <2.4>
|
||
bsr.s @getIconPtr ; get the icon pointer <2.4>
|
||
move.l a3,Drive1PhysIcon(a1) ; save it <2.4>
|
||
move.l 14(a2),d0 ; offset to secondary drive icon <2.4>
|
||
bsr.s @getIconPtr ; get the icon pointer <2.4>
|
||
move.l a3,Drive2PhysIcon(a1) ; save it <2.4>
|
||
bra.s @IconsDone ; done with ICON stuff <2.4>
|
||
|
||
@getIconPtr ; <2.4>
|
||
lea (a2,d0.l),a3 ; assume relative to table <2.4>
|
||
bclr.l #0,d0 ; test & clear 'use ROM table' bit <2.4>
|
||
beq.s @IconPtrOK ; branch if should use current table <2.4>
|
||
move.l UnivInfoPtr,a3 ; <SM6>
|
||
adda.l ProductInfo.IconInfoPtr(a3),a3 ; point to icon info table in ROM <SM6>
|
||
adda.l d0,a3 ; add in relative offset <2.4>
|
||
@IconPtrOK rts ; ptr to icon is in a3 now <2.4>
|
||
|
||
@IconsDone ; <2.4>
|
||
|
||
; Initialize the IOPMsgInfo parameter block for rcv messages
|
||
|
||
with IOPRequestInfo
|
||
lea rcvReq.irIOPNumber(a1),a0 ; point into the param block
|
||
assert irRequestKind=(irIOPNumber+1)
|
||
move.w #(SwimIopNum<<8)+\ ; irIOPNumber := SwimIopNum
|
||
(irWaitRcvMessage<<0),(a0)+ ; irRequestKind := irWaitRcvMessage
|
||
assert irMsgNumber=(irRequestKind+1)
|
||
assert irMessageLen=(irMsgNumber+1)
|
||
assert irReplyLen=(irMessageLen+1)
|
||
assert irReqActive=(irReplyLen+1)
|
||
move.l #(SwimMsgNumber<<24)+\ ; irMsgNumber := SwimMsgNumber
|
||
(SwimIopMsg.SwimIopMsgSize<<16)+\ ; irMessageLen := SwimIopMsgSize
|
||
(SwimIopMsg.SwimIopMsgSize<<8)+\ ; irReplyLen := SwimIopMsgSize
|
||
(0<<0),(a0)+ ; irReqActive := 0
|
||
lea rcvMsg(a1),a2 ; message and reply buffer
|
||
assert irMessagePtr=(irReqActive+1)
|
||
move.l a2,(a0)+ ; irMessagePtr := rcvMsg
|
||
assert irReplyPtr=(irMessagePtr+4)
|
||
move.l a2,(a0)+ ; irReplyPtr := rcvMsg
|
||
lea ReceivedCallFromIop,a2 ; handler for rcv msg arrival
|
||
assert irHandler=(irReplyPtr+4)
|
||
move.l a2,(a0)+ ; irHandler := ReceivedCallFromIop
|
||
lea rcvReq(a1),a0 ; prepare to issue the request
|
||
_IOPMsgRequest ; wait for receive messages
|
||
bne.w @ErrorReturn ; in case IOP didn't initialize
|
||
endwith
|
||
|
||
; Initialize the IOPMsgInfo parameter block for xmt messages
|
||
|
||
with IOPRequestInfo
|
||
lea xmtReq.irIOPNumber(a1),a0 ; point into the param block
|
||
assert irRequestKind=(irIOPNumber+1)
|
||
move.w #(SwimIopNum<<8)+\ ; irIOPNumber := SwimIopNum
|
||
(irSendXmtMessage<<0),(a0)+ ; irRequestKind := irSendXmtMessage
|
||
assert irMsgNumber=(irRequestKind+1)
|
||
assert irMessageLen=(irMsgNumber+1)
|
||
assert irReplyLen=(irMessageLen+1)
|
||
assert irReqActive=(irReplyLen+1)
|
||
move.l #(SwimMsgNumber<<24)+\ ; irMsgNumber := SwimMsgNumber
|
||
(SwimIopMsg.SwimIopMsgSize<<16)+\ ; irMessageLen := SwimIopMsgSize
|
||
(SwimIopMsg.SwimIopMsgSize<<8)+\ ; irReplyLen := SwimIopMsgSize
|
||
(0<<0),(a0)+ ; irReqActive := 0
|
||
lea xmtMsg(a1),a2 ; message and reply buffer
|
||
assert irMessagePtr=(irReqActive+1)
|
||
move.l a2,(a0)+ ; irMessagePtr := xmtMsg
|
||
assert irReplyPtr=(irMessagePtr+4)
|
||
move.l a2,(a0)+ ; irReplyPtr := xmtMsg
|
||
lea IOPCallReturned,a2 ; handler for xmt msg completion
|
||
assert irHandler=(irReplyPtr+4)
|
||
move.l a2,(a0)+ ; irHandler := IOPCallReturned
|
||
endwith
|
||
|
||
move.b #xmtReqInitialize,XmtMsg.ReqKind(a1) ; setup init request
|
||
bsr.w @CallIOPsync ; initialize the IOP SWIM driver
|
||
|
||
; Install the vectors for Prime and Control <2.8>
|
||
|
||
lea jtIopDiskPrime,a2 ; get the routine address <2.8>
|
||
move.l a2,JDiskPrime ; install the vector <2.8>
|
||
lea jtIopDiskControl,a2 ; get the routine address <2.8>
|
||
move.l a2,JControl ; install the vector <2.8>
|
||
|
||
; initialize the Control and Status Call Info tables
|
||
|
||
lea ControlCallInfo+4(a1),a2; a2 <- address of table in globals <2.8>
|
||
lea ControlDecode,a3 ; a3 <- address of table in ROM
|
||
moveq.l #controlErr,d0 ; d0 <- default error code
|
||
moveq.l #TotalControlCalls-1,d1 ; d1 <- loop counter
|
||
bsr.w @InstallCallInfo ; install the ControlCallInfo
|
||
|
||
lea StatusCallInfo+4(a1),a2 ; a2 <- address of table in globals <2.8>
|
||
lea StatusDecode,a3 ; a3 <- address of table in ROM
|
||
moveq.l #statusErr,d0 ; d0 <- default error code
|
||
moveq.l #TotalStatusCalls-1,d1 ; d1 <- loop counter
|
||
bsr.s @InstallCallInfo ; install the StatusCallInfo
|
||
|
||
; assign drive numbers, and add drive queue elements to the drive queue
|
||
|
||
with PerDriveInfo
|
||
lea FirstDriveInfo(a1),a2 ; a2 <- pointer to PerDriveInfo for drive
|
||
lea DriveInfoPtrs(a1),a3 ; a3 <- pointer to DriveInfoPtrs list entry
|
||
lea xmtMsg.DriveKinds(a1),a4; a4 <- pointer to returned drive kinds
|
||
moveq.l #0,d1 ; d1 <- logical drive number/loop counter
|
||
moveq.l #MaxDrives,d2 ; d2 <- physical drives available to allocate
|
||
moveq.l #MissingDrives,d3 ; d3 <- bit mask of missing drive types
|
||
move.w #RemovableDrives,d4 ; d4 <- bit mask of removable drive types
|
||
|
||
@AddDriveLoop
|
||
move.b (a4)+,d5 ; d5 <- the drive kind
|
||
btst.l d5,d3 ; check for missing drive
|
||
bne.s @AddDriveNext ; if missing drive, skip install
|
||
|
||
move.l a2,(a3) ; install pointer to per drive info
|
||
move.b #1,Installed(a2) ; indicate that drive is installed
|
||
moveq.l #SonyRefNum,d0 ; d0 <- driver RefNum in low 16 bits
|
||
btst.l d5,d4 ; check for removable drive kind
|
||
bne.s @AddTheDrive ; if removable drive, ready to install
|
||
|
||
moveq.l #HD20RefNum,d0 ; d0 <- driver RefNum in low 16 bits
|
||
move.w #1,DriveQElement+qType(a2) ; fixed drives have extended drive sizes
|
||
movea.l UTableBase,a0
|
||
move.l (-1-SonyRefNum)*4(a0),\
|
||
(-1-HD20RefNum)*4(a0) ; use a different RefNum for Fixed Drives
|
||
|
||
@AddTheDrive
|
||
swap d0 ; prepare to insert drive number
|
||
move.w d1,d0 ; setup logical drive number for _AddDrive
|
||
swap d0 ; d0 <- drive number in high 16 bits
|
||
lea DriveQElement(a2),a0 ; a0 <- pointer to Drive Queue Element
|
||
_AddDrive ; add the drive to the drive queue
|
||
adda.w #PerDriveInfoSize,a2 ; point to next PerDriveInfo
|
||
@AddDriveNext
|
||
addq.l #4,a3 ; point to next DriveInfoPtr
|
||
addq.w #1,d1 ; increment logical drive number
|
||
cmpi.w #MaxDriveNumber,d1 ; check for all drives done
|
||
bls.s @AddDriveLoop ; loop through all logical drive numbers
|
||
@AddDriveExit
|
||
endwith
|
||
|
||
move.b #xmtReqSetHFSTagAddr,\
|
||
xmtMsg.ReqKind(a1) ; setup HFS Tag buffer address
|
||
move.l #HFSTagData,xmtMsg.BufferAddr(a1) ; pass the address
|
||
bsr.s @CallIOPsync ; tell the IOP the address of HFSTagData
|
||
|
||
move.b #xmtReqStartPolling,\
|
||
xmtMsg.ReqKind(a1) ; setup StartPolling request
|
||
bsr.s @CallIOPsync ; tell the IOP to start polling the drives
|
||
|
||
moveq.l #noErr,d0 ; return No Error status
|
||
@ErrorReturn
|
||
rts ; all done
|
||
|
||
|
||
@InstallCallInfo
|
||
move.l a2,-4(a2) ; save the pointer to the table (for patching) <2.8>
|
||
move.w d1,(a2)+ ; install the loop counter
|
||
move.w d0,(a2)+ ; install the default error code
|
||
@CallInfoLoop
|
||
move.l (a3)+,(a2)+ ; install csCode, IOProutine, Flags
|
||
lea SonyHeader,a4 ; get driver base address
|
||
adda.w (a3)+,a4 ; convert relative addr to absolute
|
||
move.l a4,(a2)+ ; install routine address
|
||
dbra d1,@CallInfoLoop ; process the whole table
|
||
rts ; all done
|
||
|
||
|
||
; the OPEN call must run synchronously, so we must loop waiting for the IOP call to complete
|
||
@CallIOPsync
|
||
pea @waitLoop ; return into wait loop after sending msg
|
||
bsr.w CallIOPRoutine ; send the request to the IOP
|
||
rts ; null waiter routine
|
||
@waitLoop tst.l xmtWaiterPC(a1) ; see if still waiting
|
||
bne.s @waitLoop ; wait until waiter runs
|
||
rts
|
||
TITLE 'SONY Driver - Close processing'
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: IopDiskClose
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to Device Control Entry (DCE)
|
||
; Outputs: D0 - Result Code (closErr)
|
||
; Destroys:
|
||
; Calls: none
|
||
; Called by: Device Manager
|
||
;
|
||
; Function: Driver shutdown routine
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
IopDiskClose ; all regs saved by Device Manager
|
||
moveq.l #closErr,d0 ; return Close Error status
|
||
rts ; not closable at present
|
||
TITLE 'SONY Driver - Read / Write processing'
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: IopDiskPrime
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to Device Control Entry (DCE)
|
||
; Outputs: D0 - Result Code
|
||
; Destroys:
|
||
; Calls: IODone
|
||
; Called by: Device Manager
|
||
;
|
||
; Function: Driver Read/Write routines
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
IopDiskPrime ; all regs saved by Device Manager
|
||
move.l JDiskPrime,-(sp) ; <2.8>
|
||
rts ; <2.8>
|
||
jtIopDiskPrime ; <2.8>
|
||
movea.l a1,a2 ; a2 <- pointer to DCE
|
||
movea.l SonyVars,a1 ; a1 <- pointer to globals
|
||
lea xmtMsg(a1),a3 ; a3 <- pointer fields in xmtMsg
|
||
|
||
bsr.w CheckIfSecure ; ¥ test for keyswitch SECUREd <SM2>
|
||
bne.s @1 ; ¥ IF SECURE THEN <T13><SM2>
|
||
moveq #ioErr,d0 ; ¥ fail with an *ioErr* <SM2>
|
||
bra DiskIODone ; ¥ ENDIF <SM2>
|
||
|
||
@1 moveq.l #xmtReqWrite,d0 ; assume write request
|
||
cmpi.b #aRdCmd,ioTrap+1(a0) ; check for read
|
||
bne.s @gotReqKind ; if not read, must be a write
|
||
moveq.l #xmtReqRead,d0 ; must be read request
|
||
btst.b #6,IOPosMode+1(a0) ; test for verify mode
|
||
beq.s @gotReqKind ; if just plain read, no verify
|
||
moveq.l #xmtReqReadVerify,d0 ; read with verify request
|
||
@gotReqKind
|
||
assert SwimIopMsg.ReqKind=0
|
||
move.b d0,(a3)+ ; setup IOP request Kind
|
||
|
||
moveq.l #NSDrvErr,d0 ; assume Bad drive number
|
||
move.w IODrvNum(a0),d1 ; get the drive number
|
||
cmpi.w #MaxDriveNumber,d1 ; see if way out of range
|
||
bhi.w @PrimeError ; if invalid drive number
|
||
assert SwimIopMsg.DriveNumber=SwimIopMsg.ReqKind+1
|
||
move.b d1,(a3)+ ; setup IOP request Drive Number
|
||
|
||
assert SwimIopMsg.ErrorCode=SwimIopMsg.DriveNumber+1
|
||
clr.w (a3)+ ; clear error code
|
||
|
||
assert SwimIopMsg.BufferAddr=SwimIopMsg.ErrorCode+2
|
||
move.l ioBuffer(a0),(a3)+ ; setup buffer address
|
||
|
||
moveq.l #ParamErr,d0 ; assume parameter error
|
||
moveq.l #9,d1 ; shift amount for divide by 512
|
||
|
||
move.l dCtlPosition(a2),d2 ; get byte position
|
||
ror.l d1,d2 ; convert to block number
|
||
assert SwimIopMsg.BlockNumber=SwimIopMsg.BufferAddr+4
|
||
move.l d2,(a3)+ ; setup block number
|
||
rol.l d1,d2 ; convert back to byte position
|
||
andi.w #$01FF,d2 ; test for mod 512
|
||
bne.s @PrimeError ; if error in dCtlPosition parameter
|
||
|
||
move.l ioByteCount(a0),d2 ; get byte count
|
||
ror.l d1,d2 ; convert to block count
|
||
assert SwimIopMsg.BlockCount=SwimIopMsg.BlockNumber+4
|
||
move.l d2,(a3)+ ; setup block count
|
||
rol.l d1,d2 ; convert back to byte count
|
||
andi.w #$01FF,d2 ; test for mod 512
|
||
bne.s @PrimeError ; if error in byte count parameter
|
||
|
||
assert SwimIopMsg.MfsTagData=SwimIopMsg.BlockCount+4
|
||
lea TagData+2,a2 ; point to tag data
|
||
move.l (a2)+,(a3)+ ; copy 12 bytes of MFS Tag data
|
||
move.l (a2)+,(a3)+
|
||
move.l (a2)+,(a3)+
|
||
|
||
bsr.w CallIOPRoutine ; call the IOP routine
|
||
|
||
lea xmtMsg.MfsTagData(a1),a0 ; point to returned tag data
|
||
lea TagData+2,a2 ; point to tag data
|
||
move.l (a0)+,(a2)+ ; copy 12 bytes of MFS Tag data
|
||
move.l (a0)+,(a2)+
|
||
move.l (a0)+,(a2)+
|
||
|
||
; if the disk has not been accessed before now, update the status to
|
||
; correctly reflect disk format, etc.
|
||
|
||
clr.l d1 ; zero extend the drive number
|
||
move.b xmtMsg.DriveNumber(a1),d1 ; get the drive number
|
||
move.l DriveInfoPtrs(a1,d1.w*4),d2 ; get drive info pointer
|
||
beq.s @StatusOK ; if no drive info for this drive
|
||
|
||
movea.l d2,a3 ; a3 <- real per drive info
|
||
cmpi.b #2,PerDriveInfo.DiskInPlace(a3) ; check for HasBeenAccessed
|
||
beq.s @StatusOK ; if status valid (has been accessed)
|
||
|
||
move.w xmtMsg.ErrorCode(a1),ErrorCodeSave(a1) ; save read error code
|
||
|
||
move.b #xmtReqDriveStatus,xmtMsg.ReqKind(a1) ; request Drive status
|
||
bsr.w CallIOPRoutine ; call the IOP for Drive Status
|
||
bsr.w UpdateXmtDriveStatus ; update the drive status
|
||
|
||
move.w ErrorCodeSave(a1),xmtMsg.ErrorCode(a1) ; restore read error code
|
||
|
||
@StatusOK move.w xmtMsg.ErrorCode(a1),d0 ; get returned error code
|
||
bne.s @PrimeError ; if I/O error
|
||
|
||
movea.l DCEPointer(a1),a2 ; get DCE pointer
|
||
movea.l DCtlQHead(a2),a0 ; get IO param block pointer
|
||
move.l ioByteCount(a0),d1 ; get byte count
|
||
move.l d1,ioNumDone(a0) ; all byte done
|
||
add.l d1,dCtlPosition(a2) ; update position pointer
|
||
|
||
@PrimeError bra.w DiskIODone ; return through IODone
|
||
TITLE 'SONY Driver - Decode table for Status Calls'
|
||
|
||
; Flags used in decode tables
|
||
|
||
CheckDriveNum equ 7
|
||
CheckDriveExists equ 6
|
||
MakeIOPcall equ 5
|
||
|
||
|
||
; Decode table for Status Calls (gets copied into RAM for patching)
|
||
|
||
StatusDecode dc.w FmtLstCode ; Get Format List status call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopGetFormatList-SonyHeader
|
||
|
||
dc.w drvStsCode ; Drive Status call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopDriveStatus-SonyHeader
|
||
|
||
dc.w MFMStsCode ; MFM Status call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopMFMStatus-SonyHeader
|
||
|
||
dc.w DupVerSts ; duplicator version status call <2.8>
|
||
dc.b xmtReqDiskDupInfo
|
||
dc.b (0<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopDupVersion-SonyHeader
|
||
|
||
dc.w FmtByteSts ; get format byte status call <2.8>
|
||
dc.b xmtReqDiskDupInfo
|
||
dc.b (0<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopGetFmtByte-SonyHeader
|
||
|
||
assert (*-StatusDecode)=(TotalStatusCalls*6)
|
||
TITLE 'SONY Driver - Decode table for Control Calls'
|
||
|
||
; Decode table for Control Calls (gets copied into RAM for patching)
|
||
|
||
ControlDecode dc.w killCode ; KillIO control call
|
||
dc.b 0 ; no IOP routine
|
||
dc.b (0<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(0<<MakeIOPcall)
|
||
dc.w IopCtlKillIO-SonyHeader
|
||
|
||
dc.w VerifyCC ; Verify control call
|
||
dc.b xmtReqFormatVerify
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlVerify-SonyHeader
|
||
|
||
dc.w FormatCC ; Format control call
|
||
dc.b xmtReqFormat
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(0<<MakeIOPcall) ; <2.8>
|
||
dc.w IopCtlFormat-SonyHeader
|
||
|
||
dc.w EjectCode ; Eject control call
|
||
dc.b xmtReqEject
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlEject-SonyHeader
|
||
|
||
dc.w tgBuffCode ; Set Tag Buffer control call
|
||
dc.b xmtReqTagBufferControl
|
||
dc.b (0<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlTagBuf-SonyHeader
|
||
|
||
dc.w TCacheCC ; Track Cache control call
|
||
dc.b xmtReqCacheControl
|
||
dc.b (0<<CheckDriveNum)+\
|
||
(0<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlTrkCache-SonyHeader
|
||
|
||
dc.w IconCC ; Physical Drive Icon control call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlPhysIcon-SonyHeader
|
||
|
||
dc.w IconLogCC ; Disk Media Icon control call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlLogIcon-SonyHeader
|
||
|
||
dc.w InfoCC ; Get Drive Info control call
|
||
dc.b xmtReqDriveStatus
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(1<<MakeIOPcall)
|
||
dc.w IopCtlDrvInfo-SonyHeader
|
||
|
||
dc.w FmtCopyCC ; Format and copy control call <2.8>
|
||
dc.b xmtReqFormat
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(0<<MakeIOPcall)
|
||
dc.w IopCtlFmtCopy-SonyHeader
|
||
|
||
dc.w GetRawDataCC ; Format and copy control call <2.8>
|
||
dc.b xmtReqGetRawData
|
||
dc.b (1<<CheckDriveNum)+\
|
||
(1<<CheckDriveExists)+\
|
||
(0<<MakeIOPcall)
|
||
dc.w IopCtlGetRawData-SonyHeader
|
||
|
||
assert (*-ControlDecode)=(TotalControlCalls*6)
|
||
TITLE 'SONY Driver - Control / Status processing'
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: IopDiskControl / IopDiskStatus
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to Device Control Entry (DCE)
|
||
; Outputs: D0 - Result Code
|
||
; Destroys:
|
||
; Calls: IODone
|
||
; Called by: Device Manager
|
||
;
|
||
; Function: Driver Control routines
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
IopDiskControl ; all regs saved by Device Manager
|
||
move.l JControl,-(sp) ; <2.8>
|
||
rts ; <2.8>
|
||
jtIopDiskControl ; <2.8>
|
||
movea.w #ControlCallInfo,a2 ; offset of decode table
|
||
bra.s HandleControlStatus ; join common code
|
||
|
||
|
||
IopDiskStatus ; all regs saved by Device Manager
|
||
movea.w #StatusCallInfo,a2 ; offset of decode table
|
||
* bra.s HandleControlStatus ; join common code (fall into it)
|
||
|
||
HandleControlStatus
|
||
movea.l SonyVars,a1 ; get pointer to globals <SM2>
|
||
|
||
cmpi.w #EjectCode,csCode(a0) ; ¥ check for Eject requests <SM2>
|
||
beq.s @OkToDoIt ; ¥ allow eject calls always <SM2>
|
||
bsr.w CheckIfSecure ; ¥ are we SECUREd? <SM2>
|
||
bne.s @OkToDoIt ; ¥ IF SECURED THEN <T13><SM2>
|
||
moveq #ioErr,d0 ; ¥ fail with an *ioErr* <SM2>
|
||
bra DiskIODone ; ¥ exit to error exit <SM2>
|
||
@OkToDoIt ; ELSE <SM2>
|
||
movea.l (a1,a2.l),a2 ; get pointer to table <SM2>
|
||
move.w (a2)+,d1 ; d1 <- loop counter <SM2>
|
||
move.w (a2)+,d0 ; d0 <- default error code <SM2>
|
||
move.w csCode(a0),d2 ; d2 <- csCode to search for <SM2>
|
||
@SearchLoop cmp.w (a2),d2 ; check for a match
|
||
addq.l #8,a2 ; point to next table entry
|
||
dbeq d1,@SearchLoop ; search through all table entries
|
||
bne.s DiskIODone ; illegal csCode, return with error
|
||
moveq.l #NoErr,d0 ; default to no error
|
||
movea.l -(a2),a3 ; get address of routine
|
||
move.w IODrvNum(a0),d1 ; get the drive number
|
||
move.b -(a2),d2 ; get flags
|
||
assert CheckDriveNum=7 ; flag is in sign bit
|
||
bpl.s @DriveNumInRange ; if flag to check drive num is not set
|
||
cmpi.w #MaxDriveNumber,d1 ; see if way out of range
|
||
bls.s @DriveNumInRange ; if valid drive number
|
||
moveq.l #NSDrvErr,d0 ; Bad drive number
|
||
bra.s DiskIODone ; drive num out of range, return with error
|
||
@DriveNumInRange
|
||
assert CheckDriveExists=CheckDriveNum-1 ; next flag is CheckDriveExists
|
||
add.b d2,d2 ; test next flag
|
||
bpl.s @DriveExists ; if flag to check drive exists is not set
|
||
tst.l DriveInfoPtrs(a1,d1.w*4); test to see if it exists
|
||
bne.s @DriveExists ; if valid drive
|
||
moveq.l #NoDriveErr,d0 ; non-existent drive error
|
||
bra.s DiskIODone ; drive doesn't exists, return with error
|
||
@DriveExists
|
||
move.b d1,xmtMsg.DriveNumber(a1); setup IOP request Drive Number
|
||
move.b -(a2),xmtMsg.ReqKind(a1); setup IOP request Kind
|
||
move.l csParam(a0),xmtMsg.AdditionalParam(a1)
|
||
assert MakeIOPcall=CheckDriveExists-1 ; next flag is MakeIOPcall
|
||
add.b d2,d2 ; test next flag
|
||
bpl.s @DontCallIOP ; if call to IOP not needed
|
||
move.l a3,-(sp) ; when IOP call returns, jump into the routine
|
||
bra.w CallIOPRoutine ; call the IOP routine
|
||
|
||
@DontCallIOP
|
||
jmp (a3) ; jump into the routine
|
||
|
||
|
||
DiskIODone move.l JIODone,-(sp) ; prepare to return to IODone
|
||
movea.l DCEPointer(a1),a1 ; a1 <- DCE (param to IODone)
|
||
ext.l d0 ; check for errors
|
||
beq.s @noError ; if no error
|
||
move.w d0,DskErr ; save error in low memory global DskErr
|
||
@noError rts ; return to IODone
|
||
eject
|
||
|
||
|
||
IopCtlKillIO
|
||
moveq.l #controlErr,d0 ; we don't support KillIO
|
||
bra.s DiskIODone ; return with error
|
||
|
||
|
||
IopCtlFormat
|
||
lea xmtMsg.HdrFmtKind(a1),a2; pointer to message for copying <2.8>
|
||
assert xmtMsg.SectInterleave=xmtMsg.HdrFmtKind+1 ; <2.8>
|
||
clr.w (a2)+ ; use default hdr format byte and interleave <2.8>
|
||
assert xmtMsg.FmtDataAddr=xmtMsg.SectInterleave+1 ; <2.8>
|
||
clr.l (a2)+ ; no sector data supplied <2.8>
|
||
assert xmtMsg.FmtTagAddr=xmtMsg.FmtDataAddr+4 ; <2.8>
|
||
clr.l (a2)+ ; no sector tags supplied <2.8>
|
||
bsr.w CallIOPRoutine ; format the disk <2.8>
|
||
IopCtlEject
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info
|
||
IopCtlVerify
|
||
IopCtlTagBuf
|
||
IopCtlTrkCache
|
||
IopCtlDone ; <2.8>
|
||
move.w xmtMsg.ErrorCode(a1),d0 ; get the returned error code (or noErr)
|
||
bra.s DiskIODone ; return through IODone
|
||
|
||
|
||
IopCtlPhysIcon
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info
|
||
movea.l Drive1PhysIcon(a1),a3 ; return primary drive Icon
|
||
btst.b #3,xmtMsg.DriveAttributes(a1) ; test for secondary
|
||
beq.s @gotDefault ; if it was primary
|
||
movea.l Drive2PhysIcon(a1),a3 ; return secondary drive Icon
|
||
@gotDefault move.w #1,xmtMsg.BlockNumber(a1) ; request drive icon info
|
||
btst.b #1,xmtMsg.IconFlags(a1) ; see if needs call for drive Icon
|
||
bra.s IconCommon ; join common code
|
||
|
||
|
||
IopCtlLogIcon
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info
|
||
movea.l MediaIconPtr(a1),a3 ; return media Icon
|
||
clr.w xmtMsg.BlockNumber(a1) ; request media icon info
|
||
btst.b #0,xmtMsg.IconFlags(a1) ; see if needs call for media Icon
|
||
IconCommon bne.s @callForIcon ; if not valid, ask IOP for the Icon
|
||
move.l a3,(a0) ; return pointer to Icon
|
||
bra.s DiskIODone ; return
|
||
|
||
@callForIcon
|
||
lea IconBuffer(a1),a3 ; get pointer to IconData
|
||
move.l a3,(a0) ; return pointer to Icon
|
||
move.l a3,xmtMsg.BufferAddr(a1); pass Icon buffer address
|
||
move.w #IconBufferSize,xmtMsg.BlockCount(a1) ; pass max size
|
||
move.b #xmtReqGetIcon,xmtMsg.ReqKind(a1)
|
||
bsr.w CallIOPRoutine ; get the Icon
|
||
bra.s IopCtlDone ; get the error code (or noErr) and return <2.8>
|
||
|
||
|
||
IopCtlDrvInfo
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info <2.2>
|
||
move.l SwimIopMsg.DriveInfo(a2),(a0)
|
||
bra.w DiskIODone ; return
|
||
|
||
|
||
;_______________________________________________________________________ <2.8>
|
||
;
|
||
; Routine: IopCtlFmtCopy
|
||
;
|
||
; Inputs: A0 -- pointer to user's parameter block
|
||
; csParam+ 0: format type (1=400K, 2=800K, 3=720K, 1=1440K[HD])
|
||
; csParam+ 2: pointer to user data buffer
|
||
; csParam+ 6: pointer to tag data buffer
|
||
; csParam+10: format byte ($02=Mac 400K, $22=Mac 800K, $24=Apple II 800K)
|
||
; csParam+11: if 0 then also verify each track
|
||
; A1 -- pointer to SonyVars
|
||
; D1 -- offset to drive's private variables
|
||
;
|
||
; Outputs: D0 -- result code (0 if correctly formatted)
|
||
;
|
||
; Function: Formats, copies [and verifies] each track on a disk in one
|
||
; pass for the Apple 3.5" Floppy Disk Duplicator program.
|
||
;_______________________________________________________________________
|
||
|
||
IopCtlFmtCopy
|
||
lea xmtMsg.HdrFmtKind(a1),a2; pointer to message for copying
|
||
move.b csParam+10(a0),(a2)+ ; setup hdr format byte
|
||
|
||
assert xmtMsg.SectInterleave=xmtMsg.HdrFmtKind+1
|
||
clr.b (a2)+ ; use default interleave
|
||
|
||
assert xmtMsg.FmtDataAddr=xmtMsg.SectInterleave+1
|
||
move.l csParam+2(a0),(a2)+ ; setup sector data ptr
|
||
|
||
assert xmtMsg.FmtTagAddr=xmtMsg.FmtDataAddr+4
|
||
move.l csParam+6(a0),(a2)+ ; setup sector tags ptr
|
||
bsr.w CallIOPRoutine ; format the disk using supplied data
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info
|
||
move.w xmtMsg.ErrorCode(a1),d0 ; get the returned error code (or noErr)
|
||
bne.s @done ; die on format errors
|
||
|
||
tst.b 11(a0) ; see if verify needed
|
||
beq.s @done ; if not, return with success
|
||
|
||
move.l xmtMsg.FixedDiskSize(a1),xmtMsg.BlockCount(a1) ; setup the disk size in blocks
|
||
move.b #xmtReqReadVerify,xmtMsg.ReqKind(a1); setup the request
|
||
move.l 2(a0),xmtMsg.BufferAddr(a1) ; setup buffer address
|
||
clr.l xmtMsg.BlockNumber(a1) ; setup starting block number
|
||
bsr.w CallIOPRoutine ; verify the data buffer
|
||
move.w xmtMsg.ErrorCode(a1),ErrorCodeSave(a1) ; save verify error code
|
||
|
||
move.b #xmtReqDriveStatus,xmtMsg.ReqKind(a1) ; setup the request
|
||
bsr.w CallIOPRoutine ; get the status buffer
|
||
move.w ErrorCodeSave(a1),d0 ; get the verify error code
|
||
bne.s @done ; die on errors
|
||
clr.l d1 ; zero extend the drive number
|
||
move.b xmtMsg.DriveNumber(a1),d1 ; get the drive number
|
||
movea.l DriveInfoPtrs(a1,d1.w*4),a2 ; get drive info pointer
|
||
moveq.l #dataVerErr,d0 ; default to data verify error
|
||
move.w PerDriveInfo.DriveQElement+dQDrvSz2(a2),d1 ; get the old error count
|
||
cmp.w xmtMsg.DiskErrors(a1),d1 ; see if any new soft errors
|
||
bne.s @done ; die on errors
|
||
|
||
moveq.l #noErr,d0 ; report success
|
||
@done bra.s ToDiskIODone ; return with success
|
||
|
||
|
||
;_______________________________________________________________________ <2.8>
|
||
;
|
||
; Routine: IopCtlGetRawData
|
||
;
|
||
; Inputs: A0 -- pointer to user's parameter block
|
||
; csParam+ 0: pointer to user Clock Bits Buffer
|
||
; csParam+ 4: pointer to user data buffer
|
||
; csParam+ 8: byte count in
|
||
; csParam+12: byte count out
|
||
; csParam+16: search mode
|
||
; csParam+18: track
|
||
; csParam+20: side
|
||
; csParam+21: sector
|
||
; A1 -- pointer to SonyVars
|
||
;
|
||
; Outputs: D0 -- result code (0 if correctly formatted)
|
||
;
|
||
; Function: reads raw data bytes from the disk, used for copy protection support
|
||
;_______________________________________________________________________
|
||
|
||
IopCtlGetRawData
|
||
lea xmtMsg.RawClockAddr(a1),a2 ; pointer to message for copying
|
||
lea csParam(a0),a0 ; pointer to params
|
||
move.l (a0)+,(a2)+ ; setup RawClockAddr
|
||
|
||
assert xmtMsg.RawDataAddr=xmtMsg.RawClockAddr+4
|
||
move.l (a0)+,(a2)+ ; setup RawDataAddr
|
||
|
||
assert xmtMsg.RawByteCount=xmtMsg.RawDataAddr+4
|
||
move.l (a0)+,(a2)+ ; setup RawByteCount
|
||
|
||
clr.l (a0)+ ; clear numDone by default
|
||
|
||
assert xmtMsg.RawSearchMode=xmtMsg.RawByteCount+4
|
||
assert xmtMsg.RawCylinder=xmtMsg.RawSearchMode+2
|
||
move.l (a0)+,(a2)+ ; setup RawSearchMode and RawCylinder
|
||
|
||
assert xmtMsg.RawHead=xmtMsg.RawCylinder+2
|
||
assert xmtMsg.RawSector=xmtMsg.RawHead+1
|
||
move.w (a0)+,(a2)+ ; setup RawHead and RawSector
|
||
|
||
bsr.w CallIOPRoutine ; get the raw data
|
||
move.w xmtMsg.ErrorCode(a1),d0 ; get the returned error code (or noErr)
|
||
bne.s @done ; die on errors
|
||
move.l xmtMsg.RawByteCount(a1),csParam+12(a0) ; return the number of bytes read
|
||
@done ; return with success
|
||
ToDiskIODone
|
||
bra.w DiskIODone
|
||
|
||
|
||
IopGetFormatList
|
||
bsr.w UpdateXmtDriveStatus ; update the drive info <2.8>
|
||
moveq.l #offLinErr,d0 ; default error in case no disk in place. <2.1>
|
||
cmpi.b #2,SwimIopMsg.DiskInPlace(a2) ; see if disk is online and clamped <2.1>
|
||
blt.s ToDiskIODone ; if no disk, or format unknown, offLinErr <2.1><2.8>
|
||
moveq.l #paramErr,d0 ; default error incase no entries allowed. <2.1>
|
||
move.w (a0)+,d2 ; d2 <- max list size <2.1>
|
||
ble.s ToDiskIODone ; no room to return anything <2.1><2.8>
|
||
move.w SwimIopMsg.FormatsAllowed(a2),d0; get allowable formats
|
||
move.w SwimIopMsg.CurrentFormat(a2),d1 ; get current format
|
||
movea.l (a0),a2 ; a2 <- pointer to result list
|
||
lea IopDiskFmtTbl,a3 ; a3 <- pointer to list template
|
||
clr.w -(a0) ; returned list size := 0
|
||
moveq.l #0,d3 ; d3 <- bit index into lists
|
||
@loop bclr.l d3,d0 ; test and clear allowable format bit
|
||
beq.s @next ; bit wasn't set, try next
|
||
move.l (a3,d3.w*8),(a2)+ ; copy disk size
|
||
move.l 4(a3,d3.w*8),(a2)+ ; copy attributes
|
||
bclr.l d3,d1 ; test and clear current format bit
|
||
beq.s @currentDone ; if not the current format
|
||
bset.b #6,-4(a2) ; set the 'is current format' bit
|
||
tst.w d3 ; was this the fixed disk format?
|
||
bne.s @currentDone ; if not, don't adjust size
|
||
move.l xmtMsg.FixedDiskSize(a1),-8(a2) ; return the fixed disk size
|
||
@currentDone
|
||
addq.w #1,(a0) ; increment result list count
|
||
subq.w #1,d2 ; decrement space left
|
||
ble.s @done ; if result list is now full
|
||
@next addq.w #1,d3 ; increment template list / bit index
|
||
tst.w d0 ; see if all formats found
|
||
bne.s @loop ; loop through remaining list
|
||
@done moveq.l #noErr,d0 ; return good status
|
||
bra.s ToDiskIODone ; return <2.8>
|
||
|
||
|
||
IopDriveStatus
|
||
bsr.s UpdateXmtDriveStatus ; update the drive info
|
||
addq.l #SwimIopMsg.DriveStatus,a2 ; point to status from IOP
|
||
addq.l #PerDriveInfo.DriveQElement,a3 ; point to drive queue element
|
||
move.w (a2)+,(a0)+ ; copy track
|
||
move.l (a2)+,(a0)+ ; copy writeProt, diskInPlace, installed, sides
|
||
move.l (a3)+,(a0)+ ; copy qLink
|
||
move.l (a3)+,(a0)+ ; copy qType, dQDrive
|
||
move.l (a3)+,(a0)+ ; copy dQRefNum, dQFSID
|
||
move.l (a2)+,(a0)+ ; copy twoSideFmt, reserved, diskErrs
|
||
bra.s ToDiskIODone ; return <2.8>
|
||
|
||
|
||
IopMFMStatus
|
||
bsr.s UpdateXmtDriveStatus ; update the drive info
|
||
move.l SwimIopMsg.ExtDriveStatus(a2),(a0)
|
||
bra.s ToDiskIODone ; return <2.8>
|
||
|
||
|
||
;_______________________________________________________________________ <2.8>
|
||
;
|
||
; Routine: IopDupVersion
|
||
;
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to SonyVars
|
||
;
|
||
; Outputs: D0 -- result code
|
||
;
|
||
; Function: Returns the duplicator version that this driver supports.
|
||
; This is so that common features are properly matched.
|
||
;_______________________________________________________________________
|
||
|
||
IopDupVersion
|
||
move.w xmtMsg.DupVersion(a1),csParam(a0) ; get the current version
|
||
bra.w IopCtlDone ; get the error code (or noErr) and return
|
||
|
||
|
||
;_______________________________________________________________________ <2.8>
|
||
;
|
||
; Routine: IopGetFmtByte
|
||
;
|
||
; Inputs: A0 - pointer to I/O ParamBlock
|
||
; A1 - pointer to SonyVars
|
||
;
|
||
; Outputs: D0 -- result code
|
||
;
|
||
; Function: Returns the format byte from the last address field read so
|
||
; that we can determine what the interleave is for 800K disks.
|
||
; This call can also be used to determine if the RAM-based
|
||
; Disk Duplicator version of the driver is installed.
|
||
;_______________________________________________________________________
|
||
|
||
IopGetFmtByte
|
||
move.b xmtMsg.HdrFmtKind(a1),csParam(a0) ; get the format byte
|
||
bra.w IopCtlDone ; get the error code (or noErr) and return
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: UpdateXmtDriveStatus, UpdateDriveStatus
|
||
; Inputs: A1 - pointer to SonyVars
|
||
; A2 - pointer to status message buffer
|
||
; Outputs: A0 - pointer to csParam field of current IO request
|
||
; A3 - pointer to PerDriveInfo for desired drive
|
||
; D0 - default error code (noErr)
|
||
; D1 - drive number from status message (zero extended to long)
|
||
; Destroys: D2, D3
|
||
; Calls: none
|
||
; Called by: ctlFormat, ctlEject, ctlPhysIcon, ctlLogIcon, ctlDrvInfo,
|
||
; GetFormatList, DriveStatus, MFMStatus, ReceivedCallFromIop
|
||
;
|
||
; Function: Locates and updates the PerDriveInfo record based upon the
|
||
; information in the status message buffer.
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
|
||
UpdateXmtDriveStatus
|
||
lea xmtMsg(a1),a2 ; point to the returned status
|
||
UpdateDriveStatus
|
||
clr.l d1 ; zero extend the drive number
|
||
move.b SwimIopMsg.DriveNumber(a2),d1 ; get the drive number
|
||
lea nullPerDriveInfo,a3 ; a3 <- per drive info for nonexistent drives
|
||
move.l DriveInfoPtrs(a1,d1.w*4),d2 ; get drive info pointer
|
||
beq.s @done ; if no drive info for this drive
|
||
|
||
movea.l d2,a3 ; a3 <- real per drive info
|
||
|
||
assert SwimIopMsg.DiskInPlace=SwimIopMsg.WriteProtected+1
|
||
assert PerDriveInfo.DiskInPlace=PerDriveInfo.WriteProtected+1
|
||
|
||
assert SwimIopMsg.Installed=SwimIopMsg.DiskInPlace+1
|
||
assert PerDriveInfo.Installed=PerDriveInfo.DiskInPlace+1
|
||
|
||
assert SwimIopMsg.Sides=SwimIopMsg.Installed+1
|
||
assert PerDriveInfo.Sides=PerDriveInfo.Installed+1
|
||
|
||
move.l SwimIopMsg.WriteProtected(a2),\
|
||
PerDriveInfo.WriteProtected(a3) ; update flags in DriveQueueElement
|
||
|
||
if Compatibility then
|
||
; the SONY driver uses the 4 bytes of the drive queue element that is
|
||
; supposed to contain the drive size, to store TwoSidedFormat, NewInterface,
|
||
; and DiskErrors information. This is not documented in Inside Macintosh
|
||
; (although it is documented as being returned by Status csCode 8).
|
||
; for compatibility with software (like DiskFirstAid) which looks directly
|
||
; at the DQElement to check TwoSided, we will update this field.
|
||
|
||
assert SwimIopMsg.NewInterface=SwimIopMsg.TwoSidedFormat+1
|
||
assert SwimIopMsg.DiskErrors=SwimIopMsg.NewInterface+1
|
||
|
||
move.l SwimIopMsg.TwoSidedFormat(a2),\
|
||
PerDriveInfo.DriveQElement+dQDrvSz(a3) ; insert info into drive queue
|
||
|
||
endif
|
||
|
||
cmpi.w #1,PerDriveInfo.DriveQElement+qType(a3)
|
||
bne.s @done ; if not entended drive queue element
|
||
|
||
move.l SwimIopMsg.FixedDiskSize(a2),d3
|
||
swap d3
|
||
move.l d3,PerDriveInfo.DriveQElement+dQDrvSz(a3)
|
||
|
||
@done movea.l DCEPointer(a1),a0 ; get DCE pointer
|
||
movea.l DCtlQHead(a0),a0 ; get IO param block pointer
|
||
lea csParam(a0),a0 ; a0 <- csParam pointer
|
||
moveq.l #noErr,d0 ; d0 <- default error code (noErr)
|
||
rts
|
||
|
||
|
||
; The information for each possible disk format is an 8-byte record:
|
||
; Byte 0-3: disk capacity in blocks
|
||
; (is [#tracks][#heads][#sectors][#bytes/sector])
|
||
; 4: bit 7=1: number of tracks, sides, sectors is valid
|
||
; 6=1: current disk has this format
|
||
; 5=0: reserved for future expansion, should be zero
|
||
; 4=0: single density, =1: double density
|
||
; 0-3: number of heads (or zero if don't care)
|
||
; 5: number of sectors (or zero if don't care)
|
||
; 6-7: number of tracks (or zero if don't care)
|
||
|
||
IopDiskFmtTbl
|
||
dc.l 38965 ; HD-20
|
||
dc.b (%0100<<4)+0,0,0,0 ; THS invalid, current disk has this format
|
||
|
||
dc.l 400*2 ; 400K GCR
|
||
dc.b (%1000<<4)+1 ; THS valid, SD, 1 head
|
||
dc.b 10 ; 10 sectors (average)
|
||
dc.w 80 ; 80 tracks
|
||
|
||
dc.l 800*2 ; 800K GCR
|
||
dc.b (%1000<<4)+2 ; THS valid, SD, 2 heads
|
||
dc.b 10 ; 10 sectors (average)
|
||
dc.w 80 ; 80 tracks
|
||
|
||
dc.l 720*2 ; 720K (1M) MFM
|
||
dc.b (%1000<<4)+2 ; THS valid, SD, 2 heads
|
||
dc.b 9 ; 9 sectors
|
||
dc.w 80 ; 80 tracks
|
||
|
||
dc.l 1440*2 ; 1440K (2M) MFM
|
||
dc.b (%1001<<4)+2 ; THS valid, DD, 2 heads
|
||
dc.b 18 ; 9 sectors
|
||
dc.w 80 ; 80 tracks
|
||
|
||
|
||
nullPerDriveInfo
|
||
dcb.b PerDriveInfo.PerDriveInfoSize,0
|
||
TITLE 'SONY Driver - IOP call processing'
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: CallIOPRoutine
|
||
; Inputs: A1 - pointer to SonyVars
|
||
; Outputs: A0 - pointer to IOPB for current call <2.8>
|
||
; A1 - pointer to SonyVars
|
||
; Destroys: all other registers are destroyed across the async call
|
||
; Calls: _IOPMsgAccess
|
||
; Called by: DiskOpen, DiskPrime, DiskControl, DiskStatus
|
||
;
|
||
; Function: Asynchronously calls a IOP based driver routine, and returns
|
||
; to the caller when the routine completes. The message parameter
|
||
; block is sent to the IOP and copied back when the call completes
|
||
; It will return immediatly to the callers-caller while the
|
||
; async operation immediatly to the callers-caller while the
|
||
; async operation is in progress.
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
CallIOPRoutine
|
||
move.l (sp)+,xmtWaiterPC(a1) ; save waiter address
|
||
lea xmtReq(a1),a0 ; a0 <- pointer to IOPRequestInfo param block
|
||
_IOPMsgRequest ; send the message to the IOP
|
||
rts ; return to callers caller
|
||
|
||
IOPCallReturned ; a0 <- pointer to IOPRequestInfo on entry
|
||
lea -xmtReq(a0),a1 ; a1 <- SonyVars
|
||
move.l xmtWaiterPC(a1),-(sp) ; prepare to return to waiter
|
||
clr.l xmtWaiterPC(a1) ; indicate nobody waiting
|
||
movea.l DCEPointer(a1),a2 ; get DCE pointer
|
||
movea.l DCtlQHead(a2),a0 ; get IO param block pointer <2.8>
|
||
rts ; return to the waiting routine <2.8>
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: ReceivedCallFromIop
|
||
; Inputs: A1 - pointer to SonyVars
|
||
; Outputs: none
|
||
; Destroys:
|
||
; Calls: _IOPMsgAccess, _PostEvent, UpdateDriveStatus
|
||
; Called by: IOPManager
|
||
;
|
||
; Function: Handles status change messages sent from the IOP based
|
||
; driver. Posts DiskInserted or DiskEject events if the
|
||
; message indicates that the corresponding events were
|
||
; detected by the IOP based driver.
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
with IOPRequestInfo
|
||
ReceivedCallFromIop ; registers a0-a3/d0-d3 preserved by interrupt
|
||
; a0 <- pointer to IOPRequestInfo on entry
|
||
lea -rcvReq(a0),a1 ; a1 <- SonyVars
|
||
lea rcvMsg(a1),a2 ; a2 <- rcvMsg
|
||
|
||
move.w #noErr,SwimIopMsg.ErrorCode(a2) ; assume no error
|
||
move.b SwimIopMsg.ReqKind(a2),d2 ; get request kind
|
||
|
||
cmpi.b #rcvReqDiskInserted,d2 ; was it an insertion event? <SM2>
|
||
bne.s @1 ; ¥ no - it's either eject or bogus <SM2>
|
||
|
||
; Check if we're SECUREd <SM2>
|
||
;
|
||
; If we're SECUREd. Fake the drive queue out by calling UpdateDriveStatus. <SM2>
|
||
; This will cause things like DiskInPlace in the drive queue to be set <SM2>
|
||
; even if the disk is not mounted. That will allow the EJECT call that <SM2>
|
||
; will get posted to occur. <SM2>
|
||
|
||
bsr CheckIfSecure ; ¥ see if we have a keyswitch and it's SECUREd<SM2>
|
||
bne.s @OkToDoIt ; ¥ IF SECURE THEN <T13><SM2>
|
||
|
||
bsr UpdateDriveStatus ; ¥ fake out drive queue <SM2>
|
||
move.b #rcvReqDiskEjected,d2 ; ¥ force D2 to contain an eject request <SM2>
|
||
bra.s @1 ; ¥ and exit to caller <SM2>
|
||
; ; ¥ ELSE <SM2>
|
||
@OkToDoIt moveq.l #0,d0 ; upper d0 <- 0, disk inserted <SM2>
|
||
beq.s @postEvent ; branch if DiskInsertEvt AND we're allowing it <SM3>
|
||
|
||
@1 moveq.l #-1,d0 ; upper d0 <- -1, disk ejected <SM2>
|
||
cmpi.b #rcvReqDiskEjected,d2 ; was it an Ejected event?
|
||
bne.s @updateStatus ; if not disk ejected request
|
||
|
||
@postEvent movea.w #DiskInsertEvt,a0 ; a0 <- event type
|
||
clr.w d0 ; zero extend drive number
|
||
move.b SwimIopMsg.DriveNumber(a2),d0 ; insert drive number into message
|
||
_PostEvent ; post the insert/eject
|
||
move.w d0,SwimIopMsg.ErrorCode(a2) ; return the error, if any
|
||
bne.s @sendReply ; don't update status if error found
|
||
|
||
@updateStatus
|
||
bsr.w UpdateDriveStatus ; update status based upon status change info
|
||
@sendReply lea rcvReq(a1),a0 ; a0 <- rcvReq
|
||
move.b #irSendRcvReply,irRequestKind(a0)
|
||
_IOPMsgRequest ; send the reply back to the IOP
|
||
rts
|
||
endwith
|
||
endwith
|
||
|
||
; ----------------------------------------------------------------------------- <SM2> begin
|
||
;
|
||
; *****************
|
||
; * CheckIfSecure *
|
||
; *****************
|
||
;
|
||
; This routine returns (via CCR) whether or not we have a keyswitch, and if
|
||
; so, whether it is in the SECURE position.
|
||
;
|
||
; NOTE: the KeyswitchSecure position value is 0 = SECURE, 1 = ON. <T13>
|
||
;
|
||
; Input: None
|
||
; Output: CCR.Z NE ... if not a keyswitch or keyswitch NOT in secure position
|
||
; EQ ... if you have a keyswitch an it IS in the SECURE position
|
||
; Trashes: D0
|
||
|
||
CheckIfSecure
|
||
bsr.s CheckForCabooseKeyswitch; universalized check for keyswitches <T16>
|
||
beq.s @secured ; IF NOT aKeyswitch THEN <T13>
|
||
rts ; return to caller with CCR.Z = NE <T13>
|
||
@secured ; ENDIF
|
||
move.l a1,d0 ; temporarily save A1
|
||
movea.l VIA2,a1 ; retrieve VIA2 location
|
||
bsr ReadSecureBit ; call the routine. returns same value as BTST <Z18>
|
||
movea.l d0,a1 ; restore A1
|
||
rts ; return to caller
|
||
|
||
;_______________________________________________________________________ <T16> thru next <T16>
|
||
;
|
||
; Routine: CheckForCabooseKeyswitch
|
||
;
|
||
; Desc: Check whether or not we have an Caboose-style keyswitch.
|
||
;
|
||
; Returns: CCR.Z EQ If you have a Caboose-style keyswitch
|
||
; NE If you don't.
|
||
;_______________________________________________________________________
|
||
|
||
EXPORT CheckForCabooseKeyswitch ; in case someone like SonyPatches.a wants it
|
||
CheckForCabooseKeyswitch
|
||
move.l d0,-(sp) ; save a handy working register
|
||
move.l #KeyswMask,d0 ; get isolation mask ready
|
||
and.l UnivROMFlags,d0 ; grab keyswitch bits in UnivROMFlags
|
||
sub.l #KeyswCaboose,d0 ; and check if we're a Caboose keyswitch
|
||
movem.l (sp)+,d0 ; restore D1 (MOVEM doesn't reset CCR)
|
||
rts ; return to caller with CCR set <T16>
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: ReadSecureBit
|
||
;
|
||
; Desc: This reads the v2Keyswitch bit in VIA2.vBufB and returns
|
||
; its value. The handy by-product of this routine is that
|
||
; it also regenerates sound interrupts that may have been
|
||
; pending that this routine would have cleared because it
|
||
; reads vBufB.
|
||
;
|
||
; Returns: CCR.Z EQ If v2Keyswitch == 0 (keyswitch == SECURE)
|
||
; NE If v2Keyswitch == 1 (keyswitch != SECURE)
|
||
;
|
||
; Trashes: None.
|
||
;_______________________________________________________________________
|
||
|
||
ReadSecureBit
|
||
movem.l d0/a1,-(sp) ; save D0/A1 on the stack so we can use em
|
||
move.b vBufB(a1),d0 ; read VIA2, clearing interrupts (GAG).
|
||
bsr.w ReGenSoundInt ; regenerate possible pending sound interrupts
|
||
btst #v2Keyswitch,d0 ; BTST the bit we're interested in
|
||
movem.l (sp)+,d0/a1 ; restore (ab)used temp. registers
|
||
rts ; <Z18><H7><SM2> end
|
||
|