mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-23 07:35:19 +00:00
468 lines
20 KiB
Plaintext
468 lines
20 KiB
Plaintext
|
NEW
|
|||
|
AUTO 3,1
|
|||
|
* object code = sel_2
|
|||
|
*
|
|||
|
* Alternate program selector segment for P8 when used in conjunction with
|
|||
|
* gs/os. This code is used in place of the standard P8 interactive program
|
|||
|
* selector when P8 is started up by GQuit. It is called when passing control
|
|||
|
* from one application to another and the new application is 8-bit. This
|
|||
|
* code first loads the specified P8 application at $2000 in bank 0 of memory.
|
|||
|
* It then checks the message center for a possible name of a file. this file
|
|||
|
* is passed on to the 8-bit application. This segment then passes control to
|
|||
|
* the freshly loaded app. This code does NOT start with a CLD instruction
|
|||
|
* (as other replacement quit code is supposed to do) because GQuit checks
|
|||
|
* this to see if this version of quit code is available.
|
|||
|
|
|||
|
ofsQ .EQ GQdisp-dispadr offset to GQuit dispatcher org
|
|||
|
|
|||
|
msb off
|
|||
|
GQdisp lda ramin read/write LC bank 1
|
|||
|
clc
|
|||
|
xce 16 bit native mode.
|
|||
|
jmp >P8QUIT go to GQuit.
|
|||
|
dc h'0000000000' offset to paragraph boundary.
|
|||
|
dc c'GQ' id bytes so GQuit can identify this
|
|||
|
|
|||
|
* load application
|
|||
|
*
|
|||
|
* Entry is in 16-bit native mode. Exit is in emulation mode.
|
|||
|
*
|
|||
|
* On entry and exit:
|
|||
|
* Data bank register is set to $00.
|
|||
|
* Direct register is set to $0000.
|
|||
|
* Stack pointer is set to $01FB.
|
|||
|
*
|
|||
|
* Inputs: acc = value of E1_OS_Switch (0 or 1, 1 = yes to switch)
|
|||
|
*
|
|||
|
* This code is moved to $00/1010 and executed there.
|
|||
|
|
|||
|
* first, copy the prefix passed from gs/os to our own volume name buffer
|
|||
|
* so in case of an error setting the P8 prefix, it can be displayed in the
|
|||
|
* error message.
|
|||
|
|
|||
|
SHORT M 8 bit accumulator
|
|||
|
LONGI ON
|
|||
|
pha save the switch status.
|
|||
|
ldx #inbuf point to passed prefix.
|
|||
|
jsr copyvol copy the name into the buffer.
|
|||
|
pla retrieve the switch status
|
|||
|
|
|||
|
* go into emulation mode to load and run Prodos 8 application
|
|||
|
|
|||
|
sec
|
|||
|
xce 8 bit emulation mode
|
|||
|
ora #$00 switching from P16 to P8 ?
|
|||
|
beq L602D no.
|
|||
|
|
|||
|
* switching from P16 to P8 so pass prefix 0 from P16 to the P8 prefix. the
|
|||
|
* prefix is passed at $00/0200 by GQuit.
|
|||
|
|
|||
|
L6020 jsr MLI set prefix
|
|||
|
dc i1'$C6'
|
|||
|
dc i2'pfxparms'
|
|||
|
bcc L602D if prefix ok.
|
|||
|
jsr gqerror error handler.
|
|||
|
bra L6020 try again
|
|||
|
|
|||
|
* load application at $2000
|
|||
|
|
|||
|
L602D xce native mode (carry clear)
|
|||
|
LONG I 16 bit regs, 8 bit acc.
|
|||
|
lda PrefixBuf+1 is the application name
|
|||
|
cmp #$2F a complete pathname ?
|
|||
|
bne L603D no, use prefix as volume name
|
|||
|
ldx #PrefixBuf else use the application name.
|
|||
|
jsr copyvol copy the volume name to buffer.
|
|||
|
L603D sec back to emulation mode.
|
|||
|
xce
|
|||
|
L603F jsr MLI open the application file
|
|||
|
dc i1'$C8'
|
|||
|
dc i2'opnparms'
|
|||
|
bcc L604C if open ok.
|
|||
|
jsr gqerror handle error.
|
|||
|
bra L603F try again.
|
|||
|
L604C lda oprefnum copy ref number to parameter lists
|
|||
|
sta eofrefn
|
|||
|
sta rdrefnum
|
|||
|
sta closeref
|
|||
|
|
|||
|
* do a geteof call for how many bytes to read
|
|||
|
|
|||
|
L6058 jsr MLI get eof
|
|||
|
dc i1'$D1'
|
|||
|
dc i2'eofparms'
|
|||
|
bcc L6065 eof ok.
|
|||
|
jsr gqerror handle error.
|
|||
|
bra L6058 try again.
|
|||
|
|
|||
|
* store the size of the file in the read parameter list
|
|||
|
|
|||
|
L6065 lda eofval
|
|||
|
sta rdcount
|
|||
|
lda eofval+1
|
|||
|
sta rdcount+1
|
|||
|
L6071 jsr MLI read
|
|||
|
dc i1'$CA'
|
|||
|
dc i2'readparm'
|
|||
|
bcc L607E read ok
|
|||
|
jsr gqerror
|
|||
|
bra L6071
|
|||
|
L607E jsr MLI close
|
|||
|
dc i1'$CC'
|
|||
|
dc i2'closeprm'
|
|||
|
bcc L608B close ok
|
|||
|
jsr gqerror
|
|||
|
bra L607E
|
|||
|
L608B jsr dolaunch check for possible 2nd pathname.
|
|||
|
bne L6099 if none then run program
|
|||
|
jsr ckfordrv else make sure the file is online.
|
|||
|
bcc L6099 if so then run the program.
|
|||
|
lda #$45 volume not found error.
|
|||
|
bra L60AB
|
|||
|
L6099 lda romin enable ROM
|
|||
|
jmp sysentry execute the system application
|
|||
|
gqerror .EQ *-ofsQ
|
|||
|
clc
|
|||
|
xce 16 bit native mode
|
|||
|
LONG I,M
|
|||
|
jsr mountvol mount volume.
|
|||
|
bcs L60AB if error.
|
|||
|
sec back to emulation mode.
|
|||
|
xce
|
|||
|
rts
|
|||
|
|
|||
|
* generate a fatal error while running under Prodos 8.
|
|||
|
* on input, acc = error code. this routine does not return.
|
|||
|
|
|||
|
L60AB clc native mode
|
|||
|
xce
|
|||
|
LONG I,M
|
|||
|
and #$00FF mask off high byte of error code.
|
|||
|
pha put on stack for IntMath tool call.
|
|||
|
pea $0000 errval>>16
|
|||
|
pea errval push address of string buffer.
|
|||
|
pea $0004 make string 4 digits long.
|
|||
|
_Int2Hex convert value to hex string.
|
|||
|
pha make space for return value.
|
|||
|
pea $0000 quitstr1>>16
|
|||
|
pea quitstr1 push first error message address
|
|||
|
pea $0000 quitstr2>>16
|
|||
|
pea quitstr2 push second error message address
|
|||
|
pea $0000 button1>>16
|
|||
|
pea button1 push first button text address
|
|||
|
pea $0000 quitbtn2>>16
|
|||
|
pea quitbtn2 push 2nd button text address (null)
|
|||
|
_TLTextMountVolume make the dialog box
|
|||
|
pla retrieve button press (not used)
|
|||
|
sec emulation mode
|
|||
|
xce
|
|||
|
jsr MLI quit back to GQuit
|
|||
|
dc i1'$65'
|
|||
|
dc i2'quitparms'
|
|||
|
|
|||
|
* p8 mount volume
|
|||
|
*
|
|||
|
* on entry: volbuf = name of volume to mount.
|
|||
|
* on exit: carry clear if mount volume displayed and 'return' was pressed.
|
|||
|
* carry set if no window displayed or if had window and 'esc' pressed.
|
|||
|
|
|||
|
mountvol .EQ *-ofsQ
|
|||
|
ldy #$0000 volbuf>>16
|
|||
|
ldx #volbuf set up pointer to volume name.
|
|||
|
|
|||
|
* if error is 'volume not found' or 'no disk in drive' then display the
|
|||
|
* Mount Volume window, otherwise return with carry set.
|
|||
|
|
|||
|
and #$00FF mask just in case.
|
|||
|
cmp #$0045 volume not found ?
|
|||
|
beq L6101 yes
|
|||
|
cmp #$002F no disk in drive ?
|
|||
|
beq L6101 yes
|
|||
|
sec indicate error not handled.
|
|||
|
rts return with error code still in acc.
|
|||
|
L6101 pha save error code in case esc pressed.
|
|||
|
phy pointer to volume name.
|
|||
|
phx
|
|||
|
tsc
|
|||
|
phd save D reg.
|
|||
|
tcd point D reg at stack.
|
|||
|
lda [$01] get length byte and leading separator.
|
|||
|
dec a don't count leading separator.
|
|||
|
xba then swap the bytes so the volume name
|
|||
|
sta [$01] doesn't cpntain the separator.
|
|||
|
pha room for result.
|
|||
|
pea $0000 mountmsg>>16
|
|||
|
pea mountmsg
|
|||
|
phy hi word of pointer to volume name.
|
|||
|
inx skip separator.
|
|||
|
phx lo word of pointer to volume name.
|
|||
|
pea $0000 button1>>16
|
|||
|
pea button1 'Return'
|
|||
|
pea $0000 button2>>16
|
|||
|
pea button2 'Escape'
|
|||
|
_TLTextMountVolume
|
|||
|
lda [$01] restore first 2 bytes of vilume name
|
|||
|
xba back to their original positions
|
|||
|
inc a and values.
|
|||
|
sta [$01]
|
|||
|
pla which button: 1=Return 2=Escape.
|
|||
|
pld restore D reg.
|
|||
|
plx pull volume name pointer off stack
|
|||
|
plx
|
|||
|
cmp #$0001 which button was pressed ?
|
|||
|
bne L613C if Escape pressed.
|
|||
|
clc indicate Return was pressed.
|
|||
|
pla pull original error code off stack.
|
|||
|
rts return with carry clear.
|
|||
|
L613C sec indicate Escape was pressed.
|
|||
|
pla restore error code.
|
|||
|
rts return with carry set.
|
|||
|
|
|||
|
* copy the volume name from the given pathname to the volume name buffer.
|
|||
|
*
|
|||
|
* inputs: x = length byte of complete pathname containing volume name.
|
|||
|
* output: volume name is stored in volbuf.
|
|||
|
|
|||
|
copyvol .EQ *-ofsQ
|
|||
|
lda |1,x get the first slash
|
|||
|
sta volbuf+1
|
|||
|
ldy #$0002 initialize the length count.
|
|||
|
LONGI OFF
|
|||
|
LONGA OFF
|
|||
|
L6148 lda |2,x now copy the volume name up to
|
|||
|
cmp #$2F the separating slash.
|
|||
|
beq L6156
|
|||
|
sta volbuf,y
|
|||
|
inx
|
|||
|
iny
|
|||
|
bra L6148
|
|||
|
L6156 dey fix character count.
|
|||
|
tya length.
|
|||
|
sta volbuf store the resultant string length.
|
|||
|
rts
|
|||
|
|
|||
|
* translate a filename message from the message center to the currently
|
|||
|
* launching P8 application if it can accept a second filename. If found,
|
|||
|
* copy the filename into the application's filename buffer.
|
|||
|
* on exit, the z-flag is set if a filename was correctly passed to the
|
|||
|
* application elst the z-flag is clear if it couldn't be done.
|
|||
|
|
|||
|
dolaunch .EQ *-ofsQ
|
|||
|
lda sysentry does the app start with a jump ?
|
|||
|
cmp #$4C
|
|||
|
bne L616F no, doesn't follow the convention.
|
|||
|
lda #$EE check for the signature bytes.
|
|||
|
cmp sysentry+3
|
|||
|
bne L616F 1st one doesn't match, skip it.
|
|||
|
cmp sysentry+4
|
|||
|
beq L6170 both match, go get a filename message.
|
|||
|
L616F rts just return to launch the app.
|
|||
|
L6170 lda #$FF put flag conditioning value on
|
|||
|
pha the stack (assume error).
|
|||
|
clc native 16-bit mode.
|
|||
|
xce
|
|||
|
LONG I,M
|
|||
|
pha make room on stack for user id.
|
|||
|
_MMStartUp start up the memory manager.
|
|||
|
pla get the user id and
|
|||
|
pha leave it on the stack.
|
|||
|
pha
|
|||
|
pha make room on stack for new handle.
|
|||
|
pea $0000
|
|||
|
pea $000A get a 10 byte block of memory.
|
|||
|
pha put user id on stack.
|
|||
|
pea $0000 totally unrestricted block.
|
|||
|
pha LocationPtr (not used)
|
|||
|
pha
|
|||
|
_NewHandle go get the block of memory.
|
|||
|
pla get the handle from the stack.
|
|||
|
plx
|
|||
|
bcs L620A branch if error, no memory available.
|
|||
|
phx leave the handle on the stack.
|
|||
|
pha
|
|||
|
pea $0002 'get' a message.
|
|||
|
pea $0001 get a type 1 (filename) message.
|
|||
|
phx put the message handle on the stack
|
|||
|
pha (still in acc and x regs)
|
|||
|
_MessageCenter
|
|||
|
bcs L6203 branch if no message.
|
|||
|
pha leave 4 bytes free on stack
|
|||
|
pha (will be used as a direct page pointer)
|
|||
|
tsc get the stack pointer.
|
|||
|
phd save current direct register.
|
|||
|
inc a point to new direct page space.
|
|||
|
tcd make a new direct page.
|
|||
|
lda [$04] de-reference the handle.
|
|||
|
sta $00
|
|||
|
ldy #$0002
|
|||
|
lda [$04],y
|
|||
|
sta $02
|
|||
|
ldy #$0006 get the message command.
|
|||
|
lda [$00],y
|
|||
|
bne bad_msg if print, then skip it.
|
|||
|
lda $00 adjust pointer to filename string.
|
|||
|
clc
|
|||
|
adc #$0008
|
|||
|
sta $00
|
|||
|
bcc L61D1
|
|||
|
inc $02
|
|||
|
L61D1 lda [$00] get the length of the string.
|
|||
|
and #$00FF mask off high (leaving just the length)
|
|||
|
SHORT M 8 bit accumulator
|
|||
|
cmp sysentry+5 check against length of app buffer.
|
|||
|
beq L61DF if equal then continue with move.
|
|||
|
bcs bad_msg if too long then bad message.
|
|||
|
L61DF tay string length.
|
|||
|
L61E0 lda [$00],y get a character.
|
|||
|
sta sysentry+6,y store it in the app's filename buffer
|
|||
|
sta inbuf,y and in prefix buffer.
|
|||
|
dey
|
|||
|
bpl L61E0
|
|||
|
lda #$00 change flag conditioning value on stack
|
|||
|
sta $0D,s to indicate a filename is passed.
|
|||
|
bad_msg LONG M 16-bit acc.
|
|||
|
pld restore direct register.
|
|||
|
pla fix stack because handle and userid
|
|||
|
pla still on stack.
|
|||
|
pea $0003 now delete the message (done with it).
|
|||
|
pea $0001 message type 1.
|
|||
|
pha garbage handle (not used).
|
|||
|
pha
|
|||
|
_MessageCenter go delete the message.
|
|||
|
L6203 _DisposeHandle throw away message (handle is on stack)
|
|||
|
L620A _MMShutDown shutdown the memory manager (userid is
|
|||
|
sec on stack).
|
|||
|
xce back to emulation mode.
|
|||
|
LONGA OFF
|
|||
|
pla condition z-flag with value on stack.
|
|||
|
bne L6231 then done.
|
|||
|
ldx inbuf get length of pathname.
|
|||
|
lda #$2F look for slash.
|
|||
|
L621B cmp inbuf,x
|
|||
|
beq L6225 when found, set prefix.
|
|||
|
dex
|
|||
|
bne L621B
|
|||
|
bra L6231 if no slash, just skip it.
|
|||
|
L6225 dex don't include trailing slash.
|
|||
|
stx inbuf set new length.
|
|||
|
jsr MLI set the P8 prefix.
|
|||
|
dc i1'$C6'
|
|||
|
dc i2'pfxparms'
|
|||
|
lda #$00 set z-flag
|
|||
|
L6231 rts and go launch the app.
|
|||
|
|
|||
|
* check for disk volume
|
|||
|
*
|
|||
|
* on exit:
|
|||
|
* carry clear = disk was found
|
|||
|
* carry set = disk not found
|
|||
|
|
|||
|
ckfordrv .EQ *-ofsQ
|
|||
|
clc native mode
|
|||
|
xce
|
|||
|
LONG I 16-bit regs, 8-bit acc.
|
|||
|
ldx #sysentry+6 point to pathname buffer.
|
|||
|
jsr copyvol copy volume name to pathname buffer.
|
|||
|
L623C sec emulation mode.
|
|||
|
xce
|
|||
|
jsr MLI get info on the volume.
|
|||
|
dc i1'$C4'
|
|||
|
dc i2'gfiparms'
|
|||
|
bcc L6252 branch if volume found,
|
|||
|
clc (native mode)
|
|||
|
xce
|
|||
|
LONG I,M
|
|||
|
jsr mountvol else ask user to mount the volume.
|
|||
|
bcc L623C if <return> pressed, then try again.
|
|||
|
sec emulation mode.
|
|||
|
xce
|
|||
|
sec disk not found.
|
|||
|
L6252 rts
|
|||
|
|
|||
|
* Prodos 8 parameter lists
|
|||
|
|
|||
|
pfxparms .EQ *-ofsQ set prefix parms.
|
|||
|
dc h'01' one parm.
|
|||
|
dc i2'inbuf' address of prefix.
|
|||
|
opnparms .EQ *-ofsQ open parms.
|
|||
|
dc h'03' 3 parms.
|
|||
|
dc i2'PrefixBuf' pathname
|
|||
|
dc i2'op_buf' i/o buffer
|
|||
|
oprefnum .EQ *-ofsQ
|
|||
|
dc h'00' reference #
|
|||
|
eofparms .EQ *-ofsQ
|
|||
|
dc h'02' 2 parms
|
|||
|
eofrefn .EQ *-ofsQ
|
|||
|
dc h'00' reference #
|
|||
|
eofval .EQ *-ofsQ
|
|||
|
dc h'000000' 3 byte eof value
|
|||
|
readparm .EQ *-ofsQ
|
|||
|
dc h'04' 4 parms
|
|||
|
rdrefnum .EQ *-ofsQ
|
|||
|
dc h'00' reference #
|
|||
|
dc i2'sysentry' read into $2000 (bank 0).
|
|||
|
rdcount .EQ *-ofsQ
|
|||
|
dc h'0000' # of bytes to read.
|
|||
|
dc h'0000' transfer count
|
|||
|
closeprm .EQ *-ofsQ
|
|||
|
dc h'01' 1 parm
|
|||
|
closeref .EQ *-ofsQ
|
|||
|
dc h'00' reference #
|
|||
|
quitparms .EQ *-ofsQ
|
|||
|
dc h'04' 4 parms.
|
|||
|
dc h'00' quit back to launcher (GQuit)
|
|||
|
dc h'0000'
|
|||
|
dc h'00'
|
|||
|
dc h'0000'
|
|||
|
gfiparms .EQ *-ofsQ get file info parms.
|
|||
|
dc h'0A' 10 parms
|
|||
|
dc i2'volbuf' volume buffer
|
|||
|
dc h'00' access
|
|||
|
dc h'00' file type
|
|||
|
dc h'0000' aux type
|
|||
|
dc h'00' storage type
|
|||
|
dc h'0000' blocks used
|
|||
|
dc h'0000' modification date
|
|||
|
dc h'0000' modification time
|
|||
|
dc h'0000' creation date
|
|||
|
dc h'0000' creation time
|
|||
|
|
|||
|
* messages for P8 fatal error. maximum length of message is 35 characters.
|
|||
|
* the error code will be displayed immediately after the final character.
|
|||
|
|
|||
|
quitstr1 .EQ *-ofsQ
|
|||
|
dc h'1B'
|
|||
|
dc c'Can''t run next application.'
|
|||
|
quitstr2 .EQ *-ofsQ
|
|||
|
dc h'14'
|
|||
|
dc c'ProDOS Error = $'
|
|||
|
errval .EQ *-ofsQ hex error code gets stored here
|
|||
|
dc c' '
|
|||
|
quitbtn2 .EQ *-ofsQ null string (no 2nd button)
|
|||
|
dc h'00'
|
|||
|
|
|||
|
* messages for P8 mount volume. maximum length of message is 35 characters.
|
|||
|
* the button labels must not be more than 16 characters.
|
|||
|
|
|||
|
mountmsg .EQ *-ofsQ
|
|||
|
dc h'17'
|
|||
|
dc c'Please insert the disk:'
|
|||
|
button1 .EQ *-ofsQ
|
|||
|
dc h'0D'
|
|||
|
dc c'Accept: '
|
|||
|
dc h'1B' mousetext on
|
|||
|
dc h'0F' inverse on
|
|||
|
dc h'4D' mousetext return
|
|||
|
dc h'0E' normal on
|
|||
|
dc h'18' mousetext off
|
|||
|
button2 .EQ *-ofsQ
|
|||
|
dc h'0B'
|
|||
|
dc c'Cancel: Esc'
|
|||
|
|
|||
|
* end of obj sel_2 (must be < GQdisp+$300)
|
|||
|
*--------------------------------------
|
|||
|
MAN
|
|||
|
LOAD USR/SRC/PRODOS/PRODOS.S.SEL2
|
|||
|
SAVE USR/SRC/PRODOS/PRODOS.S
|
|||
|
ASM
|