multiplications

This commit is contained in:
Irmen de Jong 2018-12-20 23:28:03 +01:00
parent 9ffc68acab
commit ee893e5a2c
11 changed files with 262 additions and 103 deletions

View File

@ -1,6 +1,6 @@
set PROG8_LIBDIR=../prog8lib
set PROG8CLASSPATH=out/production/compiler/
set KOTLINPATH=%USERPROFILE%/.IdeaIC2018.3/config/plugins/Kotlin
set LIBJARS=%KOTLINPATH%/lib/kotlin-stdlib.jar;%KOTLINPATH%/lib/kotlin-reflect.jar;antlr/lib/antlr-runtime-4.7.1.jar
set LIBJARS=%KOTLINPATH%/lib/kotlin-stdlib.jar;%KOTLINPATH%/lib/kotlin-reflect.jar;antlr/lib/antlr-runtime-4.7.2.jar
java -Dprog8.libdir=%PROG8_LIBDIR% -cp %PROG8CLASSPATH%;%LIBJARS% prog8.CompilerMainKt %*

View File

@ -3,6 +3,6 @@
PROG8_LIBDIR=../prog8lib
PROG8CLASSPATH=out/production/compiler
KOTLINPATH=${HOME}/.IntelliJIdea2018.3/config/plugins/Kotlin
LIBJARS=${KOTLINPATH}/lib/kotlin-stdlib.jar:${KOTLINPATH}/lib/kotlin-reflect.jar:antlr/lib/antlr-runtime-4.7.1.jar
LIBJARS=${KOTLINPATH}/lib/kotlin-stdlib.jar:${KOTLINPATH}/lib/kotlin-reflect.jar:antlr/lib/antlr-runtime-4.7.2.jar
java -Dprog8.libdir=${PROG8_LIBDIR} -cp ${PROG8CLASSPATH}:${LIBJARS} prog8.CompilerMainKt $*

View File

@ -6,23 +6,127 @@
;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation???!!!
; @todo unify the type cast functions... "wrd(5)" -> "5 as word"
; @todo docs: "integer / int will not result in float but is integer floor division." verify this!
sub toscreenx(float x, float z) -> word {
return 42.w as word
}
asmsub blerp(ubyte x @ A, uword ding @ XY) -> clobbers() -> () {
word qq = A as word
}
sub start() {
word x = toscreenx(1.22, 3.22)
blerp(4, 555)
ubyte ub1
ubyte ub2
ubyte ub3
byte b1
byte b2
byte b3
uword uw1
uword uw2
uword uw3
word w1
word w2
word w3
float f1
float f2
float f3
c64scr.print(" X=")
c64scr.print_ub(X)
c64.CHROUT('\n')
ub1=20
ub2=6
ub3=ub1*ub2
c64scr.print_ub(ub3) ; 120
c64.CHROUT('\n')
uw1=900
uw2=66
uw3=uw1*uw2
c64scr.print_uw(uw3) ; 59400
c64.CHROUT('\n')
b1=20
b2=6
b3=b1*b2
c64scr.print_b(b3) ; 120
c64.CHROUT('\n')
w1=500
w2=44
w3=w1*w2
c64scr.print_w(w3) ; 22000
c64.CHROUT('\n')
b1=20
b2=-6
b3=b1*b2
c64scr.print_b(b3) ; -120
c64.CHROUT('\n')
w1=500
w2=-44
w3=w1*w2
c64scr.print_w(w3) ; -22000
c64.CHROUT('\n')
b1=-20
b2=-6
b3=b1*b2
c64scr.print_b(b3) ; 120
c64.CHROUT('\n')
w1=-500
w2=-44
w3=w1*w2
c64scr.print_w(w3) ; 22000
c64.CHROUT('\n')
f1=-500.11
f2=44.4
f3=f1*f2
c64flt.print_f(f3)
c64.CHROUT('\n')
; ub3 = 200/67 as ubyte
; ub3 = 200//67
; c64scr.print_ub(ub3)
; c64.CHROUT('\n')
; ub3 = ub1/ub2
; c64scr.print_ub(ub3)
; c64.CHROUT('\n')
; ub3 = ub1//ub2
; c64scr.print_ub(ub3)
; c64.CHROUT('\n')
;
; uw3 = 2000/67 as uword
; c64scr.print_uw(uw3)
; c64.CHROUT('\n')
; uw3 = 2000//67
; c64scr.print_uw(uw3)
; c64.CHROUT('\n')
; uw3 = uw1/uw2
; c64scr.print_uw(uw3)
; c64.CHROUT('\n')
; uw3 = uw1//uw2
; c64scr.print_uw(uw3)
; c64.CHROUT('\n')
;
; f3 = 999/44
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = 999//44
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = f1/f2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = f1//f2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = ub1/ub2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = ub1//ub2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = uw1/uw2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
; f3 = uw1//uw2
; c64flt.print_f(f3)
; c64.CHROUT('\n')
c64scr.print(" X=")
c64scr.print_ub(X)
c64.CHROUT('\n')
; const byte width=20
; word w1
@ -36,10 +140,10 @@
; c64scr.print_byte(b1)
; c64.CHROUT('\n')
; ub1 = b2ub(fintb(x * flt(width)/4.2) + width//2)
; c64scr.print_ubyte(ub1)
; c64scr.print_ub(ub1)
; c64.CHROUT('\n')
; ub1 = b2ub(fintb(x/4.2 * flt(width)) + width//2)
; c64scr.print_ubyte(ub1)
; c64scr.print_ub(ub1)
; c64.CHROUT('\n')
; w1 = fintw(x * flt(width)/4.2) + width//2
; c64scr.print_word(w1)

View File

@ -895,7 +895,7 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
}
DataType.FLOAT -> when(rightDt) {
in NumericDatatypes -> DataType.WORD
in NumericDatatypes -> DataType.FLOAT
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
}
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")

View File

@ -55,7 +55,7 @@ enum class Opcode {
DIV_UW,
DIV_W,
DIV_F,
FLOORDIV,
FLOORDIV, // integer division but on floatint point argument(s)
REMAINDER_UB,
REMAINDER_B,
REMAINDER_UW,

View File

@ -410,7 +410,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, numericValue())
DataType.WORD -> Value(DataType.WORD, numericValue())
DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}
DataType.BYTE -> {
@ -420,7 +420,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535)
DataType.WORD -> Value(DataType.WORD, integerValue())
DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}
DataType.UWORD -> {
@ -434,7 +434,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
Value(DataType.WORD, -(65536-integerValue()))
}
DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}
DataType.WORD -> {
@ -443,7 +443,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535)
DataType.WORD -> this
DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}
DataType.FLOAT -> {
@ -453,7 +453,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
if(integer in -128..127)
Value(DataType.BYTE, integer)
else
throw AstException("overflow when casting float to byte: $this")
throw AstException("overflow when casting float to byte: $this") // @todo ast-check for this
}
DataType.UBYTE -> Value(DataType.UBYTE, numericValue().toInt() and 255)
DataType.UWORD -> Value(DataType.UWORD, numericValue().toInt() and 65535)
@ -462,13 +462,13 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
if(integer in -32768..32767)
Value(DataType.WORD, integer)
else
throw AstException("overflow when casting float to word: $this")
throw AstException("overflow when casting float to word: $this") // @todo ast-check for this
}
DataType.FLOAT -> this
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}
else -> throw ValueException("invalid type cast from $type to $targetType")
else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this
}
}

View File

@ -690,11 +690,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " ${signExtendA("${ESTACK_HI+1},x")}" // sign extend the lsb @todo missing an lda???
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
Opcode.DIV_UB -> " jsr prog8_lib.div_ub"
Opcode.DIV_B -> " jsr prog8_lib.div_b"
Opcode.DIV_F -> " jsr prog8_lib.div_f"
Opcode.DIV_W -> " jsr prog8_lib.div_w"
Opcode.DIV_UW -> " jsr prog8_lib.div_uw"
Opcode.ADD_UB, Opcode.ADD_B -> {
"""
lda ${(ESTACK_LO + 2).toHex()},x
@ -713,15 +708,19 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
sta ${(ESTACK_LO + 1).toHex()},x
"""
}
Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_w"
Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_word"
Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_word"
Opcode.MUL_B, Opcode.MUL_UB -> " jsr prog8_lib.mul_byte"
Opcode.MUL_W, Opcode.MUL_UW -> " jsr prog8_lib.mul_word"
Opcode.ADD_F -> " jsr prog8_lib.add_f"
Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_w"
Opcode.SUB_F -> " jsr prog8_lib.sub_f"
Opcode.MUL_B -> " jsr prog8_lib.mul_b"
Opcode.MUL_UB -> " jsr prog8_lib.mul_ub"
Opcode.MUL_W -> " jsr prog8_lib.mul_w"
Opcode.MUL_UW -> " jsr prog8_lib.mul_uw"
Opcode.MUL_F -> " jsr prog8_lib.mul_f"
Opcode.DIV_UB -> " jsr prog8_lib.div_ub"
Opcode.DIV_B -> " jsr prog8_lib.div_b"
Opcode.DIV_F -> " jsr prog8_lib.div_f"
Opcode.DIV_W -> " jsr prog8_lib.div_w"
Opcode.DIV_UW -> " jsr prog8_lib.div_uw"
Opcode.FLOORDIV -> " jsr prog8_lib.floordiv_f"
Opcode.AND_BYTE -> {
"""

View File

@ -432,11 +432,13 @@ You can also reference idendifiers defined elsewhere in your code.
will be automatically converted into floats in this case. The compiler will issue a warning though when this happens, because floating
point calculations are very slow and possibly unintended!
Calculations with integers will not result in floating point values;
if you divide two integer values (say: ``32500 / 99``) the result will be the integer floor
Calculations with integer variables will not result in floating point values.
if you divide two integer variables say 32500 and 99 the result will be the integer floor
division (328) rather than the floating point result (328.2828282828283). If you need the full precision,
you'll have to make sure at least the first operand is a floating point. So write ``32500.0 / 99.0``,
or use the type cast ``value as float``.
you'll have to make sure at least the first operand is a floating point. You can do this by
using a floating point value or variable, or use a type cast.
When the compiler can calculate the result during compile-time, it will try to avoid loss
of precision though and gives an error if you may be losing a floating point result.

View File

@ -280,7 +280,7 @@ asmsub GETADRAY () -> clobbers(X) -> (uword @ AY) {
}}
}
sub print_float (float value) {
sub print_f (float value) {
; ---- prints the floating point value (without a newline) using basic rom routines.
; clobbers no registers.
; @todo version that takes A/Y pointer to float instead
@ -290,8 +290,8 @@ sub print_float (float value) {
pha
txa
pha
lda #<print_float_value
ldy #>print_float_value
lda #<print_f_value
ldy #>print_f_value
jsr c64.MOVFM ; load float into fac1
jsr c64.FOUT ; fac1 to string in A/Y
jsr c64.STROUT ; print string in A/Y
@ -304,7 +304,7 @@ sub print_float (float value) {
}}
}
sub print_float_ln (float value) {
sub print_fln (float value) {
; ---- prints the floating point value (with a newline at the end) using basic rom routines
; clobbers no registers.
; @todo version that takes A/Y pointer to float instead
@ -314,8 +314,8 @@ sub print_float_ln (float value) {
pha
txa
pha
lda #<print_float_ln_value
ldy #>print_float_ln_value
lda #<print_fln_value
ldy #>print_fln_value
jsr c64.MOVFM ; load float into fac1
jsr c64.FPRINTLN ; print fac1 with newline
pla
@ -579,7 +579,7 @@ _scroll_screen ; scroll the screen memory
asmsub print_string (str text @ AY) -> clobbers(A,Y) -> () {
asmsub print (str text @ AY) -> clobbers(A,Y) -> () {
; ---- print null terminated string from A/Y
; note: the compiler contains an optimization that will replace
; a call to this subroutine with a string argument of just one char,
@ -598,7 +598,7 @@ asmsub print_string (str text @ AY) -> clobbers(A,Y) -> () {
}
asmsub print_pstring (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
asmsub print_p (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
; ---- print pstring (length as first byte) from A/Y, returns str len in Y
%asm {{
sta c64.SCRATCH_ZPB1
@ -617,7 +617,7 @@ asmsub print_pstring (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
}
asmsub print_ubyte0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ub0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
%asm {{
jsr c64utils.ubyte2decimal
@ -632,7 +632,7 @@ asmsub print_ubyte0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
}
asmsub print_ubyte (ubyte value @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ub (ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in decimal form, without left padding 0s
%asm {{
jsr c64utils.ubyte2decimal
@ -653,7 +653,7 @@ _print_tens txa
}}
}
asmsub print_byte (byte value @ A) -> clobbers(A,X,Y) -> () {
asmsub print_b (byte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the byte in A in decimal form, without left padding 0s
%asm {{
pha
@ -663,12 +663,12 @@ asmsub print_byte (byte value @ A) -> clobbers(A,X,Y) -> () {
jsr c64.CHROUT
+ pla
jsr c64utils.byte2decimal
jmp print_ubyte._print_byte_digits
jmp print_ub._print_byte_digits
}}
}
asmsub print_ubyte_hex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () {
asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () {
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
bcc +
@ -684,21 +684,21 @@ asmsub print_ubyte_hex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y)
}
asmsub print_uword_hex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in hexadecimal form (4 digits)
; (if Carry is set, a radix prefix '$' is printed as well)
%asm {{
pha
tya
jsr print_ubyte_hex
jsr print_ubhex
pla
clc
jmp print_ubyte_hex
jmp print_ubhex
}}
}
asmsub print_uword0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uw0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
; @todo shorter in loop form?
%asm {{
@ -717,7 +717,7 @@ asmsub print_uword0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
}
asmsub print_uword (uword value @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_uw (uword value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the uword in A/Y in decimal form, without left padding 0s
%asm {{
jsr c64utils.uword2decimal
@ -749,7 +749,7 @@ _pr_decimal
}}
}
asmsub print_word (word value @ AY) -> clobbers(A,X,Y) -> () {
asmsub print_w (word value @ AY) -> clobbers(A,X,Y) -> () {
; ---- print the (signed) word in A/Y in decimal form, without left padding 0s
%asm {{
cpy #0
@ -766,7 +766,7 @@ asmsub print_word (word value @ AY) -> clobbers(A,X,Y) -> () {
adc #1
bcc +
iny
+ jmp print_uword
+ jmp print_uw
}}
}

View File

@ -19,19 +19,19 @@
asmsub multiply_bytes (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) -> (ubyte @ A) {
asmsub multiply_bytes (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers() -> (ubyte @ A) {
; ---- multiply 2 bytes, result as byte in A (signed or unsigned)
%asm {{
sta SCRATCH_ZPB1
sty SCRATCH_ZPREG
ldx #8
- asl a
asl SCRATCH_ZPB1
bcc +
clc
adc SCRATCH_ZPREG
+ dex
bne -
sta SCRATCH_ZPB1 ; num1
sty SCRATCH_ZPREG ; num2
lda #0
beq _enterloop
_doAdd clc
adc SCRATCH_ZPB1
_loop asl SCRATCH_ZPB1
_enterloop lsr SCRATCH_ZPREG
bcs _doAdd
bne _loop
rts
}}
}
@ -58,41 +58,42 @@ asmsub multiply_bytes_16 (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) ->
}}
}
word[2] multiply_words_product = 0
asmsub multiply_words (uword number @ AY) -> clobbers(A,X) -> () {
; ---- multiply two 16-bit words into a 32-bit result
; ---- multiply two 16-bit words into a 32-bit result (signed and unsigned)
; input: A/Y = first 16-bit number, SCRATCH_ZPWORD1 in ZP = second 16-bit number
; output: multiply_words_product 32-bits product, LSB order (low-to-high)
; output: multiply_words.result 4-bytes/32-bits product, LSB order (low-to-high)
%asm {{
sta SCRATCH_ZPWORD2
sty SCRATCH_ZPWORD2+1
mult16 lda #$00
sta multiply_words_product+2 ; clear upper bits of product
sta multiply_words_product+3
sta multiply_words_result+2 ; clear upper bits of product
sta multiply_words_result+3
ldx #16 ; for all 16 bits...
- lsr SCRATCH_ZPWORD1+1 ; divide multiplier by 2
ror SCRATCH_ZPWORD1
bcc +
lda multiply_words_product+2 ; get upper half of product and add multiplicand
lda multiply_words_result+2 ; get upper half of product and add multiplicand
clc
adc SCRATCH_ZPWORD2
sta multiply_words_product+2
lda multiply_words_product+3
sta multiply_words_result+2
lda multiply_words_result+3
adc SCRATCH_ZPWORD2+1
+ ror a ; rotate partial product
sta multiply_words_product+3
ror multiply_words_product+2
ror multiply_words_product+1
ror multiply_words_product
sta multiply_words_result+3
ror multiply_words_result+2
ror multiply_words_result+1
ror multiply_words_result
dex
bne -
rts
multiply_words_result .fill 4
}}
}
asmsub divmod_bytes (ubyte number @ X, ubyte divisor @ Y) -> clobbers() -> (ubyte @ X, ubyte @ A) {
; ---- divide X by Y, result quotient in X, remainder in A (unsigned)
; division by zero will result in quotient = 255 and remainder = original number

View File

@ -316,7 +316,18 @@ push_fac1_as_result .proc
jmp push_float
.pend
floordiv_f .proc
; -- push f1//f2 on stack
jsr pop_2_floats_f2_in_fac1
stx SCRATCH_ZPREGX
lda #<fmath_float1
ldy #>fmath_float1
jsr c64.FDIV
jsr c64.INT
jmp push_fac1_as_result
.pend
div_f .proc
; -- push f1/f2 on stack
jsr pop_2_floats_f2_in_fac1
@ -465,47 +476,80 @@ sub_w .proc
rts
.pend
mul_b .proc
mul_byte .proc
; -- b*b->b (signed and unsigned)
inx
lda ESTACK_LO,x
ldy ESTACK_LO+1,x
jsr math.multiply_bytes
sta ESTACK_LO+1,x
rts
.warn "mul_b not implemented"
.pend
mul_ub .proc
mul_word .proc
inx
lda ESTACK_LO,x
sta SCRATCH_ZPWORD1
lda ESTACK_HI,x
sta SCRATCH_ZPWORD1+1
lda ESTACK_LO+1,x
ldy ESTACK_HI+1,x
stx SCRATCH_ZPREGX
jsr math.multiply_words
ldx SCRATCH_ZPREGX
lda math.multiply_words_result
sta ESTACK_LO+1,x
lda math.multiply_words_result+1
sta ESTACK_HI+1,x
rts
.warn "mul_ub not implemented"
.pend
mul_w .proc
rts
.warn "mul_w not implemented"
.pend
mul_uw .proc
rts
.warn "mul_uw not implemented"
.pend
div_b .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "div_b not implemented"
.pend
div_ub .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "div_ub not implemented"
.pend
div_w .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "div_w not implemented"
.pend
div_uw .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "div_uw not implemented"
.pend
remainder_b .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "remainder_b via div_b?"
.pend
@ -524,18 +568,27 @@ remainder_ub .proc
.pend
remainder_w .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "remainder_w not implemented - via div_w"
.pend
remainder_uw .proc
inx
lda #42
sta ESTACK_LO+1,x
lda #0
sta ESTACK_HI+1,x
rts
.warn "remainder_uw not implemented - via div_uw"
.pend
equal_w .proc
; -- are the two words on the stack identical?
; @todo optimize according to http://www.6502.org/tutorials/compare_beyond.html
lda ESTACK_LO+1,x
cmp ESTACK_LO+2,x
bne equal_b._equal_b_false