diff --git a/Makefile b/Makefile index de38e2f3..f8256f00 100644 --- a/Makefile +++ b/Makefile @@ -930,7 +930,7 @@ testremote: build/kernal_custom.rom build/basic_custom.rom $(TARGET_CHR_PXL) bui x64 -kernal build/kernal_custom.rom -basic build/basic_custom.rom -chargen $(TARGET_CHR_PXL) -moncommands build/symbols_custom.vs -remotemonitor testsimilarity: $(TOOL_SIMILARITY) $(DIR_TST38)/OUTx_x.BIN $(ROM_CBM_KERNAL) $(ROM_CBM_BASIC) - $(TOOL_SIMILARITY) $(ROM_CBM_KERNAL) $(DIR_TST38)/OUTx_x.BIN + $(TOOL_SIMILARITY) $(ROM_CBM_KERNAL) $(DIR_TST38)/OUTx_x.BIN --basic --high $(TOOL_SIMILARITY) $(ROM_CBM_BASIC) $(DIR_TST38)/OUTx_x.BIN --basic build/testresults: testsuite/unit/testresults.cc diff --git a/STATUS.md b/STATUS.md index 01fd551c..da4fea08 100644 --- a/STATUS.md +++ b/STATUS.md @@ -265,7 +265,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$E264` | `cos_FAC1` | PARTIAL | not fully tested yet | | `$E26B` | `sin_FAC1` | PARTIAL | not fully tested yet | | `$E2B4` | `tan_FAC1` | PARTIAL | not fully tested yet | -| `$E30E` | `atn_FAC1` | PARTIAL | not fully tested yet | +| `$E30E` | `atn_FAC1` | DONE | From the Microsoft BASIC, original name: ATN |
diff --git a/src/basic/math_trans/e30e.atn_FAC1.s b/src/basic/math_trans/e30e.atn_FAC1.s index c58a811c..e620adf8 100644 --- a/src/basic/math_trans/e30e.atn_FAC1.s +++ b/src/basic/math_trans/e30e.atn_FAC1.s @@ -2,9 +2,13 @@ ;; #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 - arc tangent of FAC1 ; +; This is verified to be identical to the original Microsoft implementation where it was named ATN +; ; See also: ; - [CM64] Computes Mapping the Commodore 64 - page 211 ; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic @@ -23,41 +27,34 @@ atn_FAC1: - lda FAC1_sign ; Save sign of FAC1 on the stack - pha - lda #$00 ; FAC1 = abs(FAC1) - sta FAC1_sign - sta TEMPF1 ; AX not scaled - - lda #const_ONE - jsr FCOMP - bmi atn_skipscale - - lda #const_ONE - jsr div_MEM_FAC1 - inc TEMPF1 ; AX scaled - -atn_skipscale: - lda #poly_atn - jsr poly1_FAC1 - - lda TEMPF1 - beq atn_skipoffset - - lda #const_HALF_PI - jsr sub_MEM_FAC1 - -atn_skipoffset: - pla - bpl atn_out - jmp toggle_sign_FAC1 - -atn_out: - rts + lda FAC1_sign ; What is sign? + pha ; (Meanwhile save it for later) + bpl ATN1 + jsr toggle_sign_FAC1 ; If negative, negate FAC1, use arctan(x) = -arctan(-x) +ATN1: + lda FAC1_exponent + pha ; Save this too for later + cmp #$81 ; See if FAC1 >= 1.0 + bcc ATN2 ; It is less than 1 + lda #const_ONE + jsr div_MEM_FAC1 ; Compute reciprocal. Use arctan(x) = pi/2 - arctan(1/x) +ATN2: + lda #poly_atn + jsr poly1_FAC1 + pla + cmp #$81 ; Was original argument < 1 ? + bcc ATN3 ; Yes + lda #const_HALF_PI + jsr sub_MEM_FAC1 ; Subtract arctan from pi/2 +ATN3: + pla ; Was original argument positive? + bpl ATN4 ; Yes + jmp toggle_sign_FAC1 ; If negative, negate result +ATN4: + rts } else { diff --git a/tools/similarity.c b/tools/similarity.c index 51bd6f0f..69eb4f75 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 9 +#define NUM_CHUNKS 10 // Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xB391, 0xB39D, @@ -32,6 +32,7 @@ unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xBDB3, 0xBDC1, 0xBDDD, 0xBF51, 0xBFB4, 0xBFEC, + 0xE30E, 0xE33D, }; @@ -40,6 +41,7 @@ int main(int argc,char **argv) { int verbose=0; int basic = 0; + int high =0; if (argc<3) { fprintf(stderr,"usage: similarity [--verbose] [--basic]\n"); @@ -51,6 +53,8 @@ int main(int argc,char **argv) verbose = 1; } else if (!strcmp(argv[i], "--basic")) { basic = 1; + } else if (!strcmp(argv[i], "--high")) { + high = 1; } else { fprintf(stderr, "Unrecognised directive.\n"); exit(-1); @@ -94,11 +98,21 @@ int main(int argc,char **argv) if (basic) { for (int i = 0; i < NUM_CHUNKS; i++) { for (int addr = microsoft_basic_chunks[i * 2]; addr <= microsoft_basic_chunks[i * 2 + 1]; addr++) { - short index = addr - 0xA000; - if (f1[index] != f2[index]) { - printf("BASIC does not match MS BASIC at %X (%X != %X)\n", addr, f1[index], f2[index]); + short index1, index2; + if (high && addr < 0xE000 || !high && addr >= 0xE000) { + continue; } - f1[index] = 0xFF; + if (!high) { + index1 = addr - 0xA000; + index2 = index1; + } else { + index1 = addr - 0xE000; + index2 = addr - 0xA000; + } + if (f1[index1] != f2[index2]) { + printf("BASIC does not match MS BASIC at %X (%X != %X)\n", addr, f1[index1], f2[index2]); + } + f1[index1] = 0xFF; } } }