14 files changed
+256
-31
No files matched your search
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
@@ -0,0 +1,3 @@
|
||||
$2D + LDA $2C + ADC #$00 + STA $2E + JSR
|
||||
|
||||
Fragment of updating well known pointers in the zero page
|
||||
@@ -0,0 +1,3 @@
|
||||
$60 + STA $24 + STA $25
|
||||
|
||||
Fragment of storing to well known pointer in zero page
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
INY + LDA ($24),Y + CMP zp
|
||||
|
||||
Loop fragment with well known zero page pointer address
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
SBC $2B + TAX + LDA $38 + SBC $2C + JSR $CD..
|
||||
|
||||
Fragment of decreasing well known pointer in zero page
|
||||
@@ -119,4 +119,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,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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user