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
11 KiB
Plaintext
1 line
11 KiB
Plaintext
TITLE ', MISC.a - Get_TempBuff'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Get Temporary Buffer
|
|
*
|
|
* Inputs: A - Length of temporary buffer requested
|
|
*
|
|
* Outputs: TempBuff - Address of temporary buffer
|
|
* A - status
|
|
* C - set if error occurred
|
|
*
|
|
* Zero Page used: none
|
|
*
|
|
****************************************************************
|
|
*
|
|
|
|
Get_TempBuff PROC
|
|
with DirectPage
|
|
;
|
|
; get a temporary buffer
|
|
;
|
|
ldx #0 ;output Handle
|
|
phx
|
|
phx
|
|
phx
|
|
pha ;BlockSize
|
|
pea uTempBuff ;Owner
|
|
pea attrLocked ;Attributes
|
|
phx ;Location
|
|
phx
|
|
|
|
_NewHandle
|
|
plx ;Handle
|
|
ply
|
|
bcs error
|
|
;
|
|
; set TempBuff to address of temporary buffer
|
|
;
|
|
txa
|
|
jsr DeRef
|
|
sta TempBuff
|
|
sty TempBuff+2
|
|
|
|
return lda #0
|
|
clc
|
|
error rts
|
|
|
|
ENDP
|
|
|
|
TITLE ', MISC.a - Block_Move'
|
|
*
|
|
*************************************************************************
|
|
* BLOCK MOVE FOR NON-OVERLAPPING BLOCKS
|
|
* (converted from ProDOS code)
|
|
*
|
|
* Moves a block of data from a source location to a destination
|
|
* location. The source and destination blocks may overlap.
|
|
*
|
|
* Calling sequence:
|
|
* Place machine in full native mode (e=0, m=0, x=0)
|
|
* Push high order word of source pointer onto stack
|
|
* Push low order word of source pointer
|
|
* Push high order word of destination pointer
|
|
* Push low order word of destination pointer
|
|
* Push high order word of transfer count
|
|
* Push low order word of transfer count
|
|
* JSR Block_Move
|
|
* Outputs: None
|
|
* Side effects: Moves the block of data from source to destination
|
|
* Notes:
|
|
* The high byte of Source, Dest, and Count must be zero
|
|
* The Count may not be 0 or $FFFF.
|
|
* This routine contains self modifying code--it cannot run in ROM
|
|
*************************************************************************
|
|
*
|
|
|
|
Block_Move PROC
|
|
|
|
Source equ $0F ; 4-byte source address
|
|
Dest equ $0B ; 4-byte destination address
|
|
Count equ $07 ; 4-byte transfer count
|
|
ReturnMove equ $05 ; 3-byte return address
|
|
TempCount equ $03 ; 2-byte temporary transfer count
|
|
*
|
|
MoveBlock equ * ; main entry point
|
|
pha ; push two bytes on stack for TempCount
|
|
phd ; save D
|
|
tsc ; make direct page correspond to stack
|
|
tcd
|
|
*
|
|
* get ready to do the move
|
|
*
|
|
phb ; save DBR on stack (MVN trashes it)
|
|
phk ; set DBR to PBR
|
|
plb
|
|
ldx Source ; X = low word of Source
|
|
ldy Dest ; Y = low word of Dest
|
|
*
|
|
* set up the self modifying code to contain dst src
|
|
*
|
|
lda Dest+2 ; make sure high byte of Dest is 0
|
|
and #$00FF
|
|
sta Dest+2
|
|
lda Source+2 ; get source bank
|
|
and #$00FF ; make sure high byte of Source is 0
|
|
xba
|
|
ora Dest+2 ; or in destination bank (high byte must be zero)
|
|
sta DoMove+1 ; put bank values into MVN instruction (danger)
|
|
*
|
|
* check for illegal values of Count
|
|
*
|
|
lda Count
|
|
ora Count+2
|
|
beq exit
|
|
cmp #$FFFF
|
|
beq exit
|
|
*
|
|
* decrement Count because it contains actual transfer count whereas
|
|
* remainder of routine assumes it contains transfer count - 1
|
|
*
|
|
lda Count
|
|
bne @1
|
|
dec Count+2
|
|
@1
|
|
dec a
|
|
sta Count
|
|
*
|
|
* initialize TempCount
|
|
*
|
|
sta TempCount
|
|
bra mdFirst
|
|
*
|
|
* main move loop
|
|
*
|
|
mdMore sta Count+2 ; more bytes to move
|
|
lda >DoMove+1 ; A = SrcDst banks
|
|
cpx #1 ; bank cross? if X=0
|
|
bcs mdXNot0
|
|
adc #$0100 ; add 1 to source bank
|
|
mdXNot0 cpy #0 ; did destination cross bank?
|
|
bne mdYIs0
|
|
inc a
|
|
mdYIs0 sta >DoMove+1
|
|
mdFirst
|
|
txa ; if count > -X then bank cross
|
|
eor #$FFFF
|
|
cmp TempCount
|
|
bcs mdXOk
|
|
sta TempCount ; only move -X bytes
|
|
mdXOk tya ; will destination cross bank?
|
|
eor #$FFFF
|
|
cmp TempCount
|
|
bcs mdYOk
|
|
sta TempCount ; only move -Y bytes
|
|
mdYOk lda TempCount ; get the number of bytes to move
|
|
*
|
|
* the following 3 bytes are the actual move instruction
|
|
* this routine dynamically modifies the source and destination banks
|
|
*
|
|
DoMove DC.B $54 ; opcode for MVN
|
|
DS.B 1 ; destination bank
|
|
DS.B 1 ; source bank
|
|
*
|
|
lda Count ; Count = Count - bytes moved
|
|
clc ; actual bytes moved 1 more than count
|
|
sbc TempCount
|
|
sta Count
|
|
sta TempCount
|
|
lda Count+2
|
|
sbc #0
|
|
bpl mdMore
|
|
*
|
|
* clean up everything before returning
|
|
*
|
|
exit plb ; restore DBR
|
|
pld ; restore D
|
|
pla ; remove TempCount
|
|
*
|
|
lda #0
|
|
clc
|
|
Stack_Cleanup 12
|
|
rts ; go home
|
|
|
|
ENDP
|
|
|
|
TITLE ', MISC.a - MemMove'
|
|
****************************************************************
|
|
*
|
|
* pascal void MemMove(source, dest, n)
|
|
* char *source, *dest;
|
|
* int n;
|
|
*
|
|
* Description
|
|
* Copies 'n' characters from memory area 'source' to 'dest'.
|
|
* This function is the same as memcpy, except that can also
|
|
* work on overlapping objects.
|
|
*
|
|
* This was ripped off from the C library, and then modified
|
|
* to be somewhat call-compatible with BlockMove.
|
|
*
|
|
****************************************************************
|
|
|
|
MemMove Func
|
|
|
|
source equ $09
|
|
dest equ $05
|
|
n equ $03
|
|
|
|
tsc ;get current stack position
|
|
phd ;save current direct page
|
|
tcd ;set up local direct page
|
|
|
|
lda n ;check # of bytes to copy
|
|
beq exit ;if 0, don't bother!
|
|
bmi exit ;if negative, skip it
|
|
|
|
lda source ;get low word of source address
|
|
sec
|
|
sbc dest ;calculate difference
|
|
tax ;save in X for a bit
|
|
lda source+2 ;must do high word (to propogate carry)
|
|
sbc dest+2
|
|
bne normal ;if 'source' comes after 'dest', it doesn't matter
|
|
cpx n ;compare low word result against # of characters to move
|
|
bcs normal ;no overlap...
|
|
|
|
; use this block if 'source' starts in the midst of 'dest'
|
|
|
|
ldy #0 ;initialize index
|
|
sep #$20 ;8-bit accumulator
|
|
longa off
|
|
|
|
@loop
|
|
lda [source],y ;get a character
|
|
sta [dest],y ;store in destination
|
|
iny ;bump index
|
|
cpy n ;compare to # of characters to move
|
|
bcc @loop ;continue until done
|
|
bra done ;then exit
|
|
|
|
; use this block if there is no overlap or if 'dest' is higher in memory
|
|
; than 'source'
|
|
|
|
normal
|
|
ldy n ;get # of characters to move
|
|
sep #$20 ;shift into 8-bit accumulator
|
|
longa off
|
|
bra @do_it ;jump into loop
|
|
|
|
@loop
|
|
lda [source],y ;get a byte
|
|
sta [dest],y ;and copy it
|
|
@do_it
|
|
dey ;one less byte to move
|
|
bne @loop ;loop until at beginning of array
|
|
lda [source] ;copy the last (first) byte
|
|
sta [dest]
|
|
|
|
done
|
|
rep #$20 ;back to 16-bit accumulator
|
|
longa on
|
|
|
|
exit
|
|
pld
|
|
Stack_Cleanup 10
|
|
rts
|
|
|
|
endf
|
|
|
|
TITLE ', MISC.a - DeRefUse'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Combines DeRef and UsePtr
|
|
*
|
|
* Instead of:
|
|
*
|
|
* jsr DeRef
|
|
* jsr UsePtr
|
|
*
|
|
* call:
|
|
*
|
|
* jsr DeRefUse
|
|
*
|
|
****************************************************************
|
|
*
|
|
|
|
DeRefUse PROC
|
|
|
|
jsr UsePtr
|
|
lda |0,x
|
|
ldy |2,x
|
|
; jsr UsePtr
|
|
; rts
|
|
; fall into UsePtr
|
|
|
|
TITLE ', MISC.a - UsePtr'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Use Pointer setup
|
|
*
|
|
* Make a Pointer usable for indirect loading or storing
|
|
* without using Zero Page. Here is an example of how
|
|
* this routine is used. Suppose 'APtr' contains a Pointer
|
|
* to a Buffer and you want to extract the 1st 4 bytes
|
|
* out of the Buffer. Remember the Pointer and the Buffer
|
|
* can be anywhere in memory.
|
|
*
|
|
* lda APtr ;lo bytes of Pointer
|
|
* ldy APtr+2 ;hi bytes of Pointer
|
|
* phb ;save DBR
|
|
* jsr UsePtr ;call this routine
|
|
* lda |0,x ;get 1st two bytes
|
|
* ldy |2,x ;get 2nd two bytes
|
|
* plb ;restore DBR
|
|
*
|
|
* Inputs: A,Y - Pointer (Low bytes in A, High bytes in Y)
|
|
*
|
|
* Outputs: X - Low bytes of Pointer
|
|
* DBR - Bank of Pointer
|
|
*
|
|
****************************************************************
|
|
*
|
|
Entry UsePtr
|
|
UsePtr
|
|
tax ;move lo bytes into X
|
|
tya ;move hi bytes into A
|
|
xba ;get bank byte into B
|
|
pha ;bank + trash
|
|
plb ;remove trash
|
|
plb ;set bank to bank of Pointer
|
|
rts ;return
|
|
|
|
ENDP
|
|
|
|
TITLE ', MISC.a - DeRef'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Dereference a Handle
|
|
*
|
|
* Without using Zero Page
|
|
*
|
|
* Inputs: A,Y - Handle (Low bytes in A, High bytes in Y)
|
|
*
|
|
* Outputs: A,Y - Pointer (Low bytes in A, High bytes in Y)
|
|
* C - set if Pointer=0
|
|
*
|
|
****************************************************************
|
|
*
|
|
DeRef PROC
|
|
|
|
phb ;save DBR
|
|
phx ;save X
|
|
jsr UsePtr ;make Handle usable
|
|
clc
|
|
lda |0,x
|
|
ldy |2,x
|
|
pha ;save A
|
|
ora |2,x ;check whether pointer=0
|
|
bne cont
|
|
sec ;yes, set carry
|
|
cont pla ;restore A
|
|
plx ;restore X
|
|
plb ;restore DBR
|
|
rts ;return
|
|
|
|
ENDP
|
|
|
|
TITLE ', MISC.a - save_dp'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* saves contents of direct page
|
|
*
|
|
* Inputs: none
|
|
*
|
|
* Outputs: C - set if problem allocating memory
|
|
* Handle to allocated memory is returned on stack
|
|
*
|
|
****************************************************************
|
|
*
|
|
save_dp Proc
|
|
|
|
ldx #256 ;allocate 256 bytes
|
|
ldy #0
|
|
lda #uTempDP ;UserID
|
|
jsr do_alloc ;allocate some memory
|
|
bcs @nfg
|
|
pla ;remove return address
|
|
phy ;save handle on stack
|
|
phx
|
|
pha ;put return address back on stack
|
|
txa ;put low word into accumulator
|
|
jsr DeRef ;deref the handle
|
|
|
|
pea 0 ;make source pointer on stack
|
|
phd
|
|
|
|
phy ;put destination pointer on stack
|
|
pha
|
|
pea 0 ;put count on stack
|
|
pea 256
|
|
jsr Block_Move ;copy the block
|
|
lda 5,s ;duplicate handle on stack
|
|
pha
|
|
lda 5,s
|
|
pha
|
|
_HUnlock ;let the block float around if necessary
|
|
@nfg
|
|
rts
|
|
EndP
|
|
|
|
TITLE ', MISC.a - restore_dp'
|
|
*
|
|
****************************************************************
|
|
*
|
|
* restores previously saved direct page
|
|
*
|
|
* Inputs: Handle to saved direct page (on stack)
|
|
*
|
|
* Outputs: C - set if Acc != 0 on entry
|
|
*
|
|
****************************************************************
|
|
*
|
|
restore_dp Proc
|
|
with Globals
|
|
|
|
sta save_a ;save possible error code
|
|
plx ;pull return address
|
|
pla ;retrieve DP buffer handle
|
|
ply
|
|
phx ;put return address back on stack
|
|
phy ;put handle on stack
|
|
pha ;for eventual _DisposeHandle call
|
|
jsr DeRef ;deref the handle
|
|
phy ;put on stack as source address
|
|
pha
|
|
pea 0 ;put address of direct page on stack
|
|
phd ;as destination address
|
|
pea 0 ;count = 256
|
|
pea 256
|
|
jsr Block_Move ;go restore the direct page
|
|
_DisposeHandle ;release the DP buffer
|
|
lda save_a ;restore accumulator
|
|
cmp #$0001 ;condition carry
|
|
rts
|
|
EndP
|