diff --git a/STATUS.md b/STATUS.md index 37517541..9ac6c490 100644 --- a/STATUS.md +++ b/STATUS.md @@ -239,7 +239,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BC3C` | `convert_A_to_FAC1` | DONE | From the Microsoft BASIC, original name: FLOAT | | `$BC44` | `convert_i16_to_FAC1` | DONE | From the Microsoft BASIC, original name: FLOATS | | `$BC58` | `abs_FAC1` | DONE | From the Microsoft BASIC, original name: ABS | -| `$BC5B` | `FCOMP` | DONE | | +| `$BC5B` | `FCOMP` | DONE | From the Microsoft BASIC, original name: FCOMP | | `$BC9B` | `QINT` | DONE | From the Microsoft BASIC, original name: QINT | | `$BCCC` | `int_FAC1` | DONE | From the Microsoft BASIC, original name: INT | | `$BCE9` | `clear_FAC1` | DONE | From the Microsoft BASIC, original name: CLRFAC | diff --git a/src/aliases/,aliases_ram_lowmem.s b/src/aliases/,aliases_ram_lowmem.s index cf78801a..edf48071 100644 --- a/src/aliases/,aliases_ram_lowmem.s +++ b/src/aliases/,aliases_ram_lowmem.s @@ -31,7 +31,8 @@ !addr TEMPPT = $16 ; pointer to the first available slot in the temporary string descriptor stack !addr LASTPT = $17 ; $17-$18 pointer to the last used slot in the temporary string descriptor !addr TEMPST = $19 ; $19-$21 temporary string stack descriptors - !addr INDEX = $22 ; $22-$25 temporary variables, [!] our usage might be different + !addr INDEX = $22 ; $22-$23 INDEX1 vector + !addr INDEX2 = $24 ; $24-$25 INDEX2 vector !addr RESHO = $26 ; $26-$2A temporary variables, [!] our usage might be different !addr TXTTAB = $2B ; $2B-$2C start of BASIC code !addr VARTAB = $2D ; $2D-$2E end of BASIC code, start of variables diff --git a/src/basic/math/FCOMP.s b/src/basic/math/FCOMP.s deleted file mode 100644 index 9c38d69d..00000000 --- a/src/basic/math/FCOMP.s +++ /dev/null @@ -1,84 +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, Z=1 if equal, N=1 if FAC1 < RAM, Z=0, N=0 if FAC1 > RAM -; -; 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 - - ldy #$01 - lda (INDEX+2),Y - eor FAC1_sign ; Check if signs are different - bmi 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 - rts - - -FCOMP_less_than: - lda FAC1_sign - bpl FCOMP_FF -FCOMP_01: - lda #$01 - rts - -FCOMP_greater_than: - lda FAC1_sign - bpl FCOMP_01 -FCOMP_FF: - lda #$FF - rts diff --git a/src/basic/math/bc5b.FCOMP.jmp.s b/src/basic/math/bc5b.FCOMP.jmp.s deleted file mode 100644 index 639bf817..00000000 --- a/src/basic/math/bc5b.FCOMP.jmp.s +++ /dev/null @@ -1,8 +0,0 @@ -;; #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 diff --git a/src/basic/math/bc5b.FCOMP.s b/src/basic/math/bc5b.FCOMP.s new file mode 100644 index 00000000..a554cd95 --- /dev/null +++ b/src/basic/math/bc5b.FCOMP.s @@ -0,0 +1,70 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; This file is under the MIT license, it contains code released by Microsoft Corporation. +; See LICENSE for more information. + +; 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, Z=1 if equal, N=1 if FAC1 < RAM, Z=0, N=0 if FAC1 > RAM +; +; This is verified to be identical to the original Microsoft implementation where it was named FCOMP. +; +; Notes: +; - uses vector at $24, leaves FAC1 and FAC2 unchanged (Codebase64) +; +; Alternative entry point: FCOMPN - Instead of A set INDEX2 to low byte of address +; +; 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 INDEX2+0 +FCOMPN: + sty INDEX2+1 + ldy #0 + lda (INDEX2),Y + iny + tax + beq sgn_FAC1_A ; arg is zero so sign of FAC1 will decide + lda (INDEX2),Y + eor FAC1_sign + bmi sgn_FAC1_A_nozero ; signs differ so sign of FAC will decide + + cpx FAC1_exponent + bne @1 + lda (INDEX2),Y + ora #$80 + cmp FAC1_mantissa+0 + bne @1 + iny + lda (INDEX2),Y + cmp FAC1_mantissa+1 + bne @1 + iny + lda (INDEX2),Y + cmp FAC1_mantissa+2 + bne @1 + iny + lda #$7F + cmp FACOV + lda (INDEX2),Y + sbc FAC1_mantissa+3 ; Get zero if equal + beq QINT_ret +@1: + lda FAC1_sign + bcc @2 + eor #$FF +@2: + jmp sgn_A diff --git a/tools/similarity.c b/tools/similarity.c index 03e8f9b3..42e4f792 100644 --- a/tools/similarity.c +++ b/tools/similarity.c @@ -20,7 +20,7 @@ int matches[MAX_SIZE]; int phase_mask[MAX_SIZE+MAX_SIZE]; -#define NUM_CHUNKS 7 +#define NUM_CHUNKS 6 // Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xB849, 0xB84F, @@ -28,8 +28,7 @@ unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xB947, 0xB97D, 0xB983, 0xB9BB, 0xBBA2, 0xBC1A, - 0xBC2B, 0xBC5A, - 0xBC9B, 0xBCF2, + 0xBC2B, 0xBCF2, };