239 lines 6.3 KiB NASM Raw Permalink Blame History

 ``` mcopy dag.macros ``` ```**************************************************************** ``` ```* ``` ```* function udiv(x,y: longint): longint; ``` ```* ``` ```* Inputs: ``` ```* num1 - numerator ``` ```* num2 - denominator ``` ```* ``` ```* Outputs: ``` ```* ans - result ``` ```* ``` ```**************************************************************** ``` ```* ``` ```udiv start ``` ```ans equ 0 answer ``` ```rem equ 4 remainder ``` ``` ``` ``` subroutine (4:num1,4:num2),8 ``` ```; ``` ```; Initialize ``` ```; ``` ``` stz rem rem = 0 ``` ``` stz rem+2 ``` ``` move4 num1,ans ans = num1 ``` ``` lda num2 check for division by zero ``` ``` ora num2+2 ``` ``` beq dv9 ``` ``` ``` ``` lda num2+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 num2 ``` ``` tax ``` ``` lda ans+6 ``` ``` sbc num2+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 num2 ``` ``` bcs dv7 ``` ``` adc num2 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 return 4:ans move answer ``` ``` end ``` ``` ``` ```**************************************************************** ``` ```* ``` ```* function umod(x,y: longint): longint; ``` ```* ``` ```* Inputs: ``` ```* num1 - numerator ``` ```* num2 - denominator ``` ```* ``` ```* Outputs: ``` ```* ans+4 - result ``` ```* ``` ```**************************************************************** ``` ```* ``` ```umod start ``` ```ans equ 0 answer ``` ```rem equ 4 remainder ``` ``` ``` ``` subroutine (4:num1,4:num2),8 ``` ```; ``` ```; Initialize ``` ```; ``` ``` stz rem rem = 0 ``` ``` stz rem+2 ``` ``` move4 num1,ans ans = num1 ``` ``` lda num2 check for division by zero ``` ``` ora num2+2 ``` ``` beq dv9 ``` ``` ``` ``` lda num2+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 num2 ``` ``` tax ``` ``` lda ans+6 ``` ``` sbc num2+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 num2 ``` ``` bcs dv7 ``` ``` adc num2 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 return 4:ans+4 move answer ``` ``` end ``` ``` ``` ```**************************************************************** ``` ```* ``` ```* function umul(x,y: longint): longint; ``` ```* ``` ```* Inputs: ``` ```* num2,num1 - operands ``` ```* ``` ```* Outputs: ``` ```* ans - result ``` ```* ``` ```**************************************************************** ``` ```* ``` ```umul start ``` ```ans equ 0 answer ``` ``` ``` ``` subroutine (4:num1,4:num2),8 ``` ```; ``` ```; Initialize the sign and split on precision. ``` ```; ``` ``` stz ans+4 set up the multiplier ``` ``` stz ans+6 ``` ``` lda num1 ``` ``` sta ans ``` ``` lda num1+2 ``` ``` sta ans+2 ``` ``` beq ml3 branch if the multiplier is 16 bit ``` ```; ``` ```; Do a 32 bit by 32 bit multiply. ``` ```; ``` ``` ldy #32 32 bit multiply ``` ``` jsr ml1 ``` ``` brl ml7 ``` ``` ``` ```ml1 lda ans SYSS1*SYSS1+2+SYSS1+2 -> SYSS1,SYSS1+2 ``` ``` lsr a ``` ``` bcc ml2 ``` ``` clc add multiplicand to the partial product ``` ``` lda ans+4 ``` ``` adc num2 ``` ``` sta ans+4 ``` ``` lda ans+6 ``` ``` adc num2+2 ``` ``` sta ans+6 ``` ```ml2 ror ans+6 shift the interem result ``` ``` ror ans+4 ``` ``` ror ans+2 ``` ``` ror ans ``` ``` dey loop til done ``` ``` bne ml1 ``` ``` rts ``` ```; ``` ```; Do and 16 bit by 32 bit multiply. ``` ```; ``` ```ml3 lda num2+2 branch if 16x16 is possible ``` ``` beq ml4 ``` ``` ``` ``` ldy #16 set up for 16 bits ``` ``` jsr ml1 do the multiply ``` ``` lda ans+2 move the answer ``` ``` sta ans ``` ``` lda ans+4 ``` ``` sta ans+2 ``` ``` bra ml7 ``` ```; ``` ```; Do a 16 bit by 16 bit multiply. ``` ```; ``` ```ml4 ldy #16 set the 16 bit counter ``` ``` ldx ans move the low word ``` ``` stx ans+2 ``` ```ml5 lsr ans+2 test the bit ``` ``` bcc ml6 branch if the bit is off ``` ``` clc ``` ``` adc num2 ``` ```ml6 ror a shift the answer ``` ``` ror ans ``` ``` dey loop ``` ``` bne ml5 ``` ``` sta ans+2 save the high word ``` ```; ``` ```; Return the result. ``` ```; ``` ```ml7 return 4:ans fix the stack ``` ``` end ```