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
7.9 KiB
Plaintext
1 line
7.9 KiB
Plaintext
TITLE ', JUMP.a - JumpLoad'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Jump Table Load ($15)
|
|
*
|
|
* Inputs: UserID (2 bytes)
|
|
* Load File Number (2 bytes)
|
|
* Load Segment Number (2 bytes)
|
|
* Load Segment Offset (4 bytes)
|
|
*
|
|
* inputs are 'not' on stack but can found by tracing
|
|
* the return address back to the calling location. They
|
|
* are in locations before the JSL.
|
|
*
|
|
* Outputs: none
|
|
* Errors: $0000 - Operation successful
|
|
* $1101 - Segment not found
|
|
* $1102 - Segment not dynamic
|
|
* $1104 - File not Load File
|
|
* $00xx - ProDOS I/O error
|
|
* $02xx - Memory Manager error
|
|
*
|
|
****************************************************************
|
|
*
|
|
JumpLoad PROC
|
|
LoadSegCheck
|
|
|
|
with DirectPage, Globals
|
|
Import reset_local_mark,find_user_id,merge_path_2, \
|
|
lock_segment,open_load_file,error_routine, \
|
|
lock_handles,unlock_handles,load_segment, \
|
|
Process_Reloc,close_load_file
|
|
;
|
|
; the stack looks like this at entry:
|
|
;
|
|
; (previous contents)
|
|
; return to Jump Table entry (3 bytes)
|
|
; top of stack
|
|
;
|
|
php ;save user's P-register
|
|
phb ;save user's DBR
|
|
phk ;set to our bank
|
|
plb
|
|
;
|
|
; Now, the stack looks like this:
|
|
;
|
|
; (previous contents)
|
|
; return to Jump Table entry (3 bytes)
|
|
; user's processor status (1 byte)
|
|
; user's Data Bank Register (1 byte)
|
|
; top of stack
|
|
;
|
|
rep #$30 ;ensure 16-bit mode
|
|
|
|
sta save_a
|
|
stx save_x
|
|
sty save_y ;save app's registers
|
|
|
|
plx ;get the processor status + Bank register
|
|
pla ;get the low word of the return address
|
|
sta starting_addr
|
|
|
|
sep #$20 ;8 bit mode
|
|
pla
|
|
sta starting_addr+2 ;store the bank byte of the return address
|
|
stz starting_addr+3
|
|
rep #$20 ;16 bit
|
|
phx ;put status and DBR back on stack
|
|
|
|
phd ;save user's direct page
|
|
lda my_dir_page ;set to my direct page
|
|
tcd
|
|
|
|
;
|
|
; Now, the stack looks like this:
|
|
;
|
|
; (previous contents)
|
|
; user's processor status (1 byte)
|
|
; user's Data Bank Register (1 byte)
|
|
; user's Direct Register (2 bytes)
|
|
; top of stack
|
|
|
|
jsl incbusyflg
|
|
|
|
sep #$20 ;8-bit mode
|
|
lda >statereg ;get current value
|
|
sta save_statereg
|
|
lda >$E0C08B ;shift in language-card memory
|
|
lda >$E0C08B
|
|
rep #$20 ;back to 16-bit mode
|
|
|
|
; Now that we've saved the user's environment, we can get down to the real work
|
|
|
|
jsr reset_local_mark
|
|
|
|
sec
|
|
lda starting_addr ;build a pointer to the start of the info
|
|
sbc #jmp_entry_size-1
|
|
sta jmp_tbl_ptr
|
|
lda starting_addr+2
|
|
sbc #$0000
|
|
sta jmp_tbl_ptr+2 ;temp_ptr points to Jump Table Entry
|
|
|
|
lda [jmp_tbl_ptr] ;get the user ID
|
|
sta |USERID ;update the global User ID
|
|
jsr find_user_id
|
|
bcc @found_it
|
|
@do_old_loader
|
|
jmp old_loader ;not ExpressLoad's file
|
|
@found_it
|
|
ldy #ID_Table_Entry.ExpressHandle ;get handle to the ExpressLoad segment
|
|
lda [temp_ptr],y
|
|
sta ExpressHandle
|
|
iny
|
|
iny
|
|
lda [temp_ptr],y
|
|
sta ExpressHandle+2
|
|
|
|
ldy #JE_FileNum ;check the load file number
|
|
lda [jmp_tbl_ptr],y
|
|
dec a
|
|
bne @do_old_loader ;This file is not ExpressLoad compatible
|
|
iny
|
|
iny
|
|
lda [jmp_tbl_ptr],y ;get the segment we need to find
|
|
sta search_seg
|
|
|
|
iny
|
|
iny
|
|
lda [jmp_tbl_ptr],y ;get the relative offset
|
|
sta jmp_patch_value
|
|
iny
|
|
iny
|
|
lda [jmp_tbl_ptr],y
|
|
sta jmp_patch_value+2
|
|
|
|
jsr merge_path_2
|
|
|
|
clc
|
|
ldy #$0002
|
|
lda [ExpressHandle]
|
|
adc #ExpressloadSeg.SegCount ;pass the link field
|
|
sta HET_ptr ;header entry table pointer
|
|
lda [ExpressHandle],y
|
|
adc #$0000
|
|
sta HET_ptr+2
|
|
|
|
lda search_seg
|
|
dec a ;convert base 1 to base 0
|
|
dec a ;allow for ExpressLoad segment
|
|
|
|
asl a
|
|
asl a
|
|
asl a ;times 8 for HET entry size
|
|
|
|
inc a ;add two to pass the segment count field
|
|
inc a
|
|
|
|
clc
|
|
adc HET_ptr ;make a pointer to the Entry
|
|
sta HET_entry_ptr ;pointer to the entry itself
|
|
lda #$0000
|
|
adc HET_ptr+2
|
|
sta HET_entry_ptr+2
|
|
;
|
|
;Build a pointer to the segment header itself
|
|
;
|
|
clc
|
|
lda HET_entry_ptr ;add in relative address to segment
|
|
adc [HET_entry_ptr]
|
|
sta seg_header_ptr
|
|
lda HET_entry_ptr+2
|
|
adc #$0000
|
|
sta seg_header_ptr+2
|
|
;
|
|
;Now lets see if the segment is already loaded into memory
|
|
;
|
|
ldy #HET_Entry.SegFlags
|
|
lda [HET_entry_ptr],y
|
|
bpl @new_segment ;we must load the segment from disk
|
|
lsr a ;see if the segment is marked as purgable
|
|
bcc @its_locked
|
|
lda search_seg ;pass in the segment number please
|
|
jsr lock_segment ;go and lock this segment
|
|
bcs @new_segment ;we have to reload the segment from disk
|
|
@its_locked
|
|
ldy #HET_Entry.SegHandle ;get the base address
|
|
lda [HET_entry_ptr],y
|
|
sta temp_handle
|
|
iny
|
|
iny
|
|
lda [HET_entry_ptr],y
|
|
sta temp_handle+2
|
|
|
|
ldy #$0002 ;get the real address
|
|
lda [temp_handle]
|
|
sta base_ptr
|
|
lda [temp_handle],y
|
|
sta base_ptr+2
|
|
bra @do_patch
|
|
@new_segment
|
|
jsr open_load_file ;open the puppy
|
|
bcc @got_it
|
|
@oops
|
|
jsr error_routine ;sorry no can do. (No Return)
|
|
@got_it
|
|
lda #1
|
|
sta PSysPrefs.pCount
|
|
|
|
jsr lock_handles
|
|
jsl $e100a8 ;get the current system preferences
|
|
dc.w GetSysPrefs
|
|
dc.l PSysPrefs
|
|
;
|
|
;Save the current user's preference please
|
|
;
|
|
lda PSysPrefs.preferences
|
|
sta users_prefs
|
|
;
|
|
;Now ask the operating system to put up a mount dialog when I ask for a disk
|
|
;
|
|
lda #$C000 ;ask the OS to put up the mount dialog
|
|
sta PSysPrefs.preferences
|
|
|
|
jsl $e100a8
|
|
dc.w SetSysPrefs ;set the system preference
|
|
dc.l PSysPrefs
|
|
jsr unlock_handles
|
|
|
|
jsr load_segment ;load the segment into memory
|
|
bcs @oops
|
|
lda search_seg ;relocate the segment
|
|
jsr Process_Reloc
|
|
|
|
lda users_prefs
|
|
sta PSysPrefs.preferences
|
|
jsr lock_handles
|
|
jsl $e100a8
|
|
dc.w SetSysPrefs ;restore the caller's system preference
|
|
dc.l PSysPrefs
|
|
jsr unlock_handles
|
|
|
|
jsr close_load_file ;close the file
|
|
@do_patch
|
|
clc ;add in the offset field
|
|
lda base_ptr
|
|
adc jmp_patch_value
|
|
sta base_ptr
|
|
lda base_ptr+2
|
|
adc jmp_patch_value+2
|
|
sta base_ptr+2
|
|
|
|
back_to_user
|
|
ldy #JE_jsl ;offset to the JSL
|
|
lda #$5C ;convert to a JML
|
|
sta [jmp_tbl_ptr],y
|
|
iny
|
|
lda base_ptr
|
|
sta [jmp_tbl_ptr],y
|
|
sta call_routine+1
|
|
lda base_ptr+1
|
|
iny
|
|
sta [jmp_tbl_ptr],y
|
|
sta call_routine+2
|
|
|
|
;
|
|
; Restore user's machine state and jump to the just-loaded routine
|
|
;
|
|
sep #$20
|
|
lda save_statereg ;restore original language card settings
|
|
sta >statereg
|
|
rep #$20
|
|
|
|
jsl decbusyflg
|
|
pld ;restore Direct Register
|
|
lda save_a ;restore registers
|
|
ldx save_x
|
|
ldy save_y
|
|
plb
|
|
plp ;restore processor mode
|
|
call_routine jml $0000000 ;call the desired routine
|
|
|
|
old_loader
|
|
;
|
|
; set System Preferences to Display Mount Dialogs
|
|
;
|
|
lda #1
|
|
sta PSysPrefs.pCount
|
|
jsl $E100A8
|
|
dc.w GetSysPrefs
|
|
dc.l PSysPrefs ;get original preferences
|
|
lda PSysPrefs.preferences ;save original preferences
|
|
pha
|
|
lda #$C000 ;set to show dialog w/o cancel button
|
|
sta PSysPrefs.preferences
|
|
jsl $E100A8
|
|
dc.w SetSysPrefs
|
|
dc.l PSysPrefs ;set new preferences
|
|
pla
|
|
sta PSysPrefs.preferences ;restore original preferences
|
|
;
|
|
; call Load Dynamic Segment routine
|
|
;
|
|
lda #0 ;output Address
|
|
pha
|
|
pha
|
|
lda [jmp_tbl_ptr] ;UserID
|
|
pha
|
|
ldy #JE_FileNum
|
|
lda [jmp_tbl_ptr],y ;File Number
|
|
pha
|
|
ldy #JE_SegNum
|
|
lda [jmp_tbl_ptr],y ;Segment Number
|
|
pha
|
|
jsr Load_Segment
|
|
plx
|
|
ply
|
|
stx TempZero+4 ;address of Dynamic Segment
|
|
sty TempZero+6
|
|
php ;save carry and error code
|
|
pha
|
|
;
|
|
; restore original System Preferences
|
|
;
|
|
jsl $E100A8
|
|
dc.w SetSysPrefs
|
|
dc.l PSysPrefs ;set preferences
|
|
|
|
pla ;restore error code
|
|
plp ;and carry
|
|
bcs error ;was there an error?
|
|
;
|
|
; calculate address of Dynamic Segment function
|
|
;
|
|
ldy #JE_Offset
|
|
lda [jmp_tbl_ptr],y
|
|
clc
|
|
adc TempZero+4
|
|
sta base_ptr
|
|
lda TempZero+6
|
|
adc #0
|
|
sta base_ptr+2
|
|
jmp back_to_user ;now off to the routine
|
|
|
|
error pha ;error code
|
|
lda #0 ;no message
|
|
pha
|
|
pha
|
|
_SysFailMgr
|
|
|
|
ENDP
|
|
|