Files
Shawn Quick dfcaae62dd Add qlink, the disk tools, and a bootable ProDOS 8 image.
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set.

make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
2026-10-16 14:41:55 -07:00

1 line
36 KiB
Plaintext

*******************************************************************************
*
* Mount Image GS
* by Steve Stephenson
*
* !!! 6.0.1 required !!!
*
*******************************************************************************
DebugSymbols equ 1
print push
print off
include 'e16.types'
include 'e16.resources'
include 'e16.window'
include 'e16.finder'
include 'e16.gsos'
include 'e16.control'
include 'all.macros'
macro
&lab DateTimeStamp
&lab dc.b '&Sysdate &SysTime'
mend
print pop
* resource equates
MainWindowTmp equ $00001000
MainWindColor equ $00001000
MainWindTitle equ $00001000
MainCtlList equ $00001000
MountBtn equ $00000001
EjectBtn equ $00000002
MainList equ $00000003
VersionStr equ $00000004
AboutBox equ $00000001
SFPromptStr equ $00002001
**********************************************************************
DriverVersion equ $100E ;experimental
* Status word bits
diskSwitchedBit equ $01
diskInDriveBit equ $10
* GS/OS direct page equates and constants
deviceNum equ $00
callNum equ $02
bufferPtr equ $04
requestCount equ $08
transferCount equ $0C
blockNum equ $10
blockSize equ $14
controlCode equ $16
statusCode equ $16
fstID equ $16
volumeID equ $18
cachePriority equ $1A
cachePointer equ $1C
dibPointer equ $20
INSTALL_DRIVER equ $01FCA8
SET_DISKSW equ $01FC90
MOVE_INFO equ $01FC70
moveblkcmd equ $0800
move_sinc_dinc equ $05+moveblkcmd
move_scon_dinc equ $04+moveblkcmd ; for zeroing blocks
* DIB offsets
dsect 0
kLinkPtr long
kEntryPtr long
kCharacteristics word
kBlockCount long
kDevName block 32
kSlotNum word
kUnitNum word
kVersion word
kDeviceID word
kHeadLink word
kForwardLink word
kExtendedDIBPtr long
kDIBDevNum word
* my extra stuff
kDataHandle long
kStatusFlag word
block 6 ;header size
kDibSize block 0
**********************************************************************
* Image file header constants
dsect 0
kDiskName block 64
kDataSize long
kTagSize long
kDataChecksum long
kTagChecksum long
kDiskFormat byte
kFormatByte byte
kPrivate word
*******************************************************************************
*
* The NDA
*
*******************************************************************************
NDAHeader proc
dc.l NDAOpen ; Pointer to the open routine
dc.l NDAClose ; Pointer to the close routine
dc.l NDAAction ; Pointer to the action routine glue
dc.l NDAInit ; Pointer to the init routine glue
NDAPeriod dc.w $FFFF ; How often the NDA gets run actions (never)
NDAEventMask dc.w $fFFF ; Describes what events the NDA wants
dc.b '**' ; two place-holding characters
NDAMenuLine dc.b 'Mount Image GS'
dc.b '\H**' ; \H and two place-holding characters
dc.b 0 ; The menu item string terminator
*******************************************************************************
*
* NDA Open
*
*******************************************************************************
NDAOpen name
phb ;save B
phk
plb ;reset B
lda OpenAllowed ;got proper environment?
bne @yup
brl @nope ; no.
@yup
* open main window
pha
pea #readEnable ;open my resource fork read-only
pha
_MMStartup
lda 1,s
sta MyID
; _OpenResourceFileByID
ldx #$2e1e
jsl $e10000
pla
bcc @opened
pha
_GetCurResourceApp
pla
cmp MyID
beq @shutmedown
brl @error
@shutmedown _ResourceShutdown
brl @error
@opened ldx #0
pha ;result spc
pha
phx ;title=nil
phx
phx ;refcon=nil
phx
pushlong #ContentDraw
phx ;defproc=nil
phx
pea #refIsResource
pushlong #mainWindowTmp
pea #rWindParam1
_NewWindow2
plx
ply
bcs @error
stx WindowPtr
sty WindowPtr+2
tya
sta 7,s ;inform Desk Mgr
txa
sta 5,s
phy
phx
_SetSysWindow
pushlong WindowPtr
_SetPort
pha ;add the list control
pha
pushlong WindowPtr
pea #singlePtr
pushlong #ListTemplate
_NewControl2
plx
ply
stx ListCtlHandle
sty ListCtlHandle+2
*``` setup list
jsr SetButtonDims
pushlong WindowPtr
_ShowWindow
@error
@nope plb
rtl
*******************************************************************************
*
* Content Draw
*
*******************************************************************************
ContentDraw name
phb
phk
plb
pushlong WindowPtr
_DrawControls
plb
rtl
*******************************************************************************
*
* NDA Close
*
*******************************************************************************
NDAClose name
phb
phk
plb
lda WindowPtr+1
beq @notOpen
pushlong WindowPtr
_CloseWindow
stz WindowPtr+1
@notOpen plb
rtl
*******************************************************************************
*
* NDA Action
*
*******************************************************************************
NDAAction name
phb
phk
plb
phy ;event record
phx
asl a
tax
jsr (@actions,x)
plx
ply
plb
rtl
@actions
dc.w NoAction
dc.w NDAEvent
dc.w NDARun
dc.w NDACursor
dc.w NoAction
dc.w NDAUndo
dc.w NDACut
dc.w NDACopy
dc.w NDAPaste
dc.w NDAClear
NDAUndo name
NDACut name
NDACopy name
NDAPaste name
NDAClear name
lda #-1
NDARun name
NDACursor name
NoAction rts
**********************************************************************
NDAEvent name
phd
tsc
tcd
dsect 5
EventPtr long
pei <EventPtr+2
pei <EventPtr
pushlong #EventRecord
pushlong #16
_BlockMove
pha
pea $ffff
pushlong #EventRecord
_TaskMasterDA
pla
cmp #wInControl
bne @done
jsr DoInControl
@done pld
rts
**********************************************************************
DoInControl name
lda TaskData4
beq @oops ;needed???
cmp #4+1
bcs @oops
asl a
tax
jsr (@controls-2,x)
jsr SetButtonDims
@oops rts
@controls dc.w doMountButton
dc.w doEjectButton
dc.w doMainList
dc.w doAbout
**********************************************************************
doMountButton name
stz SFStatus ;clr SF started flag
pea #0
_SFStatus
pla ;is it loaded?
bcs @load ; no, loaded it
sta SFStatus ; yes, is it started?
beq @loaded ; no, start it
bne @started ; yes, use it.
@load
pea #023 ;load it
pea #$0304
_LoadOneTool
bcs @toerror
@loaded ;start it
pha
pha
pea 0
pea #$0100
pea MyID
pea #$c005
pea 0
pea 0
_NewHandle ;get dp mem
plx
ply
bcs @toerror
stx SFdpHandle
sty SFdpHandle+2
pea MyID
phx
_SFStartup
bcs @toerror
@started ;use it to choose an image file
pea #20
pea #20
pea #refIsResource
pushlong #SFPromptStr
pushlong #0
pushlong #typeList
pushlong #SFReply
_SFGetFile2
bcc @noerr
@toerror brl @error
@noerr lda SFReply
bne @mount
brl @cancel ;user cancelled
@mount pushlong SFpathRef ;lock & deref the path
phd
tsc
tcd
pei <5
pei <3
_HLock
_WaitCursor ;this may take a while..
ldy #2
lda [3]
inc a ;move past buffer length word to c1Str
inc a
tax
lda [3],y
tay ;X,Y hold name pointer
pld
pla
pla
jsr MountIt ;mount the image
php ;save the result
pha
_InitCursor ;fix the cursor
pla
plp ;error?
bcc @mounted ; no, continue
ldx #0 ; yes, show it
phx
phx
phx
phx
pha
_ErrorWindow
pla
brl @error2
@mounted
* add it to the list
jsr SetImageAddr ;set XY=addr of image header
phy
phx
lda dibNum ;find my spot in the member array
asl a
asl a
asl a
tax
pla ;ptr to header/name
sta |ListPtr,x
pla
sta |ListPtr+2,x
lda dibNum ;local dib number
xba
sta |ListPtr+4,x
lda devNum ;bogus!!!```
sta |ListPtr+6,x
inc ListSize
jsr NewSort ;resize and resort
@error2 pushlong SFnameRef ;release SF reply handles
_DisposeHandle
pushlong SFpathRef
_DisposeHandle
@cancel
@error
lda SFStatus ;did we start it?
bne @done ; no, we're done
_SFShutdown ; else, shutdown and unload
pea #023
_UnloadOneTool
pushlong SFdpHandle
_DisposeHandle
@done
rts
**********************************************************************
* Mount the image
* Entry: X,Y = ptr to GS/OS pathname
* Exit: A & C affected
MountIt name
stx Opathname ;save the c1Str pointer
sty Opathname+2
jsr FindAvailableDIB ;get a DIB spot
bcc @found
lda #$68 ;```temp
@toError1 brl @error
@found
stx dibAddr ;lo word of DIB addr (hi is this bank)
sty dibNum ;my 0-rel number of the DIB to use
sta devNum ;device number from DIB (zero if virgin)
; open file
_OpenGS OpenParam ;open the file
bcs @toError1
; read first 84 bytes
lda OrefNum ;clone refNums
sta RWrefNum
sta CloseRefNum
lda #84 ;length of the image file header
sta RWreqCount
stz RWreqCount+2
jsr SetImageAddr ;addr for the header
stx RWbuffer
sty RWbuffer+2
_ReadGS RWparam ;read the header
bcs @toError2
pha ;long spc
pha
ldx RWbuffer
lda |kDataSize,x ;size hi
xba
pha
lda |kDataSize+2,x ;size lo
xba
pha
pha
_MMStartup ;ID
lda #0
pha ;attrib
pha ;addr
pha
_NewHandle ;get mem for image
plx
ply
bcc @gotmem
@toError2 brl @error2
@gotmem
; finish filling the DIB while RWbuffer is still set to header data
txa ;XY hold the handle
ldx dibAddr
sta |kDataHandle,x ;put it into the post-DIB spot
tya
sta |kDataHandle+2,x
ldx RWbuffer ;calc the block count (size/$200)
lda |kDataSize+1,x
xba
lsr a
ldx dibAddr
sta |kBlockCount,x
lda #0
sta |kBlockCount+2,x
ldx RWbuffer ;setup the device ID to look like the image
lda |kDiskFormat,x
and #$ff
asl a
tax
lda IDtable,x
ldx dibAddr
sta |kDeviceID,x
lda #(diskSwitchedBit+diskInDriveBit)
sta |kStatusFlag,x ;init the local status
; read in the data
ldx RWbuffer ;setup the request count
lda |kDataSize,x
xba
sta RWreqCount+2
lda |kDataSize+2,x
xba
sta RWreqCount
ldx dibAddr ;setup the read addr (deref the handle)
lda |kDataHandle+2,x
tay
lda |kDataHandle,x
tax
phb
phy
plb
lda |2,x
tay
lda |0,x
plb
plb
sta RWbuffer
sty RWbuffer+2
_ReadGS RWparam ;read the disk
@error2 php
pha ;keep error code
_CloseGS CloseParam
pla
plp
bcs @error
; if not already started, call INSTALL_DRIVER
lda devNum ;already have a devNum?
bne @good ; yes, don't reinstall.
lda dibaddr ;finish creating the DIB list
sta thisDIBaddr
sep #$20
lda >$e0c068 ;save the slots
pha
lda >$e0c08b ;onto the proper bank
lda >$e0c08b
rep #$20
ldx #DIBList ;point to the DIB list
ldy #^DIBList
jsl INSTALL_DRIVER ;get a devNum assigned
tax
sep #$20
pla
sta >$e0c068 ;restore the slots
rep #$20
txa
bcs @error
ldx dibAddr
lda |kDIBDevNum,x ;get a bogus devNum!!!```
sta devNum
@good clc
rts
@error sec
rts
IDtable
dc.w $03 ;0=400k
dc.w $03 ;1=800k
dc.w $17 ;2=720k
dc.w $17 ;3=1440k
DIBList dc.l 1
thisDIBaddr dc.l DIB_1
**********************************************************************
* Input: none
* Output: C= success
* A= devNum (zero if never installed)
* X= DIB addr
* Y= nth dib
*
FindAvailableDIB name
ldy #0
ldx #DIB_1
@next lda |KStatusFlag,x ;already have one mounted?
and #diskInDriveBit
beq @found ; no, it's available
iny ; yes, keep looking
cpy #8 ;tried all 8?
bcs @none ; yup, none available; return carry set.
txa ; no, step to next dib
clc
adc #kDibSize ; inc X by size of a dib
tax
bra @next
@found lda |kDIBDevNum,x ;return devNum in A
clc
@none rts
**********************************************************************
* Input: dibNum valid
* Output: XY = Image header addr
*
SetImageAddr name
pha
pha
pea #84 ;multiply the dibNum by the header size
pushword dibNum
_Multiply
pla
adc #ImageHeaders ;and add the offset from the first
tax
pla
lda #^ImageHeaders
tay
rts
**********************************************************************
doEjectButton name
lda ListSize ;use a local copy
sta @count
pushlong #SelectSort ;sort all selected members to the end
pushlong ListCtlHandle
_SortList2
stz @next ;start at top of list
@loop pha
pushword @next
pushlong ListCtlHandle
_NextMember2 ;get first selected
pla ;got one?
beq @none ; no, we're done.
sta @next ; yes, set next search start spot
dec a
asl a
asl a
asl a
tax
lda |ListPtr+5,x ;get dibNum
and #$ff
pha
pha
pha
pea #kDIBsize
_Multiply
pla
adc #DIB_1
tax ;X=this DIB addr
pla ;(fix stk)
lda |kDIBdevNum,x ;get the real devNum
sta EjectNum
_DControlGS EjectParam
dec @count
bra @loop
@none lda @count
sta ListSize
brl NewSort ;reset and resort the list
@next dc.w 0
@count dc.w 0
**********************************************************************
* Compare routine to move all selected members to the end of the list
SelectSort name
ldy #5 ;index to ListMgr select byte
sep #$20
lda [4],y
cmp [8],y
rep #$20
lda 0,s
sta 8,s
lda 2,s
sta 10,s
pla
pla
pla
pla
rtl
**********************************************************************
doMainList name
* need to do anything here?
rts
**********************************************************************
doAbout name
lda #0
pha
pea awButtonLayout+awResource
pha
pha
pushlong #AboutBox
_AlertWindow
pla
rts
**********************************************************************
* Set the hilite state of the buttons
* If no items are selected in the list, dim the Eject button
* If there are already 8 mounted images, dim the Mount button
SetButtonDims name
pha
pea 0
pushlong ListCtlHandle
_NextMember2
pla ;anything selected?
beq @dimEject ; no, dim it
@undimEject lda #noHilite ; yes, undim it
bra @setEject
@dimEject lda #inactiveHilite
@setEject pha
pushlong WindowPtr
pushlong #EjectBtn
; _HiliteCtlByID
ldx #$3f10
jsl $e10000
lda ListSize
cmp #8 ;list already full?
beq @dimMount ; yes, dim it
@undimMount lda #noHilite ; no, undim it
bra @setMount
@dimMount lda #inactiveHilite
@setMount pha
pushlong WindowPtr
pushlong #MountBtn
; _HiliteCtlByID
ldx #$3f10
jsl $e10000
rts
**********************************************************************
* Update the List globals and sort it
NewSort name
ldx #0
phx
phx
pea 1 ;display from #1
pushlong #ListPtr
phx
pushword ListSize
pushlong ListCtlHandle
_NewList2
lda #0 ;use default alpha sort
pha
pha
pushlong ListCtlHandle
_SortList2
rts
*******************************************************************************
*
* NDA Init
*
*******************************************************************************
NDAInit name
phb
phk
plb
pha
stz OpenAllowed
_GET_VERSION OSversion
lda OSversion
and #$7fff
cmp #$0402 ;6.0.1 required
bcc @bad
sta OpenAllowed
@bad
pla
bcc @done
beq @shutdown
@startup
* on startup: add request proc
; pushlong #RequestName
; pha
; _MMStartup
; pushlong #RequestProc
; _AcceptRequests
@shutdown
*``` on shutdown: ???
@done
plb
rtl
*******************************************************************************
*
* Request Proc
*
*******************************************************************************
RequestProc name
phb
phk
plb
phd
tsc
tcd
dsect 1
@d word
@b byte
@rtl block 3
dataOut long
dataIn long
reqCode word
result word
lda <reqCode
cmp #finderSaysBeforeOpen
bne @notOurs
ldy #$16
lda [dataIn],y ;printing?
bne @notOurs ; yes, skip
ldy #$0a
lda [dataIn],y ;type
cmp #$E0 ;ours?
bne @notOurs ; no, skip
iny
iny
lda [dataIn],y ;auxtype lo
cmp #$0005 ;ours?
bne @notOurs ; no, skip
iny
iny
lda [dataIn],y ;auxtype hi (must be 0)
bne @notOurs ; no, skip
ldy #2
lda [dataIn],y
tax
iny
iny
lda [dataIn],y
tay ;pass pathname ptr in XY
jsr MountIt ;try to mount it
bcs @notOurs ; treat error same as not handled
lda #$8000 ;we handled it
bra @exit
@notOurs
lda #0 ;we did not handle it
@exit sta <result
pld ;restore D
plx ;hold B and hi addr
ply ;hold lo addr
pla ;pop 10 bytes
pla
pla
pla
pla
phy ;restore lo addr
phx ;restore hi addr and B
plb ;restore B
rtl
*******************************************************************************
*
* NDA Variables
*
*******************************************************************************
MyID dc.w 0
OSversion dc.w 0
OpenAllowed dc.w 0
WindowPtr dc.l 0
EventRecord
What dc.w 0
Message dc.l 0
When dc.l 0
Where dc.l 0
Modifiers dc.w 0
TaskData dc.l 0
TaskMask dc.l tmMenuKey+tmUpdate+tmFindW+tmMenuSel+tmOpenNDA+tmSysClick+\
tmDragW+tmContent+tmClose+tmZoom+tmGrow+tmScroll+tmSpecial+\
tmCRedraw+tmInactive+tmInfo+tmContentControls+tmControlKey+\
tmControlMenu+tmMultiClick+tmIdleEvents
LastClickTick dc.l 0
ClickCount dc.w 0
TaskData2 dc.l 0
TaskData3 dc.l 0
TaskData4 dc.l 0
LastClickPoint dc.l 0
RequestName str 'Apple~Mount Image GS~'
SFStatus dc.w 0
SFdpHandle dc.l 0
TypeList dc.w 1
@flags dc.w 0 ;must match both type and auxtype
@type dc.w $E0
@auxtype dc.l $0005
SFReply dc.w 0
@type dc.w 0
@auxtype dc.l 0
@nameRefDesc dc.w refIsNewHandle
SFnameRef dc.l 0
@pathRefDesc dc.w refIsNewHandle
SFpathRef dc.l 0
OpenParam dc.w 5
OrefNum dc.w 0
Opathname dc.l 0
OreqAccess dc.w 0
@fork dc.w 0
Oaccess dc.w 0
RWparam dc.w 4
RWrefNum dc.w 0
RWbuffer dc.l 0
RWreqCount dc.l 0
RWtransCount dc.l 0
CloseParam dc.w 1
CloseRefNum dc.w 0
EjectParam dc.w 5
EjectNum dc.w 0
@code dc.w 2
dc.l 0
dc.l 0
dc.l 0
dibAddr dc.w 0
dibNum dc.w 0
devNum dc.w 0
ListCtlHandle dc.l 0
ListTemplate dc.w 14
dc.l MainList ;ID
dc.w 4,10,86,284 ;rect
dc.l listControl
dc.w 0 ;flag
dc.w fCtlProcRefNotPtr+fCtlIsMultiPart
dc.l 0 ;refcon
ListSize dc.w 0
dc.w 8 ;list view
dc.w 0 ;pStrings, multi-select, scrollbar outside
dc.w 1 ;list start
dc.l 0 ;list draw
dc.w 10 ;font height
dc.w 8 ;member size
dc.l ListPtr ;list ptr
ListPtr ds 64
ImageHeaders
IMAGE_1
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_2
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_3
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_4
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_5
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_6
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_7
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
IMAGE_8
@DiskName ds 64
@DataSize dc.l 0
@TagSize dc.l 0
@DataChecksum dc.l 0
@TagChecksum dc.l 0
@DiskFormat dc.b 0
@FormatByte dc.b 0
@Private dc.w 0
*������������������������������������������������������������������������������
*������������������������������������������������������������������������������
*******************************************************************************
*
* The Driver
*
*******************************************************************************
*******************************************************************************
*
* The Main Driver entry point
*
* All calls start here with the command number in A.
*
* Returns a result/error code in A and affects the carry.
*
*******************************************************************************
MainEntry name
phk
plb
cmp #8+1
bcc @handleCall
lda #DrvrBadReq ;command out of range
bra @exitDriver ;return the error and condition the carry
@handleCall asl a ;index into handler table
tax
stz OurError ;init to noError
jsr (DrvrTable,X) ;handle it
lda OurError ;setup result in A
@exitDriver cmp #1 ;and success in P
rtl
DrvrTable dc.w Startup
dc.w Open
dc.w Read
dc.w Write
dc.w Close
dc.w Status
dc.w Control
dc.w Flush
dc.w Shutdown
*******************************************************************************
*
* Startup
*
*******************************************************************************
Startup name
* do nothing
rts
*******************************************************************************
*
* Open
*
*******************************************************************************
Open name
* do nothing
rts
*******************************************************************************
*
* Read
*
*******************************************************************************
Read name
jsr SetupTheMove
bcs @Exit
; lookup the disk's handle
@handle equ requestCount
pei <requestCount+2 ;save original
pei <requestCount
ldy #kDataHandle+2
lda [dibPointer],y
and #$ff
sta <@handle+2
dey
dey
lda [dibPointer],y
sta <@handle
; calc the offset into the block using a temp long on the stack
lda #0
pha
pha
lda <blockNum
asl a
sta 2,s
; add the offset to the start of the block to get the abs addr
ldy #2
lda [@handle]
clc
adc 1,s
sta 1,s
lda [@handle],y
adc 3,s
sta 3,s ; source address now on stack
pei <bufferPtr+2
pei <bufferPtr ; destination address on the stack
pei <transferCount+2
pei <transferCount ; request count on stack
pea move_sinc_dinc ; the command word
jsl MOVE_INFO ; system service call
pla
sta <requestCount ;restore
pla
sta <requestCount+2
@Exit rts
*******************************************************************************
*
* Write
*
*******************************************************************************
Write name
jsr SetupTheMove
bcs @Exit
; lookup the disk's handle
@handle equ requestCount
pei <requestCount+2 ;save original
pei <requestCount
ldy #kDataHandle+2
lda [dibPointer],y
and #$ff
sta <@handle+2
dey
dey
lda [dibPointer],y
sta <@handle
pei <bufferPtr+2
pei <bufferPtr ; source address on the stack
; calc the offset into the block using a temp long on the stack
lda #0
pha
pha
lda <blockNum
asl a
sta 2,s
; add the offset to the start of the block to get the abs addr
ldy #2
lda [@handle]
clc
adc 1,s
sta 1,s
lda [@handle],y
adc 3,s
sta 3,s ; destination address now on stack
pei <transferCount+2
pei <transferCount ; request count on stack
pea move_sinc_dinc ; the command word
jsl MOVE_INFO ; system service call
pla
sta <requestCount ;restore
pla
sta <requestCount+2
ldy #kDataHandle+2
lda [dibPointer],y
ora #$8000 ;set image dirty flag
sta [<dibPointer],y
@Exit rts
**********************************************************************
*
* Check for errors and set <transferCount to the amount to do
* Return carry set to skip the move
*
**********************************************************************
SetupTheMove
jsr CheckSwitched
beq @notswitched
sec
brl @Bad
@notswitched
; Make sure there is something to do
lda <requestCount
ora <requestCount+2
bne @CheckTheCount
sec
brl @Bad ; no action in this case (but also no error)
@CheckTheCount lda <requestCount
and #$1FF ;is the requestCount a multiple of $200
beq @CheckSize ; yes
@BadCount lda #DrvrBadCount
sta OurError
sec
brl @Bad
; Make sure this has our block size
@CheckSize lda <BlockSize ;is the blockSize $200
cmp #$200
bne @BadCount ; no
; Setup amount to do..
lda <requestCount+2 ;clone amount to do in bytes
sta <transferCount+2
lda <requestCount
sta <transferCount
lda <requestCount+3 ;convert bytes to blocks on the stack
and #$00FF
lsr a
pha
lda <requestCount+1
ror a
pha
; Check starting block + requested block count <= total blocks
lda <blockNum ;starting blk
clc
adc 1,s ;+ requested amount
sta 1,s ;= requested total
lda <blockNum+2
adc 3,s
sta 3,s
ldy #kBlockCount ;see if blockCount is = or greater
lda [dibPointer],y
sec
sbc 1,s
pla ;(fix stk as we go)
iny
iny
lda [dibPointer],y
sbc 1,s
pla
bcs @Good ; yes, it's in range, continue
lda #DrvrBadBlock ; no, flag as out of bounds,
sta OurError
stz <transferCount ; but do what will fit anyway.
stz <transferCount+2
ldy #kBlockCount
lda [dibPointer],y ;reset bytes to do
sec ; to amount between starting blk and last blk
sbc <blockNum ; (convert blks to bytes)
asl a
sta <transferCount+1
@Good clc
@Bad rts
*******************************************************************************
*
* Close
*
*******************************************************************************
Close name
* do nothing
rts
*******************************************************************************
*
* Status
*
*******************************************************************************
Status name
lda <statusCode
cmp #4+1 ;check code in range
bcc @handleCall
lda #DrvrBadCode ;out of range
sta OurError
rts
@handleCall asl a
tax
jsr (StatusTable,x)
rts
StatusTable dc.w doGetDeviceStatus
dc.w doGetConfigParameters
dc.w doGetWaitStatus
dc.w doGetFormatOptions
dc.w doGetPartitionMap
**********************************************************************
doGetDeviceStatus name
lda #2
sta <transferCount
ldy #kStatusFlag
lda [dibPointer],y
sta [<BufferPtr]
lda <requestCount
cmp #6
bcc @skipBlockCount
lda #6
sta <transferCount
ldy #kBlockCount
lda [dibPointer],y
tax
iny
iny
lda [dibPointer],y
ldy #4
sta [<BufferPtr],y
dey
dey
txa
sta [<BufferPtr],y
@skipBlockCount
rts
**********************************************************************
doGetConfigParameters name
; -- fall thru --
**********************************************************************
doGetWaitStatus name
lda #0
sta [<BufferPtr]
lda #2
sta <transferCount
rts
**********************************************************************
doGetFormatOptions name ;none
* do nothing
; -- fall thru --
**********************************************************************
doGetPartitionMap name ;none
* do nothing
rts
*******************************************************************************
*
* Control
*
*******************************************************************************
Control name
jsr CheckSwitched
beq @notswitched
rts
@notswitched
lda <controlCode
cmp #9+1 ;check code in range
bcc @handleCall
lda #DrvrBadCode ;out of range
sta OurError
rts
@handleCall asl a
tax
jsr (controlTable,x)
rts
ControlTable dc.w doResetDevice
dc.w doFormatDevice
dc.w doEjectMedium
dc.w doSetConfigParameters
dc.w doSetWaitStatus
dc.w doSetFormatOptions
dc.w doAssignPartitionOwner
dc.w doArmSignal
dc.w doDisarmSignal
dc.w doSetPartitionMap
**********************************************************************
doResetDevice name
* do nothing
; -- fall thru --
**********************************************************************
doFormatDevice name
* do nothing
; -- fall thru --
**********************************************************************
doSetConfigParameters name
* do nothing
; -- fall thru --
**********************************************************************
doSetFormatOptions name
* do nothing
; -- fall thru --
**********************************************************************
doAssignPartitionOwner name
* do nothing
; -- fall thru --
**********************************************************************
doArmSignal name
* do nothing
; -- fall thru --
**********************************************************************
doDisarmSignal name
* do nothing
; -- fall thru --
**********************************************************************
doSetPartitionMap name
* do nothing
rts
**********************************************************************
doEjectMedium name
ldx #0
ldy #kDataHandle+2
lda [dibPointer],y
pha
txa
sta [dibPointer],y
dey
dey
lda [dibPointer],y
pha
txa
sta [dibPointer],y
_DisposeHandle
ldy #kStatusFlag
lda #diskSwitchedBit
sta [dibPointer],y
rts
**********************************************************************
doSetWaitStatus name
lda [<BufferPtr]
bne @err
rts
@err lda #DrvrBadParm
sta OurError
rts
*******************************************************************************
*
* Flush
*
*******************************************************************************
Flush name
* do nothing
rts
*******************************************************************************
*
* Shutdown
*
*******************************************************************************
Shutdown name
jsr doEjectMedium
ldy #1
ldx #DIB_1
@next lda |KStatusFlag,x ;already have one mounted?
and #diskInDriveBit ;got one mounted here?
bne @notAllGone ; yes, then we can't shutdown.
iny ; no, keep looking
cpy #8+1 ;tried all 8?
bcs @allGone ; yup, none mounted.
txa ; no, step to next dib
clc
adc #kDibSize ; inc X by size of a dib
tax
bra @next
@notAllGone lda #DrvrBusy
sta OurError
@allGone rts
*******************************************************************************
*
* Check Disk Switched
*
*******************************************************************************
CheckSwitched
ldy #kStatusFlag
lda [dibPointer],y
bit #diskSwitchedBit
beq @notswitched
and #$ffff-diskSwitchedBit
sta [dibPointer],y
jsl SET_DISKSW
lda #drvrDiskSwitch
sta OurError
@notswitched rts
*******************************************************************************
*
* DIBs
*
*******************************************************************************
MyChar equ %1000101111100100
* ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
* | | | | | | | | | | | | | | | | |
* | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
* | | | | | | | | | | | | | | | |_ RESERVED
* | | | | | | | | | | | | | | |_____ RESERVED
* | | | | | | | | | | | | | |_________ REMOVABLE
* | | | | | | | | | | | | |_____________ FORMAT
* | | | | | | | | | | | |_________________ RESERVED
* | | | | | | | | | | |_____________________ READ
* | | | | | | | | | |_________________________ WRITE
* | | | | | | | | |_____________________________ BLOCK DEVICE
* | | | | | | | |_________________________________ SPEED GROUP (LSB)
* | | | | | | |_____________________________________ SPEED GROUP (MSB)
* | | | | | |_________________________________________ FIXED NAME
* | | | | |_____________________________________________ RESTARTABLE
* | | | |_________________________________________________ BUSY
* | | |_____________________________________________________ LINKED
* | |_________________________________________________________ GENERATED
* |_____________________________________________________________ RAM/ROM DEV
*
DIB_1_HEADER
@DIBoffset dc.w DIB_1-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_1
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.1'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 1
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_2_HEADER
@DIBoffset dc.w DIB_2-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_2
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.2'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 2
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_3_HEADER
@DIBoffset dc.w DIB_3-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_3
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.3'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 3
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_4_HEADER
@DIBoffset dc.w DIB_4-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_4
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.4'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 4
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_5_HEADER
@DIBoffset dc.w DIB_5-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_5
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.5'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 5
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_6_HEADER
@DIBoffset dc.w DIB_6-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_6
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.6'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 6
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_7_HEADER
@DIBoffset dc.w DIB_7-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_7
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.7'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 7
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
DIB_8_HEADER
@DIBoffset dc.w DIB_8-@DIBoffset
@devCount dc.w 1
@configListOffset dc.w 0 ;none
DIB_8
@linkPtr dc.l 0
@entryPtr dc.l MainEntry
@characteristics dc.w MyChar
@blockCount dc.l $77777777 ;fill this in later
@devName str 'MOUNTED.IMAGE.8'
@padding ds.b (@devName+32)-*
@slotNum dc.w $8003 ;independent of hardware resources
@unitNum dc.w 8
@version dc.w DriverVersion
@deviceID dc.w $7777 ;fill this in later
@headLink dc.w 0 ;not used
@forwardLink dc.w 0 ;not used
@extendedDIBPtr dc.l 0 ;not used
@DIBDevNum dc.w 0 ;filled in by the device dispatcher
@dataHandle dc.l 0 ;image block handle
@statusFlag dc.w 0 ;device status word
*******************************************************************************
*
* Driver Variables
*
*******************************************************************************
OurError dc.w 0
**********************************************************************
DateTimeStamp
ENDP
END