mirror of
https://github.com/byteworksinc/ORCALib.git
synced 2024-11-16 04:10:08 +00:00
1 line
25 KiB
NASM
Executable File
1 line
25 KiB
NASM
Executable File
keep obj/cc
|
|
mcopy cc.macros
|
|
****************************************************************
|
|
*
|
|
* CC - C Specific Run Time Libraries
|
|
*
|
|
* October 1988
|
|
* Mike Westerfield
|
|
*
|
|
* Copyright 1988
|
|
* Byte Works, Inc.
|
|
*
|
|
****************************************************************
|
|
*
|
|
CC start dummy routine
|
|
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~CopyBF - Copy a bit field
|
|
* ~SaveBF - Save a bit field
|
|
*
|
|
* Inputs:
|
|
* addr - address to copy to
|
|
* bitDisp - displacement past the address
|
|
* bitNum - number of bits
|
|
* val - value to copy
|
|
*
|
|
****************************************************************
|
|
*
|
|
~CopyBF start
|
|
ret equ 2 return address
|
|
val equ 5 value to copy
|
|
bitNum equ 9 number of bits
|
|
bitDisp equ 11 displacement past the address
|
|
addr equ 13 address to copy to
|
|
|
|
lda #0 set the call type
|
|
bra lb1
|
|
~SaveBF entry
|
|
lda #1
|
|
lb1 phb
|
|
phk
|
|
plb
|
|
sta isSave
|
|
tsc set up the stack frame
|
|
phd
|
|
tcd
|
|
|
|
move4 val,lval save the value (for copybf only)
|
|
stz mask+2 set up the and mask
|
|
ldx bitNum
|
|
lda #0
|
|
lb2 sec
|
|
rol A
|
|
rol mask+2
|
|
dex
|
|
bne lb2
|
|
sta mask
|
|
and val and out extra bits in the mask
|
|
sta val
|
|
lda mask+2
|
|
and val+2
|
|
sta val+2
|
|
ldx bitDisp shift the mask and value
|
|
beq lb4
|
|
lda mask
|
|
lb3 asl A
|
|
rol mask+2
|
|
asl val
|
|
rol val+2
|
|
dex
|
|
bne lb3
|
|
sta mask
|
|
lb4 ldy #2 place the bits in memory
|
|
lda mask
|
|
eor #$FFFF
|
|
and [addr]
|
|
ora val
|
|
sta [addr]
|
|
lda mask+2
|
|
eor #$FFFF
|
|
and [addr],Y
|
|
ora val+2
|
|
sta [addr],Y
|
|
|
|
lda isSave branch based on call type
|
|
beq lb5
|
|
|
|
lda ret+1 return from save
|
|
sta addr+2
|
|
lda ret
|
|
sta addr+1
|
|
pld
|
|
plb
|
|
tsc
|
|
clc
|
|
adc #12
|
|
tcs
|
|
rtl
|
|
|
|
lb5 move4 lval,addr place the value back on the stack
|
|
lda ret+1 return from copy
|
|
sta bitDisp
|
|
lda ret
|
|
sta bitDisp-1
|
|
pld
|
|
plb
|
|
tsc
|
|
clc
|
|
adc #8
|
|
tcs
|
|
rtl
|
|
;
|
|
; local data
|
|
;
|
|
mask ds 4 bit mask
|
|
isSave ds 2 is the call a save? (or copy?)
|
|
lval ds 4 temp storage for val
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~C_ShutDown - do shut down peculiar to the C language
|
|
*
|
|
* Inputs:
|
|
* A - shell return code
|
|
*
|
|
****************************************************************
|
|
*
|
|
~C_ShutDown start
|
|
|
|
pha save the return code
|
|
jsr ~Exit do exit processing
|
|
pla quit
|
|
jml ~Quit
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~C_ShutDown2 - do shut down peculiar to the C language
|
|
*
|
|
* Inputs:
|
|
* A - shell return code
|
|
*
|
|
****************************************************************
|
|
*
|
|
~C_ShutDown2 start
|
|
|
|
pha save the return code
|
|
jsr ~Exit do exit processing
|
|
pla quit
|
|
jml ~RTL
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~C_StartUp - do startup peculiar to the C language
|
|
*
|
|
****************************************************************
|
|
*
|
|
~C_StartUp start
|
|
argv equ 11 argument vector
|
|
argc equ 9 argument count
|
|
cLine equ 1 command line address
|
|
|
|
TAB equ 9 TAB key code
|
|
|
|
phb remove our return address
|
|
phk
|
|
plb
|
|
plx
|
|
ply
|
|
pea 0 make room for argc, argv
|
|
pea 0
|
|
pea 0
|
|
phy put the return addr back on the stack
|
|
phx
|
|
ph4 ~CommandLine create some work space
|
|
tsc set up our stack frame
|
|
phd
|
|
tcd
|
|
|
|
stz ~ExitList no exit routines, yet
|
|
stz ~ExitList+2
|
|
case on
|
|
jsl ~InitIO reset standard I/O
|
|
case off
|
|
|
|
lda cLine if cLine == 0 then
|
|
ora cLine+2
|
|
jeq rtl exit
|
|
|
|
add4 cLine,#8 skip the shell identifier
|
|
ldx #0 count the arguments
|
|
txy
|
|
short M
|
|
lb2 lda [cLine],Y
|
|
beq lb6
|
|
cmp #' '
|
|
beq lb3
|
|
cmp #'"'
|
|
beq lb3
|
|
cmp #TAB
|
|
bne lb4
|
|
lb3 iny
|
|
bra lb2
|
|
lb4 inx
|
|
lb5 lda [cLine],Y
|
|
beq lb6
|
|
cmp #' '
|
|
beq lb2
|
|
cmp #'"'
|
|
beq lb2
|
|
cmp #TAB
|
|
beq lb2
|
|
iny
|
|
bra lb5
|
|
lb6 long M
|
|
txa we need (X+1)*4 + strlen(cLine)+1 bytes
|
|
inc A
|
|
asl A
|
|
asl A
|
|
sta start
|
|
phy
|
|
sec
|
|
adc 1,S
|
|
ply
|
|
pha
|
|
pha
|
|
pea 0
|
|
pha
|
|
ph2 >~User_ID
|
|
ph2 #$C008
|
|
ph4 #0
|
|
_NewHandle
|
|
bcc lb7
|
|
puts #'Out of memory',cr=t,errout=t
|
|
lda #-1
|
|
jml ~Quit
|
|
|
|
lb7 pl4 argv get the pointer to the area
|
|
ldy #2
|
|
lda [argv],Y
|
|
tax
|
|
lda [argv]
|
|
sta targv
|
|
stx targv+2
|
|
clc get a pointer to the command line string
|
|
adc start
|
|
bcc lb8
|
|
inx
|
|
lb8 sta argv
|
|
stx argv+2
|
|
short M move the command line string
|
|
ldy #0
|
|
lb9 lda [cLine],Y
|
|
sta [argv],Y
|
|
beq lb10
|
|
iny
|
|
bra lb9
|
|
lb10 long M
|
|
move4 argv,cLine save the pointer
|
|
move4 targv,argv set up the pointer to argv
|
|
|
|
av1 lda [cLine] skip leading spaces
|
|
and #$00FF
|
|
beq av8
|
|
cmp #' '
|
|
beq av2
|
|
cmp #TAB
|
|
bne av3
|
|
av2 inc4 cLine
|
|
bra av1
|
|
av3 tax save the argument
|
|
cmp #'"' if the argument is quoted then
|
|
bne av4
|
|
inc4 cLine skip the quote
|
|
av4 ldy #2 save the address in argv
|
|
lda cLine
|
|
sta [argv]
|
|
lda cLine+2
|
|
sta [argv],Y
|
|
add4 argv,#4
|
|
inc argc inc the # of arguments
|
|
cpx #'"' if the string is quoted then
|
|
bne av6
|
|
av5 lda [cLine] skip to the next quote
|
|
and #$00FF
|
|
beq av8
|
|
cmp #'"'
|
|
beq av7
|
|
inc4 cLine
|
|
bra av5 else
|
|
av6 lda [cLine] skip to the next whitespace char
|
|
and #$00FF
|
|
beq av8
|
|
cmp #' '
|
|
beq av7
|
|
cmp #TAB
|
|
beq av7
|
|
inc4 cLine
|
|
bra av6
|
|
av7 short M null terminate the parameter
|
|
lda #0
|
|
sta [cLine]
|
|
long M
|
|
bra av2 get the next parameter
|
|
av8 lda #0 null terminate the arg list
|
|
sta [argv]
|
|
ldy #2
|
|
sta [argv],Y
|
|
move4 targv,argv set up the pointer to argv
|
|
|
|
rtl pld return
|
|
pla
|
|
pla
|
|
plb
|
|
rtl
|
|
|
|
targv ds 4
|
|
start ds 2 start of the command line string
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~C_StartUp2 - do C startup for RTL pragma programs
|
|
*
|
|
****************************************************************
|
|
*
|
|
~C_StartUp2 start
|
|
|
|
phb remove our return address
|
|
phk
|
|
plb
|
|
plx
|
|
ply
|
|
pea 0 set argc, argv to 0
|
|
pea 0
|
|
pea 0
|
|
phy put the return addr back on the stack
|
|
phx
|
|
|
|
stz ~ExitList no exit routines, yet
|
|
stz ~ExitList+2
|
|
|
|
plb return
|
|
rtl
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~Exit - call exit routines and clean up open files
|
|
*
|
|
* Inputs:
|
|
* ~ExitList - list of exit routines
|
|
*
|
|
****************************************************************
|
|
*
|
|
~Exit start
|
|
ptr equ 3 pointer to exit routines
|
|
;
|
|
; Set up our stack frame
|
|
;
|
|
phb
|
|
phk
|
|
plb
|
|
ph4 ~ExitList set up our stack frame
|
|
phd
|
|
tsc
|
|
tcd
|
|
;
|
|
; Call the exit functions
|
|
;
|
|
lb1 lda ptr if the pointer is non-nil then
|
|
ora ptr+2
|
|
beq lb3
|
|
pea +(lb2-1)|-8 call the function
|
|
pea +(lb2-1)|8
|
|
phb
|
|
pla
|
|
ldy #5
|
|
lda [ptr],Y
|
|
pha
|
|
dey
|
|
dey
|
|
lda [ptr],Y
|
|
pha
|
|
phb
|
|
pla
|
|
rtl
|
|
lb2 ldy #2 dereference the pointer
|
|
lda [ptr],Y
|
|
tax
|
|
lda [ptr]
|
|
sta ptr
|
|
stx ptr+2
|
|
bra lb1
|
|
;
|
|
; Close (and flush) any open files
|
|
;
|
|
case on
|
|
lb3 lda >stderr+6 while there is a next file
|
|
ora >stderr+4
|
|
beq lb4
|
|
ph4 >stderr+4 close it
|
|
dc h'22' (jsl fclose, soft reference)
|
|
dc s3'fclose'
|
|
bra lb3
|
|
case off
|
|
;
|
|
; return
|
|
;
|
|
lb4 pld return
|
|
pla
|
|
pla
|
|
plb
|
|
rts
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~ExitList - list of exit routines
|
|
*
|
|
****************************************************************
|
|
*
|
|
~ExitList start
|
|
ds 4
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~IntChkC - check for integer math error
|
|
*
|
|
* Inputs:
|
|
* V - set for error
|
|
*
|
|
****************************************************************
|
|
*
|
|
~IntChkC start
|
|
|
|
bvc lb1 branch if no error
|
|
php
|
|
pha
|
|
phx
|
|
phy
|
|
error #9 integer math error
|
|
ply
|
|
plx
|
|
pla
|
|
plp
|
|
lb1 rtl
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~LoadBF - load a bit field
|
|
*
|
|
* Inputs:
|
|
* addr - address to load from
|
|
* bitDisp - displacement past the address
|
|
* bitNum - number of bits
|
|
*
|
|
****************************************************************
|
|
*
|
|
~LoadBF start
|
|
mask equ 1 bit mask
|
|
sign equ 5 sign mask
|
|
|
|
csubroutine (2:bitNum,2:bitDisp,4:addr),8
|
|
|
|
ldy #2 get the value
|
|
lda [addr],Y
|
|
tax
|
|
lda [addr]
|
|
sta addr
|
|
stx addr+2
|
|
ldx bitDisp normalize the value
|
|
beq lb2
|
|
lb1 lsr addr+2
|
|
ror addr
|
|
dex
|
|
bne lb1
|
|
lb2 stz mask form the bit and sign mask
|
|
lda #-1
|
|
sta sign
|
|
sta sign+2
|
|
lda #0
|
|
ldx bitNum
|
|
lb3 sec
|
|
rol A
|
|
rol mask
|
|
asl sign
|
|
rol sign+2
|
|
dex
|
|
bne lb3
|
|
sec adjust the sign flag
|
|
ror sign+2
|
|
ror sign
|
|
and addr and out the extra bits
|
|
sta addr
|
|
lda mask
|
|
and addr+2
|
|
sta addr+2
|
|
lda addr if the value is negative then
|
|
and sign
|
|
bne lb4
|
|
lda addr+2
|
|
and sign+2
|
|
beq lb5
|
|
lb4 lda addr or in the sign bits
|
|
ora sign
|
|
sta addr
|
|
lda addr+2
|
|
ora sign+2
|
|
sta addr+2
|
|
|
|
lb5 creturn 4:addr
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~LoadStruct - load a long value onto the stack
|
|
*
|
|
* Inputs:
|
|
* addr - address of the structure to load
|
|
* size - size of the structure
|
|
*
|
|
****************************************************************
|
|
*
|
|
~LoadStruct start
|
|
|
|
phb save the caller's data bank
|
|
pl4 >ret get the return address
|
|
plx get the transfer size
|
|
pla get the absolute save addr
|
|
sta >ad1+1
|
|
sta >ad2+1
|
|
plb set the data bank
|
|
phb remove the data bank & extra addr byte
|
|
pla
|
|
|
|
txa quit if there are no bytes to move
|
|
beq lb3
|
|
|
|
lsr a branch if the # of bytes is even
|
|
bcc lb1
|
|
dex move one byte
|
|
short M
|
|
ad1 lda ad1,X
|
|
pha
|
|
long M
|
|
txa
|
|
beq lb3
|
|
|
|
lb1 dex move the words
|
|
dex
|
|
bmi lb3
|
|
ad2 lda ad2,X
|
|
pha
|
|
bra lb1
|
|
|
|
lb3 ph4 >ret return to the caller
|
|
plb
|
|
rtl
|
|
;
|
|
; Local data
|
|
;
|
|
ret ds 4
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~LoadUBF - load an unsigned bit field
|
|
*
|
|
* Inputs:
|
|
* addr - address to load from
|
|
* bitDisp - displacement past the address
|
|
* bitNum - number of bits
|
|
*
|
|
****************************************************************
|
|
*
|
|
~LoadUBF start
|
|
mask equ 1 msw of bit mask
|
|
|
|
csubroutine (2:bitNum,2:bitDisp,4:addr),2
|
|
|
|
ldy #2 get the value
|
|
lda [addr],Y
|
|
tax
|
|
lda [addr]
|
|
sta addr
|
|
stx addr+2
|
|
ldx bitDisp normalize the value
|
|
beq lb2
|
|
lb1 lsr addr+2
|
|
ror addr
|
|
dex
|
|
bne lb1
|
|
lb2 stz mask form the bit mask
|
|
lda #0
|
|
ldx bitNum
|
|
lb3 sec
|
|
rol A
|
|
rol mask
|
|
dex
|
|
bne lb3
|
|
and addr and out the extra bits
|
|
sta addr
|
|
lda mask
|
|
and addr+2
|
|
sta addr+2
|
|
|
|
creturn 4:addr
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~LongMove2 - move some bytes
|
|
*
|
|
* Inputs:
|
|
* source - pointer to source bytes
|
|
* dest - pointer to destination bytes
|
|
* len - number of bytes to move
|
|
*
|
|
* Notes:
|
|
* This subroutine leaves the destination address on the
|
|
* stack. It is used by C for multiple assignment of
|
|
* arrays and structures. It differs from ~Move2 in that
|
|
* it can move 64K or more.
|
|
*
|
|
****************************************************************
|
|
*
|
|
~LongMove2 start
|
|
|
|
csubroutine (4:len,4:source),0
|
|
dest equ source+4
|
|
|
|
ldx len+2 move whole banks
|
|
beq lm2
|
|
ldy #0
|
|
lm1 lda [source],Y
|
|
sta [dest],Y
|
|
dey
|
|
dey
|
|
bne lm1
|
|
inc source+2
|
|
inc dest+2
|
|
dex
|
|
bne lm1
|
|
lm2 lda len move one byte if the move length is odd
|
|
lsr a
|
|
bcc lb1
|
|
short M
|
|
lda [source]
|
|
sta [dest]
|
|
long M
|
|
inc4 source
|
|
inc4 dest
|
|
dec len
|
|
lb1 ldy len move the bytes
|
|
beq lb4
|
|
dey
|
|
dey
|
|
beq lb3
|
|
lb2 lda [source],Y
|
|
sta [dest],Y
|
|
dey
|
|
dey
|
|
bne lb2
|
|
lb3 lda [source]
|
|
sta [dest]
|
|
lb4 creturn
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~LShr4 - Shift an unsigned long value right
|
|
*
|
|
* Inputs:
|
|
* A - value to shift
|
|
* X - # bits to shift by
|
|
*
|
|
* Outputs:
|
|
* A - result
|
|
*
|
|
****************************************************************
|
|
*
|
|
~LShr4 start
|
|
num1 equ 8 number to shift
|
|
num2 equ 4 # bits to shift by
|
|
|
|
tsc set up DP
|
|
phd
|
|
tcd
|
|
lda num2+2 if num2 < 0 then
|
|
bpl lb2
|
|
cmp #$FFFF shift left
|
|
bne zero
|
|
ldx num2
|
|
cpx #-34
|
|
blt zero
|
|
lb1 asl num1
|
|
rol num1+2
|
|
inx
|
|
bne lb1
|
|
bra lb4
|
|
zero stz num1 (result is zero)
|
|
stz num1+2
|
|
bra lb4
|
|
lb2 bne zero else shift right
|
|
ldx num2
|
|
beq lb4
|
|
cpx #33
|
|
bge zero
|
|
lb3 lsr num1+2
|
|
ror num1
|
|
dex
|
|
bne lb3
|
|
|
|
lb4 lda 0 fix stack and return
|
|
sta num2
|
|
lda 2
|
|
sta num2+2
|
|
pld
|
|
pla
|
|
pla
|
|
rtl
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~Move2 - move some bytes
|
|
*
|
|
* Inputs:
|
|
* source - pointer to source bytes
|
|
* dest - pointer to destination bytes
|
|
* len - number of bytes to move
|
|
*
|
|
* Notes:
|
|
* This subroutine leaves the destination address on the
|
|
* stack. It is used by C for multiple assignment of
|
|
* arrays and structures.
|
|
*
|
|
****************************************************************
|
|
*
|
|
~Move2 start
|
|
|
|
csubroutine (2:len,4:source),0
|
|
dest equ source+4
|
|
|
|
lda len move one byte if the move length is odd
|
|
lsr a
|
|
bcc lb1
|
|
short M
|
|
lda [source]
|
|
sta [dest]
|
|
long M
|
|
inc4 source
|
|
inc4 dest
|
|
dec len
|
|
lb1 ldy len move the bytes
|
|
beq lb4
|
|
dey
|
|
dey
|
|
beq lb3
|
|
lb2 lda [source],Y
|
|
sta [dest],Y
|
|
dey
|
|
dey
|
|
bne lb2
|
|
lb3 lda [source]
|
|
sta [dest]
|
|
lb4 creturn
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* extern pascal PDosInt(int callNum, void *parm)
|
|
*
|
|
* Make a ProDOS or shell call
|
|
*
|
|
* Inputs:
|
|
* callNum - ProDOS call number
|
|
* parm - address of the parameter block
|
|
*
|
|
****************************************************************
|
|
*
|
|
PDOSINT start
|
|
ProDOS equ $E100A8
|
|
|
|
csubroutine (4:parm,2:callNum),0
|
|
|
|
lda callNum
|
|
sta >lb1
|
|
lda parm
|
|
sta >lb2
|
|
lda parm+2
|
|
sta >lb2+2
|
|
jsl ProDOS
|
|
lb1 ds 2
|
|
lb2 ds 4
|
|
sta >~TOOLERROR
|
|
|
|
creturn
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~UDiv4 - Four byte unsigned integer divide
|
|
*
|
|
* Inputs:
|
|
* num1 - numerator
|
|
* X-A - denominator
|
|
*
|
|
* Outputs:
|
|
* ans - result
|
|
*
|
|
****************************************************************
|
|
*
|
|
~UDiv4 start
|
|
num1 equ 12 arguments
|
|
ans equ 1 answer
|
|
rem equ 5 remainder
|
|
return equ 9
|
|
;
|
|
; Initialize
|
|
;
|
|
tay place the values in the correct spot
|
|
pea 0 on the stack frame
|
|
pea 0
|
|
lda 10,S
|
|
pha
|
|
lda 10,S
|
|
pha
|
|
tsc set up DP
|
|
phd
|
|
tcd
|
|
sty num1
|
|
stx num1+2
|
|
tya check for division by zero
|
|
ora num1+2
|
|
beq dv10
|
|
|
|
lda num1+2 do 16 bit divides separately
|
|
ora ans+2
|
|
beq dv5
|
|
;
|
|
; 32 bit divide
|
|
;
|
|
ldy #32 32 bits to go
|
|
dv3 asl ans roll up the next number
|
|
rol ans+2
|
|
rol ans+4
|
|
rol ans+6
|
|
sec subtract for this digit
|
|
lda ans+4
|
|
sbc num1
|
|
tax
|
|
lda ans+6
|
|
sbc num1+2
|
|
bcc dv4 branch if minus
|
|
stx ans+4 turn the bit on
|
|
sta ans+6
|
|
inc ans
|
|
dv4 dey next bit
|
|
bne dv3
|
|
bra dv9 go do the sign
|
|
;
|
|
; 16 bit divide
|
|
;
|
|
dv5 lda #0 initialize the remainder
|
|
ldy #16 16 bits to go
|
|
dv6 asl ans roll up the next number
|
|
rol a
|
|
sec subtract the digit
|
|
sbc num1
|
|
bcs dv7
|
|
adc num1 digit is 0
|
|
dey
|
|
bne dv6
|
|
bra dv8
|
|
dv7 inc ans digit is 1
|
|
dey
|
|
bne dv6
|
|
|
|
dv8 sta ans+4 save the remainder
|
|
;
|
|
; Return the result
|
|
;
|
|
dv9 move4 ans,num1 move answer
|
|
dv10 pld return
|
|
tsc
|
|
clc
|
|
adc #8
|
|
tcs
|
|
rtl
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~UMod4 - Four byte unsigned integer remainder
|
|
*
|
|
* Inputs:
|
|
* num1 - numerator
|
|
* X-A - denominator
|
|
*
|
|
* Outputs:
|
|
* ans - result
|
|
*
|
|
****************************************************************
|
|
*
|
|
~UMod4 start
|
|
num1 equ 12 arguments
|
|
ans equ 1 answer
|
|
rem equ 5 remainder
|
|
return equ 9
|
|
;
|
|
; Initialize
|
|
;
|
|
tay place the values in the correct spot
|
|
pea 0 on the stack frame
|
|
pea 0
|
|
lda 10,S
|
|
pha
|
|
lda 10,S
|
|
pha
|
|
tsc set up DP
|
|
phd
|
|
tcd
|
|
sty num1
|
|
stx num1+2
|
|
tya check for division by zero
|
|
ora num1+2
|
|
beq dv10
|
|
|
|
lda num1+2 do 16 bit divides separately
|
|
ora ans+2
|
|
beq dv5
|
|
;
|
|
; 32 bit divide
|
|
;
|
|
ldy #32 32 bits to go
|
|
dv3 asl ans roll up the next number
|
|
rol ans+2
|
|
rol ans+4
|
|
rol ans+6
|
|
sec subtract for this digit
|
|
lda ans+4
|
|
sbc num1
|
|
tax
|
|
lda ans+6
|
|
sbc num1+2
|
|
bcc dv4 branch if minus
|
|
stx ans+4 turn the bit on
|
|
sta ans+6
|
|
inc ans
|
|
dv4 dey next bit
|
|
bne dv3
|
|
bra dv9 go do the sign
|
|
;
|
|
; 16 bit divide
|
|
;
|
|
dv5 lda #0 initialize the remainder
|
|
ldy #16 16 bits to go
|
|
dv6 asl ans roll up the next number
|
|
rol a
|
|
sec subtract the digit
|
|
sbc num1
|
|
bcs dv7
|
|
adc num1 digit is 0
|
|
dey
|
|
bne dv6
|
|
bra dv8
|
|
dv7 inc ans digit is 1
|
|
dey
|
|
bne dv6
|
|
|
|
dv8 sta ans+4 save the remainder
|
|
;
|
|
; Return the result
|
|
;
|
|
dv9 move4 ans+4,num1 move answer
|
|
dv10 pld return
|
|
tsc
|
|
clc
|
|
adc #8
|
|
tcs
|
|
rtl
|
|
end
|
|
|
|
****************************************************************
|
|
*
|
|
* ~Zero - zero an area of direct page memory
|
|
*
|
|
* Inputs:
|
|
* addr - address of the memory
|
|
* size - number of bytes to zero (must be > 1)
|
|
*
|
|
****************************************************************
|
|
*
|
|
~Zero start
|
|
|
|
csubroutine (2:size,4:addr),0
|
|
|
|
lda #0
|
|
sta [addr]
|
|
ldx addr
|
|
txy
|
|
iny
|
|
lda size
|
|
dea
|
|
dea
|
|
phb
|
|
mvn 0,0
|
|
plb
|
|
|
|
creturn
|
|
end
|