mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-24 22:02:28 +00:00
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.
1 line
24 KiB
Plaintext
1 line
24 KiB
Plaintext
string asis
|
|
blanks off
|
|
|
|
print push
|
|
print off
|
|
include 'common.equ.src'
|
|
print pop,nogen,nopage,nohdr
|
|
|
|
;====================================================================================================
|
|
;
|
|
;Fast.Access: This setup file will speed up file writes to the console driver.
|
|
;
|
|
;Created: June 25, 1989
|
|
;Modified: June 28, 1989
|
|
;Author: Rob Turner
|
|
;
|
|
;Modified: August 7, 1989
|
|
;Modifier: Greg Branche
|
|
;
|
|
; At @call_console_fast, the code now checks whether it's handing a read call or a write
|
|
; call. If it's a read call, it skips the modification to the JSR SIGNAL instruction. In
|
|
; other words, the call to the signal handler only get's patched out during a driver write
|
|
; call. This allows Rob's improved console driver to continue working with this speed-up
|
|
; init file. (His modification to the User Input Routine (UIR) implemented a method of
|
|
; using the signal handler so that the CDA menu was still accessible while waiting for
|
|
; input in the UIR.)
|
|
;
|
|
;Modified: August 25, 1989
|
|
;Modifier: Greg Branche
|
|
;
|
|
; When verifying the device characteristics, the code masks the 'Fixed Name' bit, since
|
|
; it's not important, and the value of that bit has changed since System Disk 5.0.
|
|
;
|
|
;Modified: July 3, 1990
|
|
;Modifier Greg Branche
|
|
;
|
|
; Updated addresses, version numbers, and code for use with GS/OS version 3.03 (System
|
|
; disk 5.0.3).
|
|
;
|
|
;====================================================================================================
|
|
|
|
go_main proc
|
|
import main
|
|
jmp main
|
|
endp
|
|
|
|
;====================================================================================================
|
|
;equates used by fast access. The following address MUST be changed if GS/OS is changed!!!!
|
|
;====================================================================================================
|
|
|
|
OSVersNum equ $0303 ;OS Version number required
|
|
ConsVersNum equ $3010 ;Console driver version number
|
|
|
|
return_address equ $00D5BD ;address we return to after call.
|
|
return_check equ $2BAB
|
|
entry_type equ $00A025 ;Better be there
|
|
patch_address equ $00D5A0 ;address in Language card
|
|
patch_check1 equ $3A22 ;patch value = JSL 00B73A
|
|
patch_check2 equ $00B7
|
|
|
|
signal_patch equ $009EC9 ;Address of signal dispatch.
|
|
signal_check1 equ $AB20 ;"JSR $ECAB" SEP #$20
|
|
signal_check2 equ $E2EC
|
|
TwoNOPs equ $EAEA ;Two NOP instructions
|
|
|
|
INCBusyPatch equ $009E38 ;Address of INC Busy call in the OS
|
|
INCBusyCheck equ $6422 ;Part of JSL $E10064
|
|
|
|
DECBusyPatch equ $009EC0 ;Address of DEC Busy call in the OS!
|
|
DECBusyCheck equ $6822 ;Part of JSL $E10068
|
|
IncDecCommon equ $E100 ;High word of JSL $E10068 = 22 68 00 E1
|
|
|
|
UnlockPatch equ $00D5B9 ;Address in LC of call to Force Unlock.
|
|
UnlockCheck1 equ $4222 ;Part of JSL $00B742 = 22 42 B7 00
|
|
UnlockCheck2 equ $00B7 ;Second Part of above JSL
|
|
OSUnlockRoutine equ $00B742
|
|
OSLockRoutine equ $00B73A
|
|
|
|
inc_busy_flag equ $E10064 ;address of inc_busy_flag call
|
|
dec_busy_flag equ $E10068 ;address of dec_busy_flag call
|
|
|
|
|
|
call_block equ $D4
|
|
temp_error equ $00A02E ;error code returned to caller
|
|
|
|
do_Unlock equ $0000
|
|
do_DEC_Busy equ $0000
|
|
|
|
No_DEC_Busy equ $0001 ;BIT set = No DEC Busy flag
|
|
No_UnLock equ $8000 ;BIT set = No_Unlock memory
|
|
|
|
;====================================================================================================
|
|
;Macros used by FastAccess
|
|
;====================================================================================================
|
|
|
|
MACRO
|
|
&lab _GSOSCall ¶m1,¶m2
|
|
&lab jsl $E100A8
|
|
DC.W ¶m1
|
|
DC.L ¶m2
|
|
MEND
|
|
|
|
open equ $2010
|
|
close equ $2014
|
|
DControl equ $202E
|
|
GetDevNum equ $2020
|
|
Version equ $202A
|
|
AddNotifyProc equ $2034
|
|
DInfo equ $202C
|
|
|
|
;====================================================================================================
|
|
;Local Data used by FastAccess
|
|
;====================================================================================================
|
|
Console_Dev_Num record
|
|
dc.w 00 ;Device number of the Console Driver
|
|
endr
|
|
|
|
;====================================================================================================
|
|
;entry_patch: This routine is called by GS/OS at the at the beginning of the OS call.
|
|
;
|
|
;Input: A = saved
|
|
; X = saved
|
|
; Y = saved
|
|
; P = saved
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = restored
|
|
; X = restored
|
|
; Y = restored
|
|
; P = restored
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
entry_patch proc
|
|
|
|
user_stack equ $48
|
|
|
|
phb
|
|
|
|
lda >entry_type ;prepare to get call_num and parm_block
|
|
beq lc_stack_entry ;processing differs by inline vs. stack
|
|
|
|
entry lc_inline_entry
|
|
lc_inline_entry ldy #3 ;set up pointer to 1 byte below call_num
|
|
lda [<user_stack],y ;user return address in user stack ...
|
|
sta <call_block ;... is the proper value
|
|
iny
|
|
lda [<user_stack],y
|
|
sta <call_block+1
|
|
bra get_parms
|
|
|
|
entry lc_stack_entry
|
|
lc_stack_entry clc ;set up pointer to 1 byte below call_num
|
|
lda <user_stack
|
|
adc #5 ;address of location 5 bytes above user
|
|
sta <call_block ;... stack pointer is the right value
|
|
stz <call_block+2
|
|
|
|
get_parms ldy #1 ;call_number to GS/OS direct page
|
|
lda [<call_block],y
|
|
sta <call_number
|
|
tax
|
|
|
|
ldy #3 ;param_blk_ptr to GS/OS direct page
|
|
lda [<call_block],y
|
|
sta <param_blk_ptr
|
|
ldy #5
|
|
lda [<call_block],y
|
|
sta <param_blk_ptr+2 ;Now PUSH the Parameter block pointer BANK
|
|
;
|
|
;Set flag that says "Do not Call ForceUnlock and Do not call DEC Busy"
|
|
;
|
|
lda #No_Unlock+No_DEC_Busy
|
|
sta >LockFlag_and_DECFlag
|
|
;
|
|
;Now check for a CONSOLE write call.
|
|
;
|
|
ldy #$0002 ;setup for class 1 write call
|
|
txa
|
|
cmp #$2013 ;is the call a write call?
|
|
beq @chk_if_console
|
|
|
|
ldy #$0000 ;setup for class 0 write call
|
|
cmp #$0013
|
|
beq @chk_if_console
|
|
;
|
|
;Now check to see if we are doing a DRead or DWrite call. IF we are doing DRead or DWrite
|
|
;Then DO NOT do ForceLock/Unlock or INC/DEC busy flag.
|
|
;
|
|
@check_DRead
|
|
cmp #$202F
|
|
bne @check_DWrite
|
|
lda #drvr_read
|
|
sta drvr_call_num ;setup the call number
|
|
bra @dev_common ;see if the device is the CONSOLE
|
|
@check_DWrite
|
|
cmp #$2030
|
|
bne @chk_close ;see if a close call is being made.
|
|
|
|
lda #drvr_write
|
|
sta drvr_call_num ;setup for Device Write
|
|
@dev_common
|
|
lda [param_blk_ptr] ;Check the PCount
|
|
cmp #$0006
|
|
bne @call_os ;Punt
|
|
|
|
ldy #$0002 ;see if this is the console driver please
|
|
lda [param_blk_ptr],y ;get the device number
|
|
cmp >console_dev_num ;is it the console!
|
|
beq @do_fast_console ;yes so do it fast!
|
|
plb
|
|
rtl ;NOT .CONSOLE but skip Lock/Unlock and INC/DEC Busy.
|
|
;
|
|
;Now see if we are making a close call. If so then zero out our check reference number
|
|
;and call the OS!
|
|
|
|
@chk_close
|
|
and #$00FF
|
|
cmp #$0014
|
|
bne @call_os ;do a standard OS call.
|
|
lda #'RT'
|
|
sta >console_ref ;enable search please
|
|
|
|
@call_os
|
|
jsl inc_busy_flag ;Do INC Busy Flag
|
|
jsl OSLockRoutine ;Do a ForceHandleLock Call
|
|
lda #Do_DEC_busy+Do_Unlock ;set flag that indicates we should "unLockHandle" and
|
|
;do a DEC Busy Flag
|
|
sta >LockFlag_and_DECFlag
|
|
;
|
|
;Restore "JSR Signal_dispatch" code in GS/OS, We may have trashed on on Console Write.
|
|
;
|
|
lda #signal_check1 ;restore orignal GS/OS code
|
|
sta >signal_patch
|
|
lda #signal_check2
|
|
sta >signal_patch+2
|
|
plb
|
|
rtl
|
|
@chk_if_console
|
|
lda #drvr_write ;we only call on write calls.
|
|
sta drvr_call_num ;setup the call number
|
|
|
|
lda [param_blk_ptr],y ;get the reference number
|
|
tax
|
|
;
|
|
;Setup the drvr_buf_ptr
|
|
;
|
|
@do_fast_console
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y
|
|
sta drvr_buf_ptr
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y
|
|
sta drvr_buf_ptr+2
|
|
;
|
|
;Setup the request count please
|
|
;
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y
|
|
sta drvr_req_cnt
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y
|
|
sta drvr_req_cnt+2
|
|
|
|
stz drvr_blk_num
|
|
stz drvr_blk_num+2
|
|
stz drvr_tran_cnt
|
|
stz drvr_tran_cnt+2
|
|
stz drvr_blk_size
|
|
|
|
lda <call_number ;is this a file write call
|
|
cmp #$202F ;IF < DRead then Must be Write Call
|
|
bcc @do_FILE_stuff
|
|
;
|
|
;IF here then we need to verify that the Starting Block is zero and the block num is zero
|
|
;
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y
|
|
iny
|
|
iny
|
|
ora [param_blk_ptr],y
|
|
bne @call_os ;let the OS fail
|
|
|
|
iny
|
|
iny
|
|
lda [param_blk_ptr],y ;check the block size
|
|
bne @call_os
|
|
;
|
|
;For DRead and DWrite we want the BUSY flag to work, so handle it here.
|
|
;
|
|
lda #do_DEC_Busy+No_Unlock ;Force DEC busy on exit.
|
|
sta >LockFlag_and_DECFlag
|
|
jsl inc_busy_flag ;Go ahead and do a INC busy
|
|
bra @call_console_fast
|
|
|
|
@do_FILE_stuff
|
|
txa ;get the reference number again
|
|
cmp >console_ref ;is it the console's reference number?
|
|
beq @call_console_fast ;Make this puppy fly!!!
|
|
|
|
jsl find_fcr ;get the file control record
|
|
bcs @call_os
|
|
jsl deref ;get me a real pointer please
|
|
stx call_block
|
|
sty call_block+2
|
|
|
|
ldy #fcr_fst_id
|
|
lda [call_block],y
|
|
cmp #$0009 ;character FST
|
|
bne @to_call_os ;cannot be console driver!
|
|
ldy #fcr_access+2
|
|
lda [call_block],y ;get the device number
|
|
cmp >console_dev_num
|
|
beq @get_ref
|
|
@to_call_os
|
|
brl @call_os ;it is not the console driver
|
|
@get_Ref
|
|
lda [call_block] ;get the reference number
|
|
sta >console_ref ;save for next time
|
|
|
|
@call_console_fast
|
|
;
|
|
;Replace "JSR Signal_Dispatch" with NOPs only if writing to the driver
|
|
;(reading from .CONSOLE requires the signal handler to be working properly)
|
|
;
|
|
ldx drvr_call_num ;get the call number
|
|
cpx #drvr_read ;reading?
|
|
beq @skip_signal_patch ;yes, skip the signal patching
|
|
|
|
lda #TwoNOPS ;Trash Signal Dispatch on exit please
|
|
sta >signal_patch
|
|
sta >signal_patch+1
|
|
|
|
@skip_signal_patch
|
|
lda >console_dev_num
|
|
sta drvr_dev_num
|
|
|
|
; lda drvr_call_num ;used as input to the console driver
|
|
txa ;drvr_call_num is still in X register
|
|
export console_address
|
|
console_address jsl $0000000 ;call the console driver please A=call number!!
|
|
bcs @oops ;had an error!
|
|
lda #$0000 ;else make sure the accumulator is clear
|
|
@oops
|
|
rol a ;save carry in low bit of temp_error
|
|
sta >temp_error
|
|
bcs @error
|
|
;
|
|
;Now we need to send the Transfer count to the caller.
|
|
;
|
|
ldy #$000A
|
|
lda <call_number ;is this a file write call
|
|
cmp #$0013 ;Class 0 write call.
|
|
beq @do_XFer_cnt
|
|
|
|
cmp #$2013 ;Write call
|
|
bne @DType_Call
|
|
|
|
ldy #$000C
|
|
lda [param_blk_ptr] ;Check the PCount for Class 1 write call
|
|
cmp #$0004
|
|
bcc @error ;Sorry the PCount DOES NOT include TRANSFER Count
|
|
bra @do_XFer_cnt
|
|
|
|
@DType_Call
|
|
ldy #$0012
|
|
@do_XFer_cnt
|
|
lda drvr_tran_cnt
|
|
sta [param_blk_ptr],y
|
|
iny
|
|
iny
|
|
lda drvr_tran_cnt+2
|
|
sta [param_blk_ptr],y
|
|
@error
|
|
plb ;fix the stack please
|
|
pla ;pull off the return address!!
|
|
sep #$20
|
|
pla
|
|
rep #$20
|
|
jml return_address ;return to SCM with error stuff.
|
|
|
|
;====================================================================================================
|
|
;This routine is called to do the DEC Busy Routine!!
|
|
;
|
|
; IF the LOW Bit of LockFlag_and_DECFlag is set then we just EXIT otherwise dec_Busy_Flag
|
|
;
|
|
;====================================================================================================
|
|
|
|
export DECBusyEntry
|
|
DECBusyEntry
|
|
lda >LockFlag_and_DECFlag ;see if we should do a DEC Busy Flag
|
|
lsr a
|
|
bcc @do_Dec_busy
|
|
rtl
|
|
@do_Dec_busy
|
|
jml dec_busy_flag ;returns to the OS
|
|
|
|
;====================================================================================================
|
|
;This routine is called to do the ForceUnlock Routine!!
|
|
;
|
|
; IF the HIGH Bit of LockFlag_and_DECFlag is set then we just EXIT otherwise UNLOCK
|
|
;
|
|
;====================================================================================================
|
|
export ForceUnlockEntry
|
|
ForceUnlockEntry
|
|
lda >LockFlag_and_DECFlag ;see if we should do a DEC Busy Flag
|
|
bpl @do_forceUnlock
|
|
rtl ;skip Unlock
|
|
@do_forceUnlock
|
|
jml OSUnlockRoutine ;Call original
|
|
|
|
console_ref dc.w 'RT'
|
|
LockFlag_and_DECFlag dc.w $00
|
|
endp ;return to GS/OS
|
|
|
|
|
|
;====================================================================================================
|
|
;resize_handle: This routine shrinks the handle size and returns to GS/OS
|
|
;
|
|
;Input: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
resize_handle proc
|
|
|
|
my_handle equ $00
|
|
|
|
php
|
|
sei ;Kill interrupts
|
|
|
|
pha ;space for result
|
|
pha
|
|
|
|
pea resize_handle>>16
|
|
pea resize_handle ;our own address
|
|
|
|
ldx #$1A02
|
|
jsl $e10000 ;FindHandle
|
|
plx
|
|
ply ;get the handle
|
|
bcs @exit
|
|
bne @have_handle
|
|
txa
|
|
beq @exit ;handle is NIL so exit.
|
|
@have_handle
|
|
stx my_handle
|
|
sty my_handle+2
|
|
|
|
ldy #$0004 ;unlock my handle
|
|
lda [my_handle],y
|
|
and #$7FFF
|
|
sta [my_handle],y
|
|
|
|
pea $0000 ;high word
|
|
lda new_size
|
|
pha
|
|
pei my_handle+2
|
|
pei my_handle
|
|
ldx #$1902
|
|
jsl $e10000 ;Set Handle Size
|
|
bcs @exit
|
|
|
|
ldy #$0004 ;unlock my handle
|
|
lda [my_handle],y
|
|
ora #$8000 ;lock the handle
|
|
sta [my_handle],y
|
|
@exit
|
|
plp ;restore interrupt state.
|
|
rtl
|
|
|
|
new_size dc.w resize_handle-go_main
|
|
|
|
endp
|
|
|
|
Console_Name record
|
|
dc.w $08
|
|
dc.b '.CONSOLE'
|
|
endr
|
|
|
|
;====================================================================================================
|
|
;check_os_version: This routine makes sure we are using GS/OS version 3.0 only.
|
|
;
|
|
;Input: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = OS Version number
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000..1 = bad OS version
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
check_os_version proc
|
|
|
|
_GSOSCall Version,VersionList
|
|
bcs @error_exit
|
|
|
|
lda OSVersion
|
|
and #$7FFF ;clear the proto bit.
|
|
cmp #OSVersNum
|
|
bne @error_exit
|
|
clc
|
|
rts
|
|
@error_exit
|
|
sec
|
|
rts
|
|
|
|
;*************************************************************************************************
|
|
;************************ Local Variables used by this routine ***********************************
|
|
;*************************************************************************************************
|
|
|
|
VersionList dc.w $0001 ;PCount for the call
|
|
OSVersion dc.w 0000 ;The result
|
|
|
|
endp
|
|
;====================================================================================================
|
|
;trap_handler: This routine is called directly by the console driver!
|
|
;
|
|
;Input: A = call number
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = console driver bank.
|
|
;
|
|
;
|
|
;Output: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = console driver bank
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
trap_handler proc
|
|
php
|
|
pha
|
|
;
|
|
;Picture of the stack:
|
|
;
|
|
; --------------
|
|
; A Register $0001
|
|
; --------------
|
|
; Process $0003
|
|
; --------------
|
|
; Return addr $0004
|
|
; --------------
|
|
;
|
|
sec
|
|
lda 4,s ;get the return address
|
|
sbc #$0003 ;get address of Vector call routine!
|
|
tax
|
|
lda 6,s
|
|
and #$00FF
|
|
sbc #$0000
|
|
;
|
|
;Console_Address jsl $000000 ;call console
|
|
;
|
|
; $22 00 00 00
|
|
;
|
|
xba ;put bank address in high byte of accum.
|
|
sta >console_address+2
|
|
txa ;low 16 bits of console address.
|
|
sta >console_address+1
|
|
|
|
pla ;restore A register and flags
|
|
plp
|
|
rtl
|
|
endp ;let the call continue please
|
|
|
|
;====================================================================================================
|
|
;get_console_entry: This routine will setup the console driver device Number and setup
|
|
; the console driver patch.
|
|
;
|
|
;Input: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000..1 = error
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
get_console_entry proc
|
|
;
|
|
;Before we can use the console driver we must open it first
|
|
;
|
|
_GSOSCall open,OpenList
|
|
bcs @exit ;Holy Cow BatMan!
|
|
|
|
lda ref_num ;setup reference number for the close call.
|
|
sta close_ref
|
|
|
|
;
|
|
;Now lets get the device number setup please.
|
|
;
|
|
|
|
_GSOSCall GetDevNum,GetDevList
|
|
bcs @close_and_exit
|
|
|
|
lda ret_dev_num ;Device number returned by the call.
|
|
sta console_dev_num ;save number for Global use
|
|
sta ctrl_dev_num ;used for DControl Calls
|
|
sta DInfo_dev_num ;used for DInfo call to console!
|
|
;
|
|
;Lets make sure that the console driver we are using is the one we think it is.
|
|
;
|
|
jsr check_cons_version
|
|
bcs @close_and_exit
|
|
|
|
;
|
|
;Issue a reset_trap call to the console driver. This will nuke anyones installed handler
|
|
;
|
|
stz request_count ;zero request count for this call
|
|
lda #$8007 ;reset trap address
|
|
sta ctrl_code
|
|
_GSOSCall DControl,DCtrlList
|
|
bcs @close_and_exit ;This call should not fail
|
|
;
|
|
;Add in my console driver handling routine.
|
|
;
|
|
lda #$0004 ;setup the request count
|
|
sta request_count
|
|
lda #$8006 ;Add_Trap address
|
|
sta ctrl_code
|
|
_GSOSCall DControl,DCtrlList
|
|
bcs @close_and_exit
|
|
;
|
|
;Reset the handler again. Note: this call will cause our Trap_Handler to be called, then
|
|
; removed, hows that for trickyness!!
|
|
;
|
|
stz request_count ;zero request count for this call
|
|
lda #$8007 ;reset trap address
|
|
sta ctrl_code
|
|
_GSOSCall DControl,DCtrlList
|
|
|
|
@close_and_exit
|
|
php
|
|
pha ;save error code if any
|
|
_GSOSCall close,CloseList
|
|
pla
|
|
plp
|
|
@exit
|
|
rts
|
|
|
|
check_cons_version
|
|
_GSOSCall DInfo,DInfoList
|
|
bcs @error_out
|
|
|
|
lda dev_char ;check the characteristics
|
|
and #%1111101111111111 ;doesn't matter whether the name is fixed or not (gab)
|
|
cmp #$0B60
|
|
bne @error_out ;sorry I don't know this console
|
|
lda slot_num
|
|
cmp #$8003 ;fake slot 3
|
|
bne @error_out
|
|
lda unit_num
|
|
dec a
|
|
bne @error_out ;we want unit 1
|
|
lda con_version ;we patch only if console is version 3.01
|
|
and #$FFF0 ;don't care about alpha, beta, or whatever
|
|
cmp #ConsVersNum
|
|
bne @error_out
|
|
lda dev_id
|
|
cmp #$000A ;check the device ID as well.
|
|
bne @error_out
|
|
|
|
clc
|
|
rts
|
|
@error_out
|
|
sec
|
|
rts
|
|
|
|
;*************************************************************************************************
|
|
;************************ Local Variables used by this routine ***********************************
|
|
;*************************************************************************************************
|
|
|
|
DInfoList dc.w $0008 ;PCount
|
|
DInfo_dev_num dc.w 000
|
|
dc.l name_buffer
|
|
dev_char dc.w 00 ;device characteristics
|
|
dc.l 00 ;total blocks
|
|
slot_num dc.w 00
|
|
unit_num dc.w 00
|
|
con_version dc.w 00 ;Console Version Number
|
|
dev_id dc.w 00 ;Device ID
|
|
|
|
name_buffer dc.w $000C
|
|
name_size dc.w 0000
|
|
dc.b '.CONSOLE' ;This will get over written at runtime.
|
|
|
|
|
|
GetDevList dc.w $0002 ;PCount
|
|
dc.l console_name ;pointer to the name ".CONSOLE"
|
|
ret_dev_num dc.w 00 ;resulting device number
|
|
|
|
DCtrlList dc.w $0005 ;PCount
|
|
ctrl_dev_num dc.w 00 ;Device number of .CONSOLE
|
|
ctrl_code dc.w 00 ;Call I wish to make
|
|
dc.l control_list ;pointer to the control data
|
|
request_count dc.l 00 ;number of bytes used
|
|
dc.l 00 ;transfer count
|
|
|
|
Control_list dc.l trap_handler ;address of routine to get data
|
|
|
|
OpenList dc.w $0002 ;PCount
|
|
Ref_Num dc.w 000 ;ref num of console driver
|
|
dc.l console_name
|
|
|
|
CloseList dc.w $0001
|
|
close_ref dc.w 000
|
|
endp
|
|
|
|
|
|
|
|
;====================================================================================================
|
|
;patch_os: This routine sets up a patch in the OS. The patch will allow us to get control
|
|
; Before we have gone to far into an OS call
|
|
;
|
|
;Input: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000..1 = error
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
patch_os proc
|
|
|
|
statereg equ $c068 ;state register
|
|
lcbank2 equ $c083 ;sel LC ram bank2, 2 rds wrt enb LC ram
|
|
lcbank1 equ $c08b ;sel LC ram bank1, 2 rds wrt enb LC ram
|
|
|
|
|
|
longa off
|
|
sep #$20
|
|
lda >statereg ;save current language card state
|
|
sta lc_state
|
|
lda >lcbank1 ;select and write enable language ...
|
|
lda >lcbank1 ;... card RAM bank 1 (really 0)
|
|
longa on
|
|
rep #$20
|
|
|
|
lda >patch_address ;see if this is OK to patch
|
|
cmp #patch_check1
|
|
bne @error_exit
|
|
lda >patch_address+2
|
|
cmp #patch_check2
|
|
bne @error_exit
|
|
|
|
;
|
|
;Check the INC Busy Call
|
|
;
|
|
lda >INCBusyPatch ;is this right!
|
|
cmp #INCBusyCheck
|
|
bne @error_exit ;Sorry NO GO
|
|
;
|
|
;Check the DEC Busy routine.
|
|
;
|
|
lda >DECBusyPatch
|
|
cmp #DECBusyCheck
|
|
bne @error_exit ;Sorry NO GO
|
|
;
|
|
;Check the FORCEUNLOCK call
|
|
;
|
|
lda >UnLockPatch
|
|
cmp #UnlockCheck1
|
|
bne @error_exit
|
|
lda >UnlockPatch+2
|
|
cmp #UnlockCheck2
|
|
bne @error_exit
|
|
|
|
;
|
|
;Check the return address to make sure we are OK
|
|
;
|
|
lda >return_address ;make sure the return code is still there!!
|
|
cmp #$2BAB ;should be a PLB PLD
|
|
bne @error_exit ;we cannot patch it!
|
|
|
|
lda >signal_patch
|
|
cmp #signal_check1
|
|
bne @error_exit
|
|
lda >signal_patch+2
|
|
cmp #signal_check2
|
|
beq @patch_it
|
|
@error_exit
|
|
sec ;set error condition
|
|
bra @exit
|
|
|
|
@patch_it
|
|
;
|
|
;It all passes so lets patch the OS please.
|
|
;
|
|
|
|
lda patch1 ;install entry patch please
|
|
sta >patch_address
|
|
lda patch1+2
|
|
sta >patch_address+2
|
|
;
|
|
;Install ForceUnlock patch
|
|
;
|
|
lda UnlockJSL
|
|
sta >UnlockPatch
|
|
lda UnlockJSL+2
|
|
sta >UnlockPatch+2
|
|
;
|
|
;Install DECBusy Patch
|
|
;
|
|
lda DECBusyJSL
|
|
sta >DECBusyPatch
|
|
lda DECBusyJSL+2
|
|
sta >DECBusyPatch+2
|
|
;
|
|
;NOP out the JSL INCBusy
|
|
;
|
|
lda #TwoNOPS
|
|
sta >INCBusyPatch
|
|
sta >INCBusyPatch+2
|
|
|
|
clc
|
|
bra @exit
|
|
|
|
@exit
|
|
pha
|
|
php
|
|
|
|
lda lc_state
|
|
sep #$20
|
|
sta >statereg ;restore langauge card setting
|
|
rep #$20
|
|
|
|
plp
|
|
pla
|
|
rts
|
|
|
|
;*************************************************************************************************
|
|
;************************ Local Variables used by this routine ***********************************
|
|
;*************************************************************************************************
|
|
|
|
lc_state dc.w 00
|
|
patch1 jsl entry_patch ;put in patch to our code
|
|
UnlockJSL jsl ForceUnlockEntry
|
|
DECBusyJSL jsl DECBusyEntry
|
|
endp
|
|
|
|
|
|
;====================================================================================================
|
|
;main: This is the main entry point to the program, it is called when we get loaded.
|
|
; Note that it is NOT called on each OS call.
|
|
;
|
|
;Input: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;Output: A = undefined
|
|
; X = undefined
|
|
; Y = undefined
|
|
; P = nvmxdizc
|
|
; ..000...
|
|
; b = k
|
|
;
|
|
;
|
|
;====================================================================================================
|
|
longa on
|
|
longi on
|
|
main proc
|
|
|
|
phk ;you know the story here.
|
|
plb
|
|
|
|
jsr check_os_version ;are we running GS/OS version 3.0?
|
|
bcs @version_exit ;I cannot patch the OS.
|
|
jsr get_console_entry ;get the console driver's dev num and entry
|
|
bcs @unload_exit
|
|
jsr patch_os
|
|
bcs @unload_exit
|
|
jmp resize_handle ;Shrink and Exit!!!!
|
|
|
|
@version_exit
|
|
cmp #$0300
|
|
bcc @exit ;IF greater > 3.0 then purge me, else exit.
|
|
@unload_exit
|
|
lda #$0001
|
|
sta 4,s ;set the unload flag for GQuit
|
|
@exit
|
|
rtl ;return with Unload request!!
|
|
|
|
endp
|
|
end
|
|
|