Compare commits

...
10 Commits
Author SHA1 Message Date
Rikard Nordgren ad178dbe4d Add build for the original C64 2026-05-16 22:31:48 +02:00
Rikard Nordgren 93b6a2460e Update STATUS for exp and FIN 2026-05-09 17:01:44 +02:00
Rikard Nordgren e8191ccbac Add similarity strings 2026-05-09 17:01:44 +02:00
Rikard Nordgren a587990f3e Do not print out similarities of 3 bytes 2026-05-09 17:01:44 +02:00
Rikard Nordgren 781ad9ee6c Add pwr_FAC2_FAC1 2026-05-09 17:01:44 +02:00
Rikard Nordgren ec3c7c05dc Add exp_FAC1
Had to deactivate it for MEGA65 because of conflicting code also placed at e000
2026-05-09 17:01:44 +02:00
Rikard Nordgren 6ea0dc74be Remove unused math helpers 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1ec43e8cd7 Update FIN 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1b1d0c4329 Remove no longer used mov_FAC1_MEM 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1adfa10462 Update -32768 2026-05-09 17:01:44 +02:00
28 changed files with 540 additions and 502 deletions

No files matched your search

+20
View File
@@ -136,6 +136,7 @@ GEN_ZMAC_H = $(DIR_ZMAC_TMP)/doc.inl
# List of build directories
DIR_C64 = build/target_c64
DIR_CUS = build/target_custom
DIR_GEN = build/target_generic
DIR_GENCRT = build/target_generic_crt
@@ -149,6 +150,7 @@ DIR_X16 = build/target_cx16
# List of config files
CFG_CUS = src/,,config_custom.s
CFG_C64 = src/,,config_c64.s
CFG_GEN = src/,,config_generic.s
CFG_GENCRT = src/,,config_generic_crt.s
CFG_TST38 = src/,,config_testing_38K.s
@@ -161,6 +163,7 @@ CFG_U64CRT = src/,,config_ultimate64_crt.s
# List of files with generated strings
GEN_STR_CUS = $(DIR_CUS)/,generated/,packed_strings.s
GEN_STR_C64 = $(DIR_C64)/,generated/,packed_strings.s
GEN_STR_GEN = $(DIR_GEN)/,generated/,packed_strings.s
GEN_STR_GENCRT = $(DIR_GENCRT)/,generated/,packed_strings.s
GEN_STR_TST38 = $(DIR_TST38)/,generated/,packed_strings.s
@@ -208,6 +211,7 @@ TARGET_CHR_ORF = build/chargen_openroms.rom
TARGET_CHR_PXL = build/chargen_pxlfont.rom
TARGET_CUS_B = build/basic_custom.rom
TARGET_C64_B = build/basic_c64.rom
TARGET_GEN_B = build/basic_generic.rom
TARGET_GENCRT_B = build/basic_generic_crt.rom
TARGET_TST38_B = build/basic_testing_38K.rom
@@ -216,6 +220,7 @@ TARGET_U64_B = build/basic_ultimate64.rom
TARGET_U64CRT_B = build/basic_ultimate64_crt.rom
TARGET_CUS_K = build/kernal_custom.rom
TARGET_C64_K = build/kernal_c64.rom
TARGET_GEN_K = build/kernal_generic.rom
TARGET_GENCRT_K = build/kernal_generic_crt.rom
TARGET_TST38_K = build/kernal_testing_38K.rom
@@ -231,6 +236,7 @@ TARGET_M65_x_PXL = build/mega65.rom
TARGET_X16_x = build/cx16-dummy.rom
TARGET_LIST_CUS = $(TARGET_CUS_B) $(TARGET_CUS_K)
TARGET_LIST_C64 = $(TARGET_C64_B) $(TARGET_C64_K)
TARGET_LIST_GEN = $(TARGET_GEN_B) $(TARGET_GEN_K)
TARGET_LIST_GENCRT = $(TARGET_GENCRT_B) $(TARGET_GENCRT_K) $(TARGET_GENCRT_X)
TARGET_LIST_TST38 = $(TARGET_TST38_B) $(TARGET_TST38_K)
@@ -242,6 +248,7 @@ TARGET_Z80TEST = ./build/cpm/Z80TEST.COM
TARGET_LIST = $(TARGET_CHR_ORF) \
$(TARGET_LIST_CUS) \
$(TARGET_LIST_C64) \
$(TARGET_LIST_GEN) \
$(TARGET_LIST_GENCRT) \
$(TARGET_LIST_TST38) \
@@ -376,6 +383,8 @@ build/patched_chargen/pxlfont.pcg: $(TOOL_PATCH_CHARGEN) $(TARGET_CHR_PXL)
$(DIR_CUS)/OUTB_x.BIN $(DIR_CUS)/BASIC_combined.vs: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_CUS) $(GEN_STR_CUS) $(DIR_CUS)/KERNAL_combined.sym
$(DIR_C64)/OUTB_x.BIN $(DIR_C64)/BASIC_combined.vs: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_C64) $(GEN_STR_C64) $(DIR_C64)/KERNAL_combined.sym
$(DIR_GEN)/OUTB_x.BIN $(DIR_GEN)/BASIC_combined.vs: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_GEN) $(GEN_STR_GEN) $(DIR_GEN)/KERNAL_combined.sym
$(DIR_TST38)/OUTB_x.BIN $(DIR_TST38)/BASIC_combined.vs: \
@@ -387,6 +396,8 @@ $(DIR_U64)/OUTB_x.BIN $(DIR_U64)/BASIC_combined.vs: \
$(DIR_CUS)/OUTK_x.BIN $(DIR_CUS)/KERNAL_combined.vs $(DIR_CUS)/KERNAL_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_CUS) $(GEN_STR_CUS)
$(DIR_C64)/OUTK_x.BIN $(DIR_C64)/KERNAL_combined.vs $(DIR_C64)/KERNAL_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_C64) $(GEN_STR_C64)
$(DIR_GEN)/OUTK_x.BIN $(DIR_GEN)/KERNAL_combined.vs $(DIR_GEN)/KERNAL_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_GEN) $(GEN_STR_GEN)
$(DIR_TST38)/OUTK_x.BIN $(DIR_TST38)/KERNAL_combined.vs $(DIR_TST38)/KERNAL_combined.sym: \
@@ -445,6 +456,7 @@ $(DIR_X16)/kernal.seg_1 $(DIR_X16)/KERNAL_1_combined.vs $(DIR_X16)/KERNAL_1_comb
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_X16) $(GEN_STR_X16) $(DIR_X16)/KERNAL_0_combined.sym
$(DIR_CUS)/OUTx_x.BIN: $(DIR_CUS)/OUTB_x.BIN $(DIR_CUS)/OUTK_x.BIN
$(DIR_C64)/OUTx_x.BIN: $(DIR_C64)/OUTB_x.BIN $(DIR_C64)/OUTK_x.BIN
$(DIR_GEN)/OUTx_x.BIN: $(DIR_GEN)/OUTB_x.BIN $(DIR_GEN)/OUTK_x.BIN
$(DIR_GENCRT)/OUTx_0.BIN: $(DIR_GENCRT)/OUTB_0.BIN $(DIR_GENCRT)/OUTK_0.BIN
$(DIR_TST38)/OUTx_x.BIN: $(DIR_TST38)/OUTB_x.BIN $(DIR_TST38)/OUTK_x.BIN
@@ -455,18 +467,21 @@ $(DIR_U64CRT)/OUTx_0.BIN: $(DIR_U64CRT)/OUTB_0.BIN $(DIR_U64CRT)/OUTK_0.BIN
$(DIR_X16)/OUTx_0.BIN: $(DIR_X16)/OUTB_0.BIN $(DIR_X16)/OUTK_0.BIN
$(TARGET_CUS_B): $(DIR_CUS)/OUTx_x.BIN
$(TARGET_C64_B): $(DIR_C64)/OUTx_x.BIN
$(TARGET_GEN_B): $(DIR_GEN)/OUTx_x.BIN
$(TARGET_TST38_B): $(DIR_TST38)/OUTx_x.BIN
$(TARGET_TST60_B): $(DIR_TST60)/OUTx_x.BIN
$(TARGET_U64_B): $(DIR_U64)/OUTx_x.BIN
$(TARGET_CUS_K): $(DIR_CUS)/OUTx_x.BIN
$(TARGET_C64_K): $(DIR_C64)/OUTx_x.BIN
$(TARGET_GEN_K): $(DIR_GEN)/OUTx_x.BIN
$(TARGET_TST38_K): $(DIR_TST38)/OUTx_x.BIN
$(TARGET_TST60_K): $(DIR_TST60)/OUTx_x.BIN
$(TARGET_U64_K): $(DIR_U64)/OUTx_x.BIN
build/symbols_custom.vs: $(DIR_CUS)/BASIC_combined.vs $(DIR_CUS)/KERNAL_combined.vs
build/symbols_c64.vs: $(DIR_C64)/BASIC_combined.vs $(DIR_C64)/KERNAL_combined.vs
build/symbols_generic.vs: $(DIR_GEN)/BASIC_combined.vs $(DIR_GEN)/KERNAL_combined.vs
build/symbols_generic_crt.vs: $(DIR_GENCRT)/BASIC_0_combined.vs $(DIR_GENCRT)/KERNAL_0_combined.vs
build/symbols_testing_38K.vs: $(DIR_TST38)/BASIC_combined.vs $(DIR_TST38)/KERNAL_combined.vs
@@ -480,6 +495,10 @@ $(GEN_STR_CUS): $(TOOL_GENERATE_STRINGS) $(CFG_CUS)
@mkdir -p $(DIR_CUS)/,generated
$(TOOL_GENERATE_STRINGS) -o $@ -c $(CFG_CUS)
$(GEN_STR_C64): $(TOOL_GENERATE_STRINGS) $(CFG_C64)
@mkdir -p $(DIR_C64)/,generated
$(TOOL_GENERATE_STRINGS) -o $@ -c $(CFG_C64)
$(GEN_STR_GEN): $(TOOL_GENERATE_STRINGS) $(CFG_GEN)
@mkdir -p $(DIR_GEN)/,generated
$(TOOL_GENERATE_STRINGS) -o $@ -c $(CFG_GEN)
@@ -521,6 +540,7 @@ build/,generated/,z80_tables.s: $(TOOL_GENERATE_Z80_TABLES)
$(TOOL_GENERATE_Z80_TABLES) -o build/,generated/,z80_tables.s
GEN_STR_custom = $(GEN_STR_CUS)
GEN_STR_c64 = $(GEN_STR_C64)
GEN_STR_generic = $(GEN_STR_GEN)
GEN_STR_generic_crt = $(GEN_STR_GENCRT)
GEN_STR_testing_38K = $(GEN_STR_TST38)
+3 -3
View File
@@ -248,15 +248,15 @@ Floating point mathematical routines - not official, but well known and broadly
| `$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 |
| `$BCF3` | `FIN` | PARTIAL | Only for 38k memory model + not fully tested yet |
| `$BCF3` | `FIN` | PARTIAL | From the Microsoft BASIC Only for 38k memory model |
| `$BD7E` | `FINLOG` | DONE | From the Microsoft BASIC, original name: FINLOG |
| `$BDDD` | `FOUT` | DONE | From the Microsoft BASIC, original name: FOUT |
| `$BF71` | `sqr_FAC1` | DONE | From the Microsoft BASIC, original name: SQR |
| `$BF74` | `sqr_FAC2` | DONE | From the Microsoft BASIC, no label |
| `$BF78` | `pwr_FAC2_MEM` | DONE | From the Microsoft BASIC, no label |
| `$BF7B` | `pwr_FAC2_FAC1` | NOT DONE | |
| `$BF7B` | `pwr_FAC2_FAC1` | DONE | From the Microsoft BASIC, original name: FPWRT |
| `$BFB4` | `toggle_sign_FAC1` | DONE | From the Microsoft BASIC, original name: NEGOP |
| `$BFED` | `exp_FAC1` | NOT DONE | |
| `$BFED` | `exp_FAC1` | PARTIAL | From the Microsoft BASIC Only for the 38k model |
| `$E043` | `poly1_FAC1` | DONE | From the Microsoft BASIC, original name: POLYX |
| `$E059` | `poly2_FAC1` | DONE | From the Microsoft BASIC, original name: POLY |
| `$E097` | `rnd_FAC1` | DONE | |
+129
View File
@@ -0,0 +1,129 @@
;; #CONFIG# ID $64 ; should be 1 byte, different for each config file!
;
; Please read CONFIG.md before modifying this file!
;
; Idea:
; Maximum compatibility with the original C64
; Original Microsoft BASIC with bugs and all
; No customizations of the KERNAL
; --- Hardware platform and brand
;; #CONFIG# PLATFORM_COMMODORE_64 YES
;; #CONFIG# BRAND_CUSTOM "C64"
; --- Processor instruction set
;; #CONFIG# CPU_MOS_6502 YES
;; #CONFIG# CPU_DTV_6502 NO
;; #CONFIG# CPU_RCW_65C02 NO
;; #CONFIG# CPU_WDC_65C02 NO
;; #CONFIG# CPU_WDC_65816 NO
;; #CONFIG# CPU_CSG_65CE02 NO
; --- Memory model
;; #CONFIG# MEMORY_MODEL_38K YES
;; #CONFIG# MEMORY_MODEL_46K NO
;; #CONFIG# MEMORY_MODEL_50K NO
;; #CONFIG# MEMORY_MODEL_60K NO
; --- IEC bus configuration
;; #CONFIG# IEC YES
;; #CONFIG# IEC_DOLPHINDOS NO
;; #CONFIG# IEC_DOLPHINDOS_FAST NO
;; #CONFIG# IEC_JIFFYDOS NO
;; #CONFIG# IEC_JIFFYDOS_BLANK NO
; --- Tape deck configuration
;; #CONFIG# TAPE_NORMAL YES
;; #CONFIG# TAPE_TURBO NO
;; #CONFIG# TAPE_AUTODETECT NO
;; #CONFIG# TAPE_NO_KEY_SENSE NO
;; #CONFIG# TAPE_NO_MOTOR_CONTROL NO
; --- Sound support
;; #CONFIG# SID_2ND_ADDRESS NO
;; #CONFIG# SID_3RD_ADDRESS NO
;; #CONFIG# SID_D4XX NO
;; #CONFIG# SID_D5XX NO
;; #CONFIG# SID_D6XX NO
;; #CONFIG# SID_D7XX NO
; --- Keyboard settings
;; #CONFIG# KEYBOARD_C128 NO
;; #CONFIG# KEYBOARD_C128_CAPS_LOCK NO
;; #CONFIG# KEY_REPEAT_DEFAULT NO
;; #CONFIG# KEY_REPEAT_ALWAYS NO
;; #CONFIG# KEY_FAST_SCAN YES
;; #CONFIG# JOY1_CURSOR YES
;; #CONFIG# JOY2_CURSOR YES
;; #CONFIG# PROGRAMMABLE_KEYS YES
;; #CONFIG# KEYCMD_RUN "\5FL"
;; #CONFIG# KEYCMD_F1 "@8$"
;; #CONFIG# KEYCMD_F2 "LOAD"
;; #CONFIG# KEYCMD_F3 "@9$"
;; #CONFIG# KEYCMD_F4 "RUN:"
;; #CONFIG# KEYCMD_F5 "@10$"
;; #CONFIG# KEYCMD_F6 NO
;; #CONFIG# KEYCMD_F7 "@11$"
;; #CONFIG# KEYCMD_F8 NO
;; #CONFIG# KEYCMD_HELP "LIST"
; --- Screen editor
;; #CONFIG# EDIT_STOPQUOTE YES
; --- Software features
;; #CONFIG# PANIC_SCREEN YES
;; #CONFIG# DOS_WEDGE NO
;; #CONFIG# TAPE_WEDGE NO
;; #CONFIG# TAPE_HEAD_ALIGN NO
;; #CONFIG# BCD_SAFE_INTERRUPTS YES
; --- BASIC features
;; #CONFIG# ORIGINAL_UNPATCHED_BASIC YES
;; #CONFIG# TRANSCENDENTAL_FUNCTIONS YES
; --- Eye candy
;; #CONFIG# COLORS_BRAND NO
;; #CONFIG# BANNER_SIMPLE YES
;; #CONFIG# BANNER_FANCY NO
;; #CONFIG# SHOW_FEATURES YES
; --- Debug options
;; #CONFIG# DBG_STUBS_BRK NO
;; #CONFIG# DBG_PRINTF NO
; --- Other
;; #CONFIG# COMPRESSION_LVL_2 NO
+3
View File
@@ -15,6 +15,7 @@
!addr ADRAY1 = $03 ; $03-$04
!addr ADRAY2 = $05 ; $05-$06
!addr CHARAC = $07 ; [!] our implementation might be different XXX give more details
!addr INTEGR = CHARAC
!addr ENDCHR = $08 ; [!] our implementation might be different XXX give more details
!addr TRMPOS = $09 ; -- NOT IMPLEMENTED -- [!] on MEGA65 also used by DOS Wedge under MONITOR
!addr VERCKB = $0A ; flag used by BASIC, 0 - LOAD, 1 - VERIFY, [!] on MEGA65 also used by DOS Wedge
@@ -63,6 +64,8 @@
!addr TEMPF2 = $5C ; $5C-$60 BASIC numeric work area
!addr DECCNT = $5D ; Number of digits after decimal point
!addr TENEXP = $5E ; Exponent count
!addr DPTFLG = $5F ; Decimal point flag for FIN
!addr EXPSGN = $60 ; Exponent sign for FIN
!addr __FAC1 = $61 ; $61-$66 floating point accumulator 1
!addr FAC1_exponent = $61
!addr FAC1_mantissa = $62 ; $62 - $65
@@ -1,26 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - set FAC1 as FAC2 raised to the power of FAC1
;
; Input:
; - .A - must load FAC1 exponent ($61) beforehand to set the zero flag
;
; Note:
; - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?)
; - uses exp(x*log(y)) formula to calculate y^x; slow and inaccurate
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 117
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; XXX provide implementation
pwr_FAC2_FAC1:
+STUB_IMPLEMENTATION
-20
View File
@@ -1,20 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - exponential function, e raised to FAC1 power
;
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 117
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; XXX provide implementation
exp_FAC1:
+STUB_IMPLEMENTATION
-152
View File
@@ -1,152 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - imports string to FAC1, ignores spaces
;
;
; Input:
; - .A needs to be loaded with first char of the string
; - Carry flag must be clear
; - string address in $7A/$7B
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 116
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
!ifdef CONFIG_MEMORY_MODEL_38K {
; NOTE: Currently CHRGET is only available for the 38K model and the equivalent function
; does not test for digits to set carry
FIN_NUMDEC = TEMPF2
FIN_DIGIT = TEMPF2 + 1
FIN_DECFOUND = TEMPF2 + 2
FIN_EXPSIGN = TEMPF2 + 3
FIN_EXP = TEMPF2 + 4
FIN:
ldx #$00
stx SGNFLG ; Sign is positive
stx FIN_DECFOUND ; Decimal point not found
stx FIN_EXP ; Exponent
stx FAC1_exponent ; FAC1 <- 0
bcc FIN_loop ; Starting with digit
cmp #$2D ; Is minus?
bne @1
dec SGNFLG
bne FIN_next ; Will always branch
@1: cmp #$2B ; Is plus?
beq FIN_next
FIN_loop:
bcs FIN_nonnumeric
sec
sbc #48 ; Convert to number
sta FIN_DIGIT
jsr mul10_FAC1
lda FIN_DIGIT
jsr FINLOG
lda FIN_DECFOUND ; Have we passed the decimal sign?
bpl FIN_next
inc FIN_NUMDEC
FIN_next:
jsr CHRGET
+bra FIN_loop
FIN_nonnumeric:
cmp #$2E ; decimal point
beq FIN_decimal
cmp #$45 ; E
beq FIN_exponent
FIN_finalize:
lda FIN_EXP
sec
sbc FIN_NUMDEC
sta FIN_EXP
bmi FIN_div_loop
FIN_mul_loop:
dec FIN_EXP
bmi FIN_out
jsr mul10_FAC1
+bra FIN_mul_loop
FIN_div_loop:
jsr div10_FAC1_p
inc FIN_EXP
bne FIN_div_loop
FIN_out:
lda SGNFLG
sta FAC1_sign
rts
FIN_decimal:
lda FIN_DECFOUND
bmi FIN_finalize
dec FIN_DECFOUND ; Indicate found decimal point
sta FIN_NUMDEC ; Number of decimal places = 0
+bra FIN_next
FIN_exponent:
ldx #0
stx FIN_EXPSIGN
jsr CHRGET
bcc FIN_exp_loop
cmp #$2D ; Is minus?
bne @1
dec FIN_EXPSIGN
bne FIN_exp_next ; Always branches
@1: cmp #$2B ; Is plus?
beq FIN_exp_next
bne FIN_done_exp
FIN_exp_loop:
tax
lda FIN_EXP
cmp #10
bcs FIN_exp_limit
asl ; Multiply by 10
sta FIN_EXP
asl
asl
clc
adc FIN_EXP
sta FIN_EXP
txa
sec
sbc #48 ; Convert to number
clc
adc FIN_EXP
sta FIN_EXP
FIN_exp_next:
jsr CHRGET
bcc FIN_exp_loop
FIN_done_exp:
lda FIN_EXP
bpl FIN_finalize
eor #$FF
tax
inx
stx FIN_EXP
+bra FIN_finalize
FIN_exp_limit:
ldx FIN_EXPSIGN
bmi FIN_zero
jmp do_OVERFLOW_error
FIN_zero:
ldx #0
stx FAC1_exponent
rts
}
-12
View File
@@ -1,12 +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
!ifdef CONFIG_MEMORY_MODEL_38K {
jmp FIN
} else {
+STUB_IMPLEMENTATION
}
+130
View File
@@ -0,0 +1,130 @@
;; #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 - imports string to FAC1, ignores spaces
;
; This is verified to be identical to the original Microsoft implementation where it was named FIN.
;
; Input:
; - .A needs to be loaded with first char of the string
; - Carry flag must be clear
; - string address in $7A/$7B
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 116
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; NUMBER INPUT IS LEFT IN FAC.
; AT ENTRY [TXTPTR] POINTS TO THE FIRST CHARACTER IN A TEXT BUFFER.
; THE FIRST CHARACTER IS ALSO IN ACCA. FIN PACKS THE DIGITS
; INTO THE FAC AS AN INTEGER AND KEEPS TRACK OF WHERE THE
; DECIMAL POINT IS. [DPTFLG] TELL WHETHER A DP HAS BEEN
; SEEN. [DECCNT] IS THE NUMBER OF DIGITS AFTER THE DP.
; AT THE END [DECCNT] AND THE EXPONENT ARE USED TO
; DETERMINE HOW MANY TIMES TO MULTIPLY OR DIVIDE BY TEN
; TO GET THE CORRECT NUMBER.
!ifdef CONFIG_MEMORY_MODEL_38K {
FIN:
ldy #0 ; Zero FAC1_sign and SGNFLG
ldx #10 ; Zero exp and hi bytes
FINZLP:
sty DECCNT,X ; Zero low bytes
dex ; Zero TENEXP and EXPSGN
bpl FINZLP ; Zero DECCNT, DPTFLG
bcc FINDGQ ; Flags still set from CHRGET
cmp #'-' ; A negative sign?
bne QPLUS ; No, try plus sign
stx SGNFLG ; It's negative
beq FINC ; Always branches
QPLUS:
cmp #'+' ; Plus sign?
bne FIN1 ; Yes, skip it
FINC:
jsr CHRGET
FINDGQ:
bcc FINDIG
FIN1:
cmp #'.' ; The decimal point?
beq FINDP ; No kidding
cmp #'E' ; Exponent follows
bne FINE ; No
;HERE TO CHECK FOR SIGN OF EXP.
jsr CHRGET ; Yes, Get another
bcc FNEDG1 ; It is a digit. (Easier than backing up pointer)
cmp #$AB ; Minus with sign set (from table)
beq FINEC1 ; Negate
cmp #'-' ; Minus sign?
beq FINEC1
cmp #$AA ; Plus with sign set (from table)
beq FINEC
cmp #'+' ; Plus sign?
beq FINEC
bne FINEC2
FINEC1:
ror EXPSGN ; Turn it on
FINEC:
jsr CHRGET ; Get another
FNEDG1:
bcc FINEDG ; It is a digit
FINEC2:
bit EXPSGN
bpl FINE
lda #0
sec
sbc TENEXP
jmp FINE1
FINDP:
ror DPTFLG
bit DPTFLG
bvc FINC
FINE:
lda TENEXP
FINE1:
sec
sbc DECCNT ; Get number of places to shift
sta TENEXP
beq FINQNG ; Negate?
bpl FINMUL ; Positive so multiply
FINDIV:
jsr div10_FAC1_p
inc TENEXP ; Done?
bne FINDIV ; No
beq FINQNG ; Yes
FINMUL:
jsr mul10_FAC1
dec TENEXP ; Done
bne FINMUL ; No
FINQNG:
lda SGNFLG
bmi NEGXQS ; If positive, Return
rts
NEGXQS:
jmp toggle_sign_FAC1 ; Otherwise, negate and return
FINDIG:
pha
bit DPTFLG
bpl FINDG1
inc DECCNT
FINDG1:
jsr mul10_FAC1
pla ; Get it back
sec
sbc #'0'
jsr FINLOG ; Add it in
jmp FINC
} else {
+STUB_IMPLEMENTATION
}
+43
View File
@@ -0,0 +1,43 @@
;; #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 - add an ASCII digit in A that has been converted to a signed integer to FAC1
;
; This is verified to be identical to the original Microsoft implementation where it was named FINEDG.
;
; HERE PACK IN THE NEXT DIGIT OF THE EXPONENT.
; MULTIPLY THE OLD EXP BY 10 AND ADD IN THE NEXT
; DIGIT. NOTE: EXP OVERFLOW IS NOT CHECKED FOR.
!ifdef CONFIG_MEMORY_MODEL_38K {
FINEDG:
lda TENEXP ; Get exp so far
cmp #10 ; Will result be >= 100
bcc MLEX10
lda #100 ; Get 100
bit EXPSGN
bmi MLEXMI ; If neg exp, no check for overflow
jmp overflow_error
MLEX10:
asl ; Mult by 2 twice
asl
clc ; Possible shift out of high
adc TENEXP ; Like multiplying by five
asl ; And now by ten
clc
ldy #0
adc (TXTPTR),Y
sec
sbc #'0'
MLEXMI:
sta TENEXP ; Save result
jmp FINEC
}
-68
View File
@@ -1,68 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - denormalize FAC1 mantissa and adapt its exponent accordingly for division
;
div_FAC1_denorm:
; Set FACOV to 0, no need for increased precision here
lda #$00
sta FACOV
; Start by moving whole bytes, if possible
lda FAC1_mantissa+3
bne div_FAC1_denorm_by_bit ; branch if last byte of mantissa is non-zero
lda FAC1_exponent
cmp #$08
bcc div_FAC1_denorm_by_bit ; branch if not suitable to increment exponent by 8
; Increment exponent
sbc #$08 ; Carry already sec
sta FAC1_exponent
; Move mantissa bytes
lda FAC1_mantissa+2
sta FAC1_mantissa+3
lda FAC1_mantissa+1
sta FAC1_mantissa+2
lda FAC1_mantissa+0
sta FAC1_mantissa+1
lda #$00
sta FAC1_mantissa+0
beq div_FAC1_denorm ; branch always
div_FAC1_denorm_by_bit:
lda FAC1_mantissa+3
and #$01
bne div_FAC1_denorm_done ; branch if lowest bit of mantissa is already 1
lda FAC1_exponent
beq div_FAC1_denorm_done ; branch if not suitable to decrement exponent
; Decrement exponent
dec FAC1_exponent
; Move mantissa bits
clc
ror FAC1_mantissa+0
ror FAC1_mantissa+1
ror FAC1_mantissa+2
ror FAC1_mantissa+3
bcc div_FAC1_denorm_by_bit ; branch always
div_FAC1_denorm_done:
rts
-84
View File
@@ -1,84 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
; Math package - 32-bit mantissa division, based on code by Verz
;
; divident: FAC2_mantissa, divisor: FAC1_mantissa (without FACOV), result: FAC2_mantissa, remainder: RESHO
; temporary storage: INDEX+0, INDEX+1, INDEX+2, INDEX+3
;
; RESHO (remainder) should be set to 0 before
;
; see https://codebase64.org/doku.php?id=base:24bit_division_24-bit_result
; XXX test this
div_mantissas:
ldx #32 ; repeat for each bit
; FALLTROUGH
div_mantissas_loop:
; Multiply divident by 2, msb -> Carry
asl FAC2_mantissa+3
rol FAC2_mantissa+2
rol FAC2_mantissa+1
rol FAC2_mantissa+0
; Multiply remainder by 2, lsb <- Carry
rol RESHO+3
rol RESHO+2
rol RESHO+1
rol RESHO+0
; Subtract divisor from the remainder, result to INDEX and .Y
sec
lda RESHO+3
sbc FAC1_mantissa+3
sta INDEX+3
lda RESHO+2
sbc FAC1_mantissa+2
sta INDEX+2
lda RESHO+1
sbc FAC1_mantissa+1
sta INDEX+1
lda RESHO+0
sbc FAC1_mantissa+0
bcc div_mantissas_skip ; if Carry is not set then divisor did not fit in remainder yet
sta INDEX+0
; Save subtraction result as new remainder
lda INDEX+3
sta RESHO+3
lda INDEX+2
sta RESHO+2
lda INDEX+1
sta RESHO+1
lda INDEX+0
sta RESHO+0
; Increment result cause divisor fit in 1 times
inc FAC2_mantissa+3
; FALLTROUGH
div_mantissas_skip:
dex
bne div_mantissas_loop
rts
-16
View File
@@ -1,16 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Multiply FAC1 by 2, do not normalize
;
mul10_FAC1_mul2:
; Increment the exponent
inc FAC1_exponent
+beq overflow_error
rts
-30
View File
@@ -1,30 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - helper routines for RESHO manipulation
;
muldiv_RESHO_set_0:
lda #$00
sta RESHO+0
sta RESHO+1
sta RESHO+2
sta RESHO+3
sta RESHO+4
rts
muldiv_RESHO_01_add_A:
clc
adc RESHO+0
sta RESHO+0
bcc @1
inc RESHO+1
@1:
rts
+6 -1
View File
@@ -3,8 +3,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 - The floating point constant -32768
;
; This is verified to be identical to the original Microsoft implementation where it was named N32768.
;
; Math package - a constant, for documentation see:
; - https://www.c64-wiki.com/wiki/BASIC-ROM
; - Computes Mapping the Commodore 64, page 105
;
-74
View File
@@ -1,74 +0,0 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Math package - copy FAC1 to memory location, do not round
;
; Input:
; - .X - address low byte
; - .Y - address high byte
;
; Output:
; - .A - FAC1 exponent
;
; See also:
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
mov_FAC1_MEM:
; Original routines use $22/$23 location for a vector too, see here:
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
sty INDEX+1
stx INDEX+0
ldy #$00
; Copy exponent
lda FAC1_exponent
sta (INDEX), y
beq mov_FAC1_MEM_end ; for 0 no need to copy anything more
; Copy first byte of mantissa
iny
lda FAC2_mantissa+3
sta (INDEX), y
; Copy the sign XXX try to optimize this part
lda FAC1_sign
bne @1
lda FAC2_mantissa+3
and #$7F
sta (INDEX), y
@1:
; Copy remaining parts of mantissa
iny
lda FAC2_mantissa+2
sta (INDEX), y
iny
lda FAC2_mantissa+1
sta (INDEX), y
iny
lda FAC2_mantissa+0
sta (INDEX), y
; Checked, that mov_FAC1_MEM works on real ROM too (at $BBD7),
; and clears FACOV in a similar way as mov_FAC1_FAC2 does (not surprising)
ldy #$00
sty FACOV
mov_FAC1_MEM_end:
lda FAC1_exponent
rts
File renamed without changes.
+74
View File
@@ -0,0 +1,74 @@
;; #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 - set FAC1 as FAC2 raised to the power of FAC1
;
; This is verified to be almost identical to the original Microsoft implementation where it was named FPWRT.
;
; Input:
; - .A - must load FAC1 exponent ($61) beforehand to set the zero flag
;
; Note:
; - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?)
; - uses exp(x*log(y)) formula to calculate y^x; slow and inaccurate
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 117
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; EXPONENTIATION --- X^Y.
; N.B. 0^0=1
; FIRST CHECK IF Y=0. IF SO, THE RESULT IS 1.
; NEXT CHECK IF X=0. IF SO THE RESULT IS 0.
; THEN CHECK IF X.GT.0. IF NOT CHECK THAT Y IS AN INTEGER.
; IF SO, NEGATE X, SO THAT LOG DOESN'T GIVE FCERR.
; IF X IS NEGATIVE AND Y IS ODD, NEGATE THE RESULT
; RETURNED BY EXP.
; TO COMPUTE THE RESULT USE X^Y=EXP((Y*LOG(X)).
!ifdef CONFIG_TRANSCENDENTAL_FUNCTIONS {
!ifdef CONFIG_MEMORY_MODEL_38K {
pwr_FAC2_FAC1:
beq exp_FAC1 ; If FAC1=0, just exponentiate that
lda FAC2_exponent ; Is X=0?
bne FPWRT1
jmp ZEROF1 ; Zero FAC1
FPWRT1:
ldx #TEMPF3 ; Save for later in a temp
ldy #0
jsr mov_r_FAC1_MEM
; Y=0 already. Good in case no one calls INT
lda FAC2_sign
bpl FPWR1 ; No problems if X>0
jsr int_FAC1 ; Integerize the FAC1
lda #TEMPF3 ; Get addr of comperand
ldy #0
jsr FCOMP ; Equal?
bne FPWR1 ; Leave X neg. log will blow him out. A=-1 and Y is irrelevant
tya ; Negate X. Make positive
ldy INTEGR ; Get evenness
FPWR1:
jsr mov_FAC2_FAC1_sign ; Alternate entry point
tya
pha ; Save evenness for later
jsr log_FAC1 ; Find log
lda #TEMPF3 ; Multiply FAC1 times log(x)
ldy #0
jsr mul_MEM_FAC1
jsr exp_FAC1 ; Exponentiate the FAC1
pla
lsr ; Is it even=
bcc NEGRTS ; Yes. or X>0
; FALLTHROUGH to toggle_sign_FAC1
}
}
+47
View File
@@ -0,0 +1,47 @@
;; #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 - exponential function, e raised to FAC1 power
;
; This is verified to be almost identical to the original Microsoft implementation where it was named EXP.
; The addition is the jmp between the two ROMs
;
; See also:
; - [CM64] Computes Mapping the Commodore 64 - page 117
; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
;
; FIRST SAVE THE ORIGINAL ARGUMENT AND MULTIPLY THE FAC BY
; LOG2(E). THE RESULT IS USED TO DETERMINE IF OVERFLOW
; WILL OCCUR SINCE EXP(X)=2^(X*LOG2(E)) WHERE
; LOG2(E)=LOG(E) BASE 2. THEN SAVE THE INTEGER PART OF
; THIS TO SCALE THE ANSWER AT THE END. SINCE
; 2^Y=2^INT(Y)*2^(Y-INT(Y)) AND 2^INT(Y) IS EASY TO COMPUTE.
; NOW COMPUTE 2^(X*LOG2(E)-INT(X*LOG2(E)) BY
; P(LN(2)*(INT(X*LOG2(E))+1)-X) WHERE P IS AN APPROXIMATION
; POLYNOMIAL. THE RESULT IS THEN SCALED BY THE POWER OF 2
; PREVIOUSLY SAVED.
!ifdef CONFIG_TRANSCENDENTAL_FUNCTIONS {
!ifdef CONFIG_MEMORY_MODEL_38K {
exp_FAC1:
lda #<const_INV_LOG_2 ; Multiply by log_2(e)
ldy #>const_INV_LOG_2
jsr mul_MEM_FAC1
lda FACOV
adc #$50
bcc @1
jsr INCRND
@1 jmp STOLD ; The BASIC ROM ends here so we need to jump to the KERNAL ROM
} else {
jmp do_NOT_IMPLEMENTED_error
} }
File renamed without changes.
@@ -0,0 +1,53 @@
;; #LAYOUT# STD * #TAKE
;; #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.
; Continuation of the exp function in the BASIC part of KERNAL ROM
!ifdef CONFIG_TRANSCENDENTAL_FUNCTIONS {
!ifdef CONFIG_MEMORY_MODEL_38K {
STOLD:
sta OLDOV
jsr mov_FAC1_FAC2 ; To save in FAC2 without ROUND
lda FAC1_exponent
cmp #$88 ; IF abs(FAC1) >= 128, too big
bcc @3
@2
jsr MLDVEX ; overflow or overflow
@3
jsr int_FAC1
lda CHARAC ; Get low part
clc
adc #$81
beq @2 ; overflow or overflow !!
sec
sbc #1 ; Subtract 1
pha ; Save a while
ldx #5 ; Prep to swap FAC1 and FAC2
@4
lda FAC2_exponent,X
ldy FAC1_exponent,X
sta FAC1_exponent,X
sty FAC2_exponent,X
dex
bpl @4
lda OLDOV
sta FACOV
jsr sub_FAC2_FAC1
jsr toggle_sign_FAC1 ; Negate FAC1
lda #<poly_exp
ldy #>poly_exp
jsr poly2_FAC1
lda #$00
sta ARISGN ; Multiply by positive 1.0
pla ; Get scale factor
jsr MLDEXP ; Modify FAC1_exponent and check for overflow
rts
}
}
+3
View File
@@ -0,0 +1,3 @@
JSR $BC5B
Call to known BASIC function FCOMP
+3
View File
@@ -0,0 +1,3 @@
JSR $0073 + BCC
Call CHRGET in zero page. From BASIC
+1
View File
@@ -0,0 +1 @@
Call CHRGOT and FIN. Both known BASIC functions
+3
View File
@@ -0,0 +1,3 @@
JSR $BBD4 + LDA
Call known floating point move function in BASIC
+3
View File
@@ -0,0 +1,3 @@
RTS + JSR $B3A6
Call BASIC error function
+3
View File
@@ -0,0 +1,3 @@
$B4 + BCC $03 + JMP
Fragment
+16 -16
View File
@@ -20,21 +20,19 @@ int matches[MAX_SIZE];
int phase_mask[MAX_SIZE+MAX_SIZE];
#define NUM_CHUNKS 14
#define NUM_CHUNKS 12
// Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC
unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
0xAEA8, 0xAEAC,
0xB1A5, 0xB1A9,
0xB248, 0xB24C,
0xB391, 0xB39D,
0xB3A2, 0xB3A5,
0xB849, 0xB97D,
0xB983, 0xBCF2,
0xBD7E, 0xBD90,
0xBDB3, 0xBDC1,
0xB983, 0xBDC1,
0xBDDD, 0xBF51,
0xBF71, 0xBF7A,
0xBFB4, 0xBFEC,
0xE043, 0xE08C,
0xBF71, 0xBFFF,
0xE000, 0xE08C,
0xE264, 0xE2C2, // Two byte gap here is an optimization
0xE2C5, 0xE37A,
};
@@ -307,16 +305,18 @@ int main(int argc,char **argv)
fclose(f);
}
// Otherwise, the match is unexplained.
matches[k]++;
// Display particularly long matches
printf("$%04X = $%04X :",i,j);
for(int b=0;b<k;b++) {
printf(" %02X",f1[i+b]);
if (k > 3) {
// Otherwise, the match is unexplained.
matches[k]++;
// Display particularly long matches
printf("$%04X = $%04X :",i,j);
for(int b=0;b<k;b++) {
printf(" %02X",f1[i+b]);
}
printf("\n");
}
printf("\n");
}
}
}