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
15 KiB
Plaintext

;====================================================================================================
;Zero page equates used by ExpressLoad
;====================================================================================================
HET_ptr equ $00 ;points the header entry table
HET_entry_ptr equ $04 ;points to an entry in the HET
temp_handle equ $08 ;temp area used for handles
base_ptr equ $0C ;points to a segment in memory.
seg_header_ptr equ $10 ;points to a segment header
reloc_dict_ptr equ $14 ;points to the relocation dictionary
patch_cnt equ $18 ;word that contains the patch count
shift_cnt equ $1A ;word that contains the shift count
patch_ptr equ $1C ;address that we have to patch
patch_value equ $20 ;value that we patch with
temp_ptr equ $24
interseg_addr equ $28 ;used to patch the segments
super_size equ $2C ;size of the super record
cnt_word equ $2E
super_ptr equ $30 ;used to relocate a super record
temp_word equ $34
segment_base equ $36 ;base address of other segment
user_id_handle equ $3A ;handle to User ID list
user_id_ptr equ $3E
temp_long equ $42
path_ptr equ $46 ;points to a GString output buffer
vol_ptr equ $4A ;points to
ExpressHandle equ $4E ;Handle to ExpressHeader
jmp_tbl_ptr equ $52 ;pointer to the Jump_tbale Entry
reloc_handle equ $56 ;handle to the relocation dictionary
seg_handle equ $5A ;handle to the segment in memory
curr_id_handle equ $5E ;Handle to ID list
segment_entry equ $62 ;entry point inside the segment
dir_page_size equ $68 ;Size MUST be EVEN EVEN EVEN EVEN EVEN EVEN
IF debug_on=0 GOTO .nobug
Rom_debug equ $FF0000
.nobug
;====================================================================================================
;Error equates
;====================================================================================================
seg_not_found equ $1101
not_load_file equ $1104
illegal_record equ $110A
User_id_err equ $11F0 ;I could not find a user_id when I should have
incompatible_err equ $11F1 ;The file is not expressload compatible
ExpressSegLost equ $11F2 ;The ExpressSeg Handle is lost
;====================================================================================================
;General equates
;====================================================================================================
jmp_tbl_seg equ $02
seg_jmp_start equ 08
jmp_entry_size equ 14
my_level equ $70 ;use to set the system level
keep_id equ $0001 ;Tell Delete_User_ID to keep the ID around after deleting memory
nuke_id equ $0000 ;delete memory and the user_id
os_chain_vector equ $e100ac
app_type equ $00B3
load_type equ $00B5
absolute equ $0000
forward equ $0001
backward equ $0002
Data_Kind equ $0001 ;and it is a data segment
Dynamic equ $8000 ;It is also Dynamic
kind_only equ $001F ;clear all but the segment kind
init_seg_type equ $10
dp_seg_type equ $12
static_code_type equ $0000
static_and_kind equ $801F
static_type equ $00
static_only equ $8000
all_types equ 00
any_kind equ 00
any_state equ 00
unloaded_state equ $8000
Reload_Segment equ $0400 ;indicates that this segment must be reloaded at restart
gs_os_start equ $9A00 ;start of GS/OS in bank zero
kind_bank_bit equ $0100 ;bank bit
kind_abs_bank equ $0800
GSOS_ID equ $3102 ;ID of operating system
locked_no_cross equ $8010
locked_only equ $8000
seperator equ $3A ;seperator is a colon
max_vol equ 40 ;maximum volume size
app_type_id equ $1000 ;used to allocate a new User_ID
purge_all equ $0000 ;and mask used to compare flags
purge_dynamics equ $0004 ;Bit 2 = static bit. If 1 then static
;====================================================================================================
;Equates used for the User_ID_table
;====================================================================================================
id_tbl_size equ 2048 ;a 2K table. Value must be an even positive number!
id_entry_size equ 16
id_entry_cnt equ 126 ;number of entries in one table
id_offset equ $00
id_expHandle equ $02
id_stack_addr equ $06 ;address of the stack
id_stack_size equ $08 ;size of the stack
id_start_addr equ $0A ;address of the start segment
;====================================================================================================
;offset in the segment header
;====================================================================================================
extra_header equ 16 ;additinal info added to expressload header
seg_size_offset equ $0004
reloc_mark_offset equ $0008
reloc_size_offset equ $000C
lablen_offset equ $0011
bank_size_offset equ $14
seg_kind_offset equ $18
Reloc_dict_Offset equ $2E ;Offset the relocation dictionary handle in seg header in HET
org_offset equ $1C
align_offset equ $20
seg_entry_offset equ $28 ;offset to the segment entry field
seg_vol_offset equ $06 ;offset to vol_name offset
seg_name_disp equ $2C ;offset to the displacement field
name_overhead equ $0E ;14 bytes to the beginning of the segment name
handle_offset equ $0004 ;offset in HET entry
flags_offset equ $0002 ;offset in HET entry
jmp_type equ $0002 ;indicates a jump table segment
stat_type equ $0004 ;indicates a static segment
;====================================================================================================
;Memory Manager equates
;====================================================================================================
Attr_Locked equ $8000 ;memory segment is locked
Attr_fixed equ $4000 ;block can't move in memory
purge_level_3 equ $0300 ;set purge level to three for dynamics only
attr_align_in_bank equ $0040 ;Align to address withing the bank
attr_bank_align equ $0020 ;force bank alignment
attr_no_cross equ $0010 ;cannot cross any bank
attr_no_spec equ $0008 ;no special memory
attr_page equ $0004 ;page aligned segment
attr_addr equ $0002 ;block must remain at fixed addr
attr_bank equ $0001 ;fixed bank address
;====================================================================================================
;equates used by function calls
;====================================================================================================
func_9_param_cnt equ $0009*2 ;18 bytes on stack
func_9_spec_mem equ $0000 ;offset to special memory flag in paramter table
func_9_path_addr equ $0002 ;offset to the pathname pointer
func_9_user_id equ $0006 ;offset to the User ID field
func_9_err_cnt equ $000A ;Number of bytes call normally returns
func_20_param_cnt equ $000A*2 ;20 bytes on stack
func_20_path_flag equ $0000 ;offset to the pathname type flag 1 = GString
func_20_spec_mem equ $0002 ;offset to special memory flag in paramter table
func_20_path_addr equ $0004 ;offset to the pathname pointer
func_20_user_id equ $0008 ;offset to the User ID field
func_20_err_cnt equ $000A ;Number of bytes call normally returns
func_22_param_cnt equ $0004*2 ;8 bytes on stack
func_22_file_num equ $0000
func_22_user_id equ $0002 ;offset to the User ID field
func_22_err_cnt equ $0004 ;Number of bytes call normally returns
func_0D_param_cnt equ $000A*2 ;20 bytes on stack
func_0D_seg_name equ $0000 ;offset to load seg name pointer
func_0D_file_name equ $0004 ;offset to the load file name
func_0D_user_id equ $0008 ;offset to the user id
func_0D_err_cnt equ $000A ;Number of bytes call normally returns
func_11_param_cnt equ $0004*2 ;8 bytes on stack
func_11_file_num equ $0000
func_11_user_id equ $0002 ;offset to the User ID field
func_11_err_cnt equ $0004 ;Number of bytes call normally returns
func_10_param_cnt equ $0003*2 ;6 bytes on stack
func_10_path_addr equ $0000 ;offset to the pathname pointer
func_21_param_cnt equ $0003*2 ;6 bytes on stack
func_21_path_addr equ $0000 ;offset to the pathname pointer
func_0B_param_cnt equ $0005*2 ;10 bytes on stack
func_0B_seg_num equ $0000 ;offset to the segment number
func_0b_file_num equ $0002 ;offset to the file number
func_0B_user_id equ $0004
func_0B_err_cnt equ $0004 ;Number of bytes call normally returns
func_0C_param_cnt equ $0003*2 ;6 bytes on stack
func_0C_seg_num equ $0000 ;offset to the segment number
func_0C_file_num equ $0002 ;offset to the file number
func_0C_user_id equ $0004
func_0C_err_cnt equ $0000
func_0E_param_cnt equ $0005*2 ;10 bytes on stack
func_0E_seg_addr equ $0000 ;address in a segment
func_12_param_cnt equ $0003*2 ;6 bytes on stack
func_12_quit_flag equ $0000 ;quit flag
func_12_user_id equ $0002 ;ID
func_12_err_cnt equ $0002 ;Number of bytes call normally returns
func_0A_param_cnt equ $0006*2 ;12 bytes on stack
func_0A_user_id equ $0000 ;ID
func_0A_err_cnt equ $000A ;Number of bytes call normally returns
func_13_param_cnt equ $0004*2 ;8 bytes on stack
func_13_new_ptr equ $0000 ;original pathname
func_13_orig_ptr equ $0004 ;new pathname
;====================================================================================================
;Local Data used by ExpressLoad.
;====================================================================================================
data Record
reloc_seg dc.w 00 ;used by 'Process_Reloc'. Segment number to relocate
end_found dc.w 00 ;indicates the end of the relocation dictionary
free_mem_size dc.l 00
AppID dc.w 00 ;ID assigned to the Application
ExpLoad_ID dc.w 00 ;ID assigned to ExpressLoader
loaded_seg_num dc.w 00 ;segment just loaded
search_kind dc.w 00 ;used by find segment
kind_mask dc.w 00 ;AND mask used by find segment
flags_mask dc.w 00 ;flags used by find segment
ExpressSeg_pos dc.w 01
alloc_attr dc.w 00 ;attributes used to allocate memory
mem_attr dc.w $8010 ;locked + my not cross bank boundary
starting_addr dc.l 00
stack_addr dc.w 00
stack_size dc.w 00
user_id dc.w 00
stack dc.w 00 ;holds stack pointer
seg_kind dc.w 00 ;used by conv_attributes
mm_attr dc.w 00 ;attribute passed to memory manager
search_addr dc.l 00 ;used by allocate lconst routine
org_address dc.l 00
my_dir_page dc.w 00 ;my direct page
LConst_Size dc.l 00 ;size of the segment
load_state dc.w 00
file_open dc.w 00 ;flag used to indicate that the load file is open
return_addr ds.b 03 ;return address to caller
return_addr2 dc.l 00
orig_a dc.w 00
orig_x dc.w 00
orig_y dc.w 00
path_size dc.w 00 ;total size of the pathname
vol_size dc.w 00 ;length of the volume name from expand path call
partial_size dc.w 00 ;length of the partial pathname
partial_offset dc.w 00 ;offset to the beginning of the partial pathname
spec_mem_flag dc.w 00 ;special memory flag used by Initial load
save_a dc.w 00
save_x dc.w 00
save_y dc.w 00
apps_dir_page dc.w 00
search_seg dc.w 00
jmp_patch_value dc.l 00
data_bank dc.w 00 ;holds the data bank for the tool call
param_blk ds.b 30 ;30 bytes for input parameters from caller
dp_handle dc.l 00 ;saves the handle to our direct page
added_flag dc.w $00 ;handles the OS switch
id_flag dc.w $00 ;used by delete_user_id.
hold_long dc.l 00 ;used by unload segment
express_size dc.l 00 ;size of the ExpressLoad segment
SubStr_size dc.w 00 ;offset into the substring
partial_match dc.w 00 ;used by rename
endr
dir_page_buffer record
ds.b dir_page_size+2 ;holds my direct page
endr
preference_list record
dc.w $01 ;PCount for the call
sys_prefs dc.w $00
users_prefs dc.w $00
endr
level_list record ;used to get and set the level
dc.w $0002 ;PCount
curr_level dc.w $0000 ;level to set
mode dc.w $0000 ;level mode
hold_level dc.w $0000 ;holds last level
endr
eof_list record
dc.w 2 ;pCount
ref_num dc.w 0
eof dc.l 0
endr
;
;Expand path output name buffer
;
Expanded_name record
dc.w 256 ;buffer is 256 bytes long
size dc.w 00 ;result size
name ds.b 1 ;space for the name is in the Graphic Data area
my_string
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$3F,$FF,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$F0,$3F,$FF,$FF,$FF,$FF,$FF,$FF,$FC,$0F,$FF
line_length equ *-my_string
dc.b $FF,$F4,$44,$44,$44,$FF,$03,$FF,$F0,$30,$30,$00,$3C,$00,$0F,$00
dc.b $0F,$C0,$00,$F0,$00,$30,$3F,$FF,$C0,$03,$F0,$00,$FC,$00,$0F,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$3C,$00,$F0,$3C,$0C,$03,$FC,$0F
dc.b $03,$03,$FF,$C0,$FF,$F0,$3F,$FF,$03,$C0,$FF,$F0,$30,$30,$0F,$FF
dc.b $44,$44,$44,$44,$4F,$FC,$0F,$FF,$FC,$0F,$C0,$F0,$30,$3F,$F0,$00
dc.b $0F,$00,$0F,$C0,$03,$C0,$FF,$FC,$0F,$03,$C0,$00,$C0,$F0,$3F,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FC,$0F,$FF,$F0,$03,$C0,$30,$30,$3F,$F0,$3F
dc.b $FF,$FF,$03,$FF,$C0,$C0,$FF,$FC,$0F,$03,$03,$C0,$C0,$C0,$3F,$FF
dc.b $FF,$FF,$44,$44,$44,$FC,$00,$00,$C0,$C0,$C0,$00,$F0,$3F,$FC,$00
dc.b $0C,$00,$0F,$00,$03,$C0,$00,$0F,$00,$0F,$C0,$00,$F0,$00,$3F,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$C0,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$C0,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
endr
full_blown record
string asis
dc.w 256
size dc.w 00
name ds.b 256-4
endr
open_list record
dc.w $06 ;PCount for the Open call
ref_num dc.w 00 ;returned by the open call
path_ptr dc.l 00
dc.w $01 ;open for read only
dc.w $00 ;ask for the data fork please
;
;Returned Info about file
;
access dc.w 00 ;file access
file_type dc.w 00 ;This is what I want
endr
;
;Expand path parameter block
;
expand record
dc.w $0003 ;PCount
src dc.l 00 ;Pointer to the Source pathname
dest dc.l Expanded_name ;result name
dc.w $8000 ;flags (UpperCase bit = true)
endr
header_buf record
size dc.l 00 ;size of my segment
dc.l 00 ;number of zeros to add to the segment
image dc.l 00 ;Memory Image Size
dc.b 00 ;Reserved
dc.b 00 ;Label Length
dc.b 04 ;number length
dc.b 02 ;say that we are version two of OMF
dc.l $10000 ;Bank size = 64K
kind dc.w Data_Kind+Dynamic
dc.w $0000 ;reserved
dc.l 00 ;org = 0
dc.l 00 ;no alignment
dc.b 00 ;number sex LSB first
dc.b 00 ;reserved
seg_num dc.w 01 ;segment number for this segment (first or Last)
dc.l 00 ;entry to the segment. (No entry for data)
name_disp dc.w $2C ;displacement to load name
code_disp dc.w $000
string asis
dc.b 'Rob Turner'
string Pascal ;no lets name the segment
dc.b 'ExpressLoad'
ds.b 256
endr
Express_name record
string pascal
dc.b 'EXPRESSLOAD'
string asis
endr
Tilda_name record
string pascal
dc.b '~EXPRESSLOAD'
string asis
endr
read_list record
dc.w $0004 ;PCount
ref_num dc.w 00
ptr dc.l 00 ;buffer to read into
cnt dc.l 00 ;number of bytes to read
ret_cnt dc.l 00 ;number of bytes read
endr
local_mark record
dc.l 00 ;our current mark in the file
endr
get_mark_list record
dc.w $02
ref_num dc.w 00
pos dc.l 000
endr
set_mark_list record
dc.w $03
ref_num dc.w 00
base dc.w 00
disp dc.l 00
endr
jump_load_instr record
import Jump_Load
dc.b $22 ;JSL
dc.l Jump_load ;address of Jump Load routine
endr