Add FCOMP

This commit is contained in:
Rikard Nordgren committed 2025-02-22 22:23:23 +01:00
1 parent b9a7f5bf5b
commit f773fd6b67
14 files changed
+256 -31

No files matched your search

+1 -1
View File
@@ -236,7 +236,7 @@ Floating point mathematical routines - not official, but well known and broadly
| `$BC3C` | `convert_A_to_FAC1` | DONE | |
| `$BC44` | `convert_i16_to_FAC1` | DONE | |
| `$BC58` | `abs_FAC1` | NOT DONE | |
| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location |
| `$BC5B` | `FCOMP` | DONE | |
| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer |
| `$BCCC` | `int_FAC1` | NOT DONE | |
| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces |
-30
View File
@@ -1,30 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - compare FAC1 with RAM location
;
; Input:
; - .A - address low byte
; - .Y - address high byte
;
; Output:
; - .A - $00 for equal, $01 for FAC1 > RAM, $FF for FAC1 < RAM
; - flags N/Z, depending on whether FAC1 is 0, positive, or negative
;
; Notes:
; - uses vector at $24, leaves FAC1 and FAC2 unchanged (Codebase64)
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 115
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; XXX provide implementation
FCOMP:
+STUB_IMPLEMENTATION
+92
View File
@@ -0,0 +1,92 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - compare FAC1 with RAM location
;
; Input:
; - .A - address low byte
; - .Y - address high byte
;
; Output:
; - .A - $00 for equal, $01 for FAC1 > RAM, $FF for FAC1 < RAM
; - flags N/Z, depending on whether FAC1 is 0, positive, or negative
;
; Notes:
; - uses vector at $24, leaves FAC1 and FAC2 unchanged (Codebase64)
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 115
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
FCOMP:
sta INDEX+2
sty INDEX+3
jsr sgn_FAC1_A ; Set N/Z flag for FAC1 and store on stack
php
ldy #$01
lda #$7F ; Expand sign of RAM float into A as $FF or $00
cmp (INDEX+2),Y
adc #$80
cmp FAC1_sign
bne FCOMP_greater_than ; FAC < or > RAM, will be swapped to correct
dey
lda (INDEX+2),Y ; Exponent of RAM float into A
cmp FAC1_exponent
bcc FCOMP_greater_than ; FAC1 > RAM
bne FCOMP_less_than
cmp #$00
beq FCOMP_equal ; FAC1 = RAM = 0
iny
lda (INDEX+2),Y
ora #$80 ; Set highest bit of mantissa (0.5)
cmp FAC1_mantissa
bcc FCOMP_greater_than
bne FCOMP_less_than
iny
lda (INDEX+2),Y
cmp FAC1_mantissa+1
bcc FCOMP_greater_than
bne FCOMP_less_than
iny
lda (INDEX+2),Y
cmp FAC1_mantissa+2
bcc FCOMP_greater_than
bne FCOMP_less_than
iny
lda (INDEX+2),Y
cmp FAC1_mantissa+3
bcc FCOMP_greater_than
bne FCOMP_less_than
FCOMP_equal:
lda #$00
plp
rts
FCOMP_less_than:
lda #$FF
cmp FAC1_sign
bne @1
lda #$01
@1: plp
rts
FCOMP_greater_than:
lda #$01
cmp FAC1_sign
bcs @1
lda #$FF
@1: plp
rts
+8
View File
@@ -0,0 +1,8 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
; Just a compatibility jump - our routine is longer than original one
jmp FCOMP
File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
$2D + LDA $2C + ADC #$00 + STA $2E + JSR
Fragment of updating well known pointers in the zero page
+3
View File
@@ -0,0 +1,3 @@
$60 + STA $24 + STA $25
Fragment of storing to well known pointer in zero page
+3
View File
@@ -0,0 +1,3 @@
LDA ($24),Y + ORA $#80 + CMP $62
Load using well knownn pointer in zero page, set sign bit and compare with byte in FAC1 mantissa
+3
View File
@@ -0,0 +1,3 @@
LDA ($24),Y + CMP $64
Load using well known zero page pointer and compare with FAC1 mantissa byte in zero page
+3
View File
@@ -0,0 +1,3 @@
INY + LDA ($24),Y + CMP zp
Loop fragment with well known zero page pointer address
+3
View File
@@ -0,0 +1,3 @@
INY + LDA ($24),Y + CMP $63
Load using well known pointer in zero page and compare with mantissa byte in FAC1
+3
View File
@@ -0,0 +1,3 @@
SBC $2B + TAX + LDA $38 + SBC $2C + JSR $CD..
Fragment of decreasing well known pointer in zero page
+114
View File
@@ -105,4 +105,118 @@ print "COMPARE"
compare $61 $67 $1001
print "END"
print "TEST: mov MEM FAC1 const 1.0"
fill $61 $67 FF FF FF FF FF AA
fill $70 $70 CD
r A=$BC
r Y=$B9
r PC=$BBA2
ret
fill $1001 $1006 81 80 00 00 00 00
print "COMPARE"
compare $61 $66 $1001
compare $70 $70 $1003 ; FACOV = 0
print "END"
print "TEST: mov MEM FAC1 const -0.5"
fill $61 $67 FF FF FF FF FF AA
fill $70 $70 CD
r A=$E0
r Y=$B9
r PC=$BBA2
ret
fill $1001 $1006 80 80 00 00 00 FF
print "COMPARE"
compare $61 $66 $1001
compare $70 $70 $1003 ; FACOV = 0
print "END"
print "TEST: FCOMP 1.0 == 1.0"
r A=$BC
r Y=$B9
r PC=$BBA2
ret
r A=$BC
r Y=$B9
r PC=$BC5B
ret
print "CHECK A==0"
r
print "TEST: FCOMP 1.0 > 0.5"
r A=$BC
r Y=$B9
r PC=$BBA2
ret
r A=$11
r Y=$BF
r PC=$BC5B
ret
print "CHECK A==1"
r
print "TEST: FCOMP 0.5 < 1.0"
r A=$11
r Y=$BF
r PC=$BBA2
ret
r A=$BC
r Y=$B9
r PC=$BC5B
ret
print "CHECK A==255"
r
print "TEST: FCOMP -0.5 < 1.0"
r A=$E0
r Y=$B9
r PC=$BBA2
ret
r A=$BC
r Y=$B9
r PC=$BC5B
ret
print "CHECK A==255"
r
print "TEST: FCOMP 10.0 > -0.5"
r A=$F9
r Y=$BA
r PC=$BBA2
ret
r A=$E0
r Y=$B9
r PC=$BC5B
ret
print "CHECK A==1"
r
print "TEST: FCOMP 0.9970194103661925 < 0.9970194105990231"
fill $1001 $1005 80 7F 3C AA 01
r A=$01
r Y=$10
r PC=$BBA2
ret
fill $1006 $100A 80 7F 3C AA 02
r A=$06
r Y=$10
r PC=$BC5B
ret
print "CHECK A==255"
r
print "TEST: FCOMP 0.0 = 0.0"
fill $1001 $1005 00 7F 3C AA 01
r A=$01
r Y=$10
r PC=$BBA2
ret
fill $1006 $100A 00 7F 3C AA 02
r A=$06
r Y=$10
r PC=$BC5B
ret
print "CHECK A==0"
r
q
+20
View File
@@ -20,6 +20,26 @@ int main()
} else if (line.starts_with(" print \"COMPARE")) {
getline(file, line);
in_compare = true;
} else if (line.starts_with(" print \"CHECK")) {
std::string cmp = line.substr(15, line.size() - 16);
std::string reg = cmp.substr(0, 1);
std::string op = cmp.substr(1, 2);
int value = std::stoi(cmp.substr(3, line.size() - 3));
if (op == "==") {
getline(file, line);
getline(file, line);
getline(file, line);
if (reg == "A") {
int A_val = std::stoi(line.substr(7, 2), 0, 16);
if (A_val != value) {
std::cout << "FAIL: A != " << value << " (was " << A_val << ")" << std::endl;
failed = true;
}
}
} else {
std::cout << "ERROR: Unknown operator for check" << std::endl;
failed = true;
}
} else if (line.starts_with(" print \"END")) {
in_compare = false;
}