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
25 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE ', STRUCT.a - Add_Link'
*
****************************************************************
*
* Add entry to Linked List
*
* Each entry in a Linked List starts with two 4 byte Handles.
* The first is a handle to the next entry
* and the second is a handle to the previous entry.
*
* Inputs: Address of Linked List (TOS+7)
* Handle to New Entry (TOS+3)
* Outputs: none
*
****************************************************************
*
Add_Link PROC
with DirectPage
First_Entry equ 7
New_Entry equ 3
;
; check whether this is 1st entry in Linked List
;
ldy #0
lda (First_Entry,s),y
ldy #2
ora (First_Entry,s),y
bne cont
;
; this is first entry, store handle of new entry in input
; address of Linked List (address assumed to be in same bank
; as this code)
;
lda New_Entry+2,s
sta (First_Entry,s),y ;Y is still == 2
lda New_Entry,s
ldy #0
sta (First_Entry,s),y
bra done ;done
;
; this is not first entry, replace address of Linked List with
; Handle to First Entry
;
cont lda (First_Entry,s),y ;Y == 2 here
sta First_Entry+2,s
ldy #0
lda (First_Entry,s),y
sta First_Entry,s
;
; Find last entry in linked list
;
; Starting from First Entry, move from Entry to Entry until
; a Entry is found whose Next Entry Handle is NIL. Put the
; Handle to each Entry back on the stack replacing the one
; before.
;
loop lda First_Entry+2,s ;Handle of First Entry
tay
lda First_Entry,s
jsr DeRef ;dereference Handle
phy ;Pointer on stack
pha
jsr DeRef ;get Next Entry Handle from First Entry
phy ;save on stack
pha
ora 3,s ;is Next Entry Handle NIL?
beq last ;yes, found last Entry
lda 1,s ;replace Handle to First Entry with
sta First_Entry+8,s ; Next Entry Handle in First Entry
tya
sta First_Entry+10,s
pla ;clean up stack
pla
pla
pla
bra loop ;repeat logic
;
; Last Entry in linked list has been found. Handle to First Entry
; on stack is now Handle to Last Entry. Pointer to Last Entry is
; on TOS+5.
;
last pla ;remove NIL Handle
pla
pla ;pull Pointer to Last Entry
ply
phb ;save DBR
jsr UsePtr ;make Pointer usable
lda New_Entry+3,s ;store Handle to New Entry
tay
sta |2,x ; as Next Entry Handle of Last Entry
lda New_Entry+1,s
sta |0,x
plb ;restore DBR
jsr DeRef ;dereference handle
phb ;save DBR
jsr UsePtr ;make Pointer to New Entry usable
lda First_Entry+1,s ;store Handle to Last Entry
sta |4,x ; in New Entry
lda First_Entry+3,s
sta |6,x
plb ;restore DBR
done Stack_Cleanup 8 ;remove parameters
rts ;return
ENDP
TITLE ', STRUCT.a - Remove_Link'
*
****************************************************************
*
* Remove entry in Linked List
*
* Inputs: Address of Linked List (TOS+7)
* Handle of Entry (TOS+3)
*
* Outputs: none
*
* Zero Page used: none
*
* This routine assumes that the Linked List is in Bank 1
* (e.g. in Loader's Global area)
*
****************************************************************
*
Remove_Link PROC
with DirectPage
Address equ 7+8
Entry equ 3+8
Next equ 5
Previous equ 1
;
; get Previous handle and Next handle out of Entry
; and put on stack
;
lda Entry-6,s ;handle of Entry
tay
lda Entry-8,s
jsr DeRefUse ;dereference Handle and use Pointer
lda |2,x ;Next handle
pha
lda |0,x
pha
lda |6,x ;Previous handle
pha
lda |4,x
pha
;
; is Entry only one in linked list ?
; (Previous handle = Next handle = 0)
;
ora Previous,s
tay ;save
ora Next,s
ora Next+2,s
bne cont1
;
; yes, zero out Address of Linked List
;
phk ;restore DBR
plb
lda #0
ldy #0
sta (Address,s),y
ldy #2
sta (Address,s),y
bra cont4
;
; no, is Previous handle of Entry = 0 (i.e. first entry) ?
;
cont1 tya
bne cont2
;
; yes, store Next handle of Entry in Address of Linked List
;
phk ;restore DBR
plb
lda Next,s
ldy #0
sta (Address,s),y
lda Next+2,s
ldy #2
sta (Address,s),y
bra cont3
;
; no, point to previous entry
;
cont2 lda Previous+2,s
tay
lda Previous,s
jsr DeRefUse ;dereference Handle and use Pointer
;
; set Next handle of previous entry to Next handle of Entry
;
lda Next,s
sta |0,x
lda Next+2,s
sta |2,x
;
; is Next handle of Entry = 0 (i.e. last entry) ?
;
cont3 lda Next,s
ora Next+2,s
beq cont4
;
; no, point to next entry
;
lda Next+2,s
tay
lda Next,s
jsr DeRefUse ;dereference Handle and use Pointer
;
; set Previous handle of next entry to Previous handle of Entry
;
lda Previous,s
sta |4,x
lda Previous+2,s
sta |6,x
;
; dispose of Entry
;
cont4 lda Entry+2,s
pha
lda Entry+2,s
pha
_DisposeHandle
;
; remove extra handles from stack
;
pla
pla
pla
pla
;
; restore DBR and stack
;
phk ;set DBR to PBR
plb
Stack_Cleanup 8
rts
ENDP
TITLE ', STRUCT.a - Add_Pathname'
*
****************************************************************
*
* Add new entry in Pathname Table
*
* Inputs: UserID (TOS+25)
* File Number (TOS+23)
* Time/Date Stamp (TOS+15)
* Direct Page/Stack Addr (TOS+13)
* Direct Page/Stack Size (TOS+11)
* Starting Address (TOS+7)
* Address of Pathname (TOS+3)
*
* Outputs: New entry linked to last entry (if previous exists)
* A - status code
* C - set if error
*
* Zero Page used: Pointer, Handle, TempZero
*
****************************************************************
*
Add_Pathname PROC
with DirectPage, Globals
IUserID EQU 25
FileNum EQU 23
Date EQU 15
ZP_Addr EQU 13
ZP_Size EQU 11
Address EQU 7
PathName EQU 3
APathTbl equ Pointer
lda PathName,s
sta TempZero ;store addr of Pathname in zero page
lda PathName+2,s
sta TempZero+2
;
; get a memory buffer for new entry
;
ldx #0
phx ;space for output Handle
phx
phx ;BlockSize =
lda [TempZero] ; length of File Name
clc
adc #PT_Path+2 ; +size of constant portion
pha
pea uPATHTBL ;Owner
pea attrNoSpec ;Attributes
phx ;Location
phx
_NewHandle ;get memory buffer
plx
ply
stx Handle ;save returned handle
sty Handle+2
bcc @1
jmp error
@1
txa
jsr DeRef ;dereference handle
sta APathTbl ;save address of entry
sty APathTbl+2
;
; zero linked list pointers
;
lda #0
ldy #6
@loop
sta [APathTbl],y
dey
dey
bpl @loop
;
; set DBR to address of entry
;
lda APathTbl
ldy APathTbl+2
phb ;save DBR
jsr UsePtr
;
; store UserID in new entry
;
lda IUserID+1,s
sta |PT_UserID,x
;
; store File Number in new entry
;
lda FileNum+1,s
sta |PT_FileNum,x
;
; if File Number=1, set Jump Table Segment processed flag to 1
; otherwise, zero it
;
cmp #1
beq cont
lda #0
cont sta |PT_Jump,x
;
; store File Date and Time in new entry
;
lda Date+1,s
sta |PT_Date,x
lda Date+3,s
sta |PT_Date+2,x
lda Date+5,s
sta |PT_Date+4,x
lda Date+7,s
sta |PT_Date+6,x
;
; store Zero Page/Stack info in new entry
;
lda ZP_Addr+1,s
sta |PT_ZP_Addr,x
lda ZP_Size+1,s
sta |PT_ZP_Size,x
;
; store Starting Address in new entry
;
lda Address+1,s
sta |PT_Address,x
lda Address+3,s
sta |PT_Address+2,x
;
; restore DBR
;
plb
;
; move File Name into Pathname
;
pei TempZero+2 ;source address
pei TempZero
lda APathTbl ;calculate destination address
clc
adc #PT_Path
tax
lda APathTbl+2
adc #^PT_Path
pha
phx ;destination address
pea 0 ;number of bytes
lda [TempZero]
clc
adc #2
pha
jsr Block_Move ;call Move function
;
; link new Pathname Table to previous
;
pea PATHTBL>>16
pea |PATHTBL
pei Handle+2
pei Handle
jsr Add_Link
;
; return
;
return lda #0
error Stack_Cleanup 24 ;remove input parameters
rts
ENDP
TITLE ', STRUCT.a - Find_Pathname'
*
****************************************************************
*
* Find entry in Pathname Table
*
* Inputs: UserID (TOS+9)
* File Number (TOS+7)
* Address of Pathname (TOS+3)
*
* Outputs: none
* X - low bytes of Pointer to entry
* DBR - bank
* Handle- Handle of entry
* A - status code
* C - set if error
* Counter - if no find, contains max File Number
*
* Zero Page used: Handle, TempZero, Counter
*
* This routine will search the Pathname Table for an entry that satisfies
* each of the input parameters. If a parameter is 0, it is not used as
* a criteria. If no such entry is found, Counter will contain the max
* File Number encountered (which is only useful if a UserID is specified)
*
* Before calling this routine, the User should save the DBR.
*
* After calling this routine and making all references to the entry,
* the User must restore the original DBR.
*
* This routine can also be used to walk through the Pathname Table
* by calling the 'Find_Pathname' entry once and then calling the
* 'Next_Pathname' entry for each subsequent entry. The Direct Page variable
* 'Handle' will point to the handle of the current entry so it should be
* bumped to the handle of the next entry between 'Next_Pathname' calls.
*
****************************************************************
*
Find_Pathname PROC
with DirectPage, Globals
IUserID EQU 9
FileNum EQU 7
Path EQU 3
lda |PATHTBL
sta Handle ;handle to 1st entry
lda |PATHTBL+2
sta Handle+2
stz Counter
ENTRY Next_Pathname
Next_Pathname
loop1 lda Handle ;is handle 0?
ora Handle+2
bne cont1
lda #NoFind ;yes, No Find error
phk ;set DBR to PBR
plb
jmp error
cont1 lda Handle
ldy Handle+2
jsr DeRefUse ;dereference Handle and use Pointer
;
; if input UserID­0, compare with value in entry
;
lda IUserID,s
beq cont2
cmp |PT_UserID,x
bne eloop2
;
; if input File Number­0, compare with value in entry
;
cont2 lda FileNum,s
beq cont5
cmp |PT_FileNum,x
bne eloop2
;
; if pathname specified, compare with pathname in entry
;
cont5 lda Path,s
ora Path+2,s
beq return ;found match, done
lda Path,s
sta TempZero
lda Path+2,s
sta TempZero+2
txa
clc
adc #PT_Path
sta TempZero+4
phb
phb
pla
and #$00FF
bcc @1 ;propage carry for possible
inc a ;bank crossing
@1
sta TempZero+6
lda [TempZero]
inc a
tay
sep #$20
longa off
loop2 lda [TempZero],y
eor [TempZero+4],y ;case insensitive comparison
and #$DF ;ignore the case bit
bne eloop2
dey
bpl loop2
bra return ;matches
eloop2 rep #$20
longa on
;
; set Counter=max(Counter,File Number)
;
lda |PT_FileNum,x
cmp Counter
bcc eloop1
sta Counter
;
; continue to next entry
;
eloop1 lda |PT_Next,x
sta Handle ;bump Handle to Next Handle
lda |PT_Next+2,x
sta Handle+2
jmp loop1 ;continue checking
;
; normal return
;
return rep #$20
longa on
lda #0 ;OK return
error Stack_Cleanup 8 ;remove input parameters
rts
ENDP
TITLE ', STRUCT.a - Get_Pathname'
*
****************************************************************
*
* Get Pathname
*
* Inputs: Handle - Handle to Pathname Table entry
*
* Outputs: TempBuff - Address of temporary buffer containing pathname
* A - status
* C - set if error occurred
*
* Zero Page used: Pointer
*
* The pathname in the Pathname Table entry is moved into
* a temporary buffer. This buffer should be disposed after
* the pathname is used.
*
****************************************************************
*
Get_Pathname PROC
with DirectPage
;
; lock input handle
;
pei Handle+2
pei Handle
_HLock
;
; set Pointer to address of pathname using Handle to entry
;
lda Handle
ldy Handle+2
jsr DeRef
clc
adc #PT_Path
sta Pointer
bcc @1
iny
@1 sty Pointer+2
;
; extract length of pathname and save
;
lda [Pointer]
inc a
inc a
pha
;
; get a temporary buffer
;
jsr Get_TempBuff
;
; unlock input handle
;
pei Handle+2
pei Handle
_HUnlock
;
; unsave length of pathname
;
plx
;
; copy pathname to temporary buffer
;
pei Pointer+2 ;Source
pei Pointer
pei TempBuff+2 ;Destination
pei TempBuff
pea 0
phx ;Size
jsr Block_Move
error rts
ENDP
TITLE ', STRUCT.a - Convert_Pathname'
*
****************************************************************
*
* Convert Pathname
*
* Inputs: A,Y - Address of Pathname
* X - pathname conversion code (0-Type 0 to 1)
* (1-Type 1 to 0)
*
* Outputs: TempBuff - Address of converted pathname
* A - status
* C - set if error occurred
*
* Zero Page used: TempZero
*
* A temporary buffer is allocated for the converted pathname and
* should be disposed after the pathname is used. Use the DisposeAll
* function with UserID 'uTempBuff' to dispose of the temporary buffer.
*
****************************************************************
*
Convert_Pathname PROC
with DirectPage
;
; save inputs in direct page
;
sta TempZero
sty TempZero+2
stx TempZero+4
;
; calculated converted pathname size
;
lda [TempZero]
inc a
dex ;if class 0 string, use 1st byte
beq cont1 ;if class 1 string, use word
and #$00FF
inc a
;
; get temporary buffer for full pathname
;
cont1 jsr Get_TempBuff
pei TempZero+2
pei TempZero
pei TempBuff+2
pei TempBuff
;
; check conversion code
;
ldx TempZero+4
dex
beq cont2
;
; class 0 to 1 requested, call GS/OS Convert 0 routine
;
jsl CVT_0TO1
bcc return
bra error
;
; class 1 to 0 requested, call GS/OS Convert 1 to 0 routine
;
cont2 jsl CVT_1TO0
bcs error
;
; replace the :'s in the pathname with /'s
;
lda [TempZero]
tay
sep #$30
longa off
longi off
loop lda [TempBuff],y
cmp #':'
bne eloop
lda #'/'
sta [TempBuff],y
eloop dey
bne loop
rep #$30
longa on
longi on
tya ;zeroize accumulator (no error)
rts
error lda #BadPath
return rts
ENDP
TITLE ', STRUCT.a - Expand_Pathname'
*
****************************************************************
*
* Expand Pathname
*
* Inputs: A,Y - Address of Partial Pathname
*
* Outputs: TempBuff - Address of full pathname
* A - status
* C - set if error occurred
*
* Zero Page used: TempZero, Counter
*
* A temporary buffer is allocated for the full pathname and should be
* disposed after the pathname is used. Use the DisposeAll function
* with UserID 'uTempBuff' to dispose of the temporary buffer.
*
****************************************************************
*
Expand_Pathname PROC
with DirectPage, Globals
;
; save address of partial pathname
;
sta TempZero
sty TempZero+2
;
; setup Expand_Path packet
;
sta |PExpandPath.inputPath ;input partial pathname
sty |PExpandPath.inputPath+2
lda #3
sta |PExpandPath.pCount ;parameter count
; lda #$8000
; sta |PExpandPath.flags ;uppercase flag
stz |PExpandPath.flags ;uppercase flag (no uppercasing)
;
; get length of partial pathname
;
lda [TempZero]
;
; calculate initial buffer size = length of partial pathname +4
;
cont2 clc
adc #4
sta Counter
;
; get temporary buffer for full pathname
;
jsr Get_TempBuff
;
; set length of buffer in output string buffer
;
lda Counter
sta [TempBuff]
;
; store address of buffer in Expand_Path packet
;
lda TempBuff
sta |PExpandPath.outputPath
lda TempBuff+2
sta |PExpandPath.outputPath+2
;
; call GS/OS Expand_Path
;
jsl $E100A8
dc.w ExpandPath
dc.l PExpandPath
;
; if buffer too small, get needed size and try again
;
bcc cont5
cmp #buffTooSmall
bne cont3
ldy #2
lda [TempBuff],y
bra cont2
;
; if GS/OS is active, that means that GS/OS called RenamePath and we can
; assume that the input filename is already expanded and in correct format
;
cont3 cmp #gsosActive
beq cont4
sec ;any other GS/OS error is really an error
bra error
cont4
lda TempZero
sta TempBuff
lda TempZero+2
sta TempBuff+2
bra return
;
; otherwise, point TempBuff to start of pathname
;
cont5 lda TempBuff
clc
adc #2
sta TempBuff
bcc return
inc TempBuff+2
return lda #0
clc
error rts
ENDP
TITLE ', STRUCT.a - Add_MemSeg'
*
****************************************************************
*
* Add entry to Memory Segment Table
*
* Inputs: Memory Handle (TOS+11)
* User ID (TOS+9)
* Load File Number (TOS+7)
* Load Segment Number (TOS+5)
* Load Segment Kind (TOS+3)
*
* Outputs: New table linked to last table (if previous exists)
* A - status code
* C - set if error
*
* Zero Page used: TempZero
*
****************************************************************
*
Add_MemSeg PROC
with DirectPage, Globals
IHandle equ 11
IUserID equ 9
FileNum equ 7
SegNum equ 5
Kind equ 3
;
; get a memory buffer for new entry
;
lda #0 ;space for output Handle
pha
pha
pea MS_Kind+2>>16 ;BlockSize
pea |MS_Kind+2
pea uSEGTBL ;Owner
pea attrNoCross+attrNoSpec ;Attributes
pha ;Location
pha
_NewHandle ;get memory buffer
plx
ply
stx TempZero ;save returned handle
sty TempZero+2
bcs error
txa
jsr DeRefUse ;dereference Handle and use Pointer
;
; store components into Memory Segment entry
;
stz |MS_Next,x
stz |MS_Next+2,x
stz |MS_Prev,x
stz |MS_Prev+2,x
lda IUserID,s
sta |MS_UserID,x
lda IHandle,s
sta |MS_Handle,x
lda IHandle+2,s
sta |MS_Handle+2,x
lda FileNum,s
sta |MS_FileNum,x
lda SegNum,s
sta |MS_SegNum,x
lda Kind,s
sta |MS_Kind,x
phk ;restore DBR to PBR
plb
;
; link new entry to previous
;
pea SEGTBL>>16
pea |SEGTBL
pei TempZero+2
pei TempZero
jsr Add_Link
;
; return
;
lda #0 ;OK return
error Stack_Cleanup 12 ;remove input parameters
rts
ENDP
TITLE ', STRUCT.a - Find_MemSeg'
*
****************************************************************
*
* Find entry in Memory Segment Table
*
* Inputs: User ID (TOS+7)
* Load File Number (TOS+5)
* Load Segment Number (TOS+3)
*
* Outputs: Handle of entry (TOS+9)
* X - low bytes of Pointer to entry
* DBR - bank
* Handle - Handle of Next entry
* A - status code
* C - set if entry not found or error ocurred
*
* Zero Page used: Handle
*
* If any of the inputs are 0, no comparison is made for that field.
*
* Be careful! The DBR will be changed by this routine and the
* calling program should restore its original DBR after referencing
* the data in the entry.
*
* This routine can also be used to walk through the Memory Segment Table
* by calling the 'Find_MemSeg' entry once and then calling the
* 'Next_MemSeg' entry for each subsequent entry. The Direct Page variable
* 'Handle' will point to the handle of the next entry so should not be
* changed between 'Next_MemSeg' calls.
*
****************************************************************
*
Find_MemSeg PROC
with DirectPage, Globals
OHandle equ 9
IUserID equ 7
FileNum equ 5
SegNum equ 3
lda >SEGTBL
sta Handle ;handle to 1st entry
lda >SEGTBL+2
sta Handle+2
ENTRY Next_MemSeg
Next_MemSeg
loop lda Handle ;is handle NIL?
ora Handle+2
bne cont1
lda #NoFind ;yes, No Find error
bra error
cont1 lda Handle+2 ;handle to entry
tay
sta OHandle+2,s ;save as output
lda Handle
sta OHandle,s
jsr DeRefUse ;dereference Handle and use Pointer
lda |MS_Next,x
sta Handle ;bump Handle to Next Handle
lda |MS_Next+2,x
sta Handle+2
;
; compare inputs with values in entry
;
lda IUserID,s
beq cont2
cmp |MS_UserID,x
bne loop
cont2 lda FileNum,s
beq cont3
cmp |MS_FileNum,x
bne loop
cont3 lda SegNum,s
beq return
cmp |MS_SegNum,x
bne loop
;
; normal return
;
return lda #0 ;OK return
error Stack_Cleanup 6 ;remove input parameters
rts
ENDP
TITLE ', STRUCT.a - Remove_UserID'
*
****************************************************************
*
* Remove entries from Table
*
* Inputs: UserID (TOS+7)
* Address of Linked List (TOS+3)
*
* Outputs: none
*
* Zero Page used: Handle, TempZero
*
* This routine can be used to remove entries from the
* Pathname Table, Jump Table List and any other Table
* that:
*
* 1. is a linked list (with forward and back handles)
* 2. first entry is UserID
*
****************************************************************
*
Remove_UserID PROC
with DirectPage
IUserID equ 7
Address equ 3
lda Address+2,s
tay
lda Address,s
jsr DeRef
sta Handle ;handle to 1st entry
sty Handle+2
loop ora Handle+2
beq return ;yes, finished
lda Handle ;Y still has high word
jsr DeRefUse ;dereference Handle and use Pointer
;
; save next Handle
;
lda |0,x
sta TempZero
lda |2,x
sta TempZero+2
;
; check UserID
;
lda |8,x
phk ;restore DBR
plb
cmp IUserID,s
bne eloop
;
; unlink this entry
;
lda Address+2,s ;address of Pathname Table
pha
lda Address+2,s
pha
pei Handle+2 ;handle to this entry
pei Handle
jsr Remove_Link
;
; continue to next entry
;
eloop lda TempZero+2
sta Handle+2 ;bump Handle to Next Handle
tay
lda TempZero
sta Handle
bra loop
;
; normal return
;
return phk ;restore DBR
plb
Stack_Cleanup 6 ;remove input parameters
rts
ENDP
TITLE ', STRUCT.a - Unload_JTL'
*
****************************************************************
*
* Unload Jump Table Entries
*
* Inputs: User ID (TOS+7)
* Load File Number (TOS+5)
* Load Segment Number (TOS+3)
*
* Outputs: none
*
* Zero Page used: none
*
* This subroutine will make all entries with the
* specified components in the Jump Table unloaded.
*
* If Load File Number or Load Segment Number is 0,
* no comparison is made for that field
*
****************************************************************
*
Unload_JTL PROC
with DirectPage, Globals
IUserID equ 7+4
FileNum equ 5+4
SegNum equ 3+4
;
; push 1st entry in Jump Table List
;
lda |JMPTBL+2
pha
lda |JMPTBL
pha
loop1 ora 3,s ;is handle 0?
beq return ;yes, we are finished
cont1 lda 3,s ;no
tay
lda 1,s
jsr DeRefUse ;dereference Handle and use Pointer
;
; is this Jump Table List entry for specified UserID?
;
lda |JT_UserID,x
cmp IUserID,s
bne eloop1 ;if not, skip this entry
;
; find Jump Table
;
lda |JT_Handle,x
ldy |JT_Handle+2,x
jsr DeRef ;dereference handle
bcs eloop1 ;skip if handle is NIL
jsr UsePtr ;make pointer useable
;
; move X past 8 zero bytes to first entry in Jump Table
; (this will not be necessary when Linker changed)
;
txa
clc
adc #8
tax
;
; compare inputs with values in entry
;
loop2 lda |JE_UserID,x
beq eloop1 ;if UserID=0, no more entries
cmp IUserID,s ;redundant check for UserID
bne eloop2
cont2 lda FileNum,s
beq cont3
cmp |JE_FileNum,x
bne eloop2
cont3 lda SegNum,s
beq cont4
cmp |JE_SegNum,x
bne eloop2
;
; entry satisfies input conditions, make unloaded
;
cont4 lda >jump_load_instr ;JSL instruction and 1st byte of address
sta |JE_jsl,x
lda >jump_load_instr+2 ;last two bytes of address
sta |JE_jsl+2,x
;
; bump X to next entry
;
eloop2 txa
clc
adc #JE_jsl+4
tax
bra loop2
;
; bump Handle to next Jump Table List entry
;
eloop1 lda 3,s
tay
lda 1,s
jsr DeRefUse ;dereference Handle and use Pointer
lda |JT_Next+2,x
sta 3,s
lda |JT_Next,x ;bump Handle to Next Handle
sta 1,s
bra loop1
return pla ;pull last Handle off stack
pla
Stack_Cleanup 6 ;remove input parameters
phk ;set DBR to PBR
plb
rts
ENDP
TITLE ', STRUCT.a - Cleanup'
*
****************************************************************
*
* Cleanup Routine
*
* Inputs: UserID (2 bytes) (TOS+3)
*
* Outputs: none
*
* Zero Page used: TempZero, Handle
*
****************************************************************
*
Cleanup PROC
with DirectPage, Globals
IUserID equ 3
;
; if UserID is not 0, remove UserID from Jump Table first
;
lda IUserID,s
beq cont
pha
pea JMPTBL>>16
pea |JMPTBL
jsr Remove_UserID
;
cont lda IUserID,s ;UserID
pha
ldx #0 ;Load File Number (all)
phx
phx ;Load Segment Number (all)
phx ;Dynamic Only Flag (no)
phx ;Purge Level (real purge)
jsr Purge_Segment
return lda #0 ;OK return
error Stack_Cleanup 2 ;remove input parameters
rts
ENDP