diff --git a/CONFIG.md b/CONFIG.md index f8c11248..027794e8 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -13,6 +13,37 @@ Note however, that features do not came for free - enabling them needs some addi Sane defaults are already present - different for each target. +## Processor instruction set + +### `CONFIG_CPU_MOS_6502` + +Choose if your CPU only supports the original MOS Technology 6502 instruction set, like: + +* MOS 6510 - used in the Commodore 64 +* MOS 8500 - used in the Commodore 64C +* MOS 8502 - used in the Commodore 128 + +If unsure - select this one. + +### `CONFIG_CPU_WDC_65C02` + +Choose if your CPU supports the Western Design Center 65C02 instruction set, like: + +* WDC 65C02 - used in the Turbo Master accelerator +* CSG 65CE02 +* CSG 4510 - used in the Commodore 65 prototypes + +It enables some speed/size code optimizations. Warning - this is untested! + +### `#define CONFIG_CPU_WDC_65816` + +Choose if your CPU supports the 16-bit Western Design Center 65816 instruction set, like: + +* WDC 65C816 - used in the Flash 8 accelerator +* WDC 65C816S - used in the SuperCPU accelerator + +It enables some speed/size code optimizations. Warning - this is untested! + ## Memory models Different layouts of memory are possible - but they can be selected at compile time only. @@ -56,3 +87,9 @@ Each of them needs a couple of bytes in KERNAL segment - but they can share some If enabled, a simple DOS wedge is available from the direct mode - supports `@`, `@`, `@$`, `@$` and `@` commands. Feature needs about 330 bytes in BASIC segment. + +### `CONFIG_BCD_SAFE_INTERRUPTS` + +On the most widespread CPUs the D flag is not cleared upon entering interrupts. Since the original Kernal does not clear it either, it's not safe to use BCD processor mode without disabling the interrupts first. This option makes sure the D flag is disabled at the start of the interrupt - this allows some optimizations in the code. + +Feature needs 2 bytes in KERNAL segmment (for CPUs needing the patch), but at the same time allows optimizations allowing to gain some more bytes. If unsure - enable. diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index 7f57226d..74d3ac34 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -4,6 +4,10 @@ // +#define CONFIG_CPU_MOS_6502 +// #define CONFIG_CPU_WDC_65C02 +// #define CONFIG_CPU_WDC_65816 + #define CONFIG_MEMORY_MODEL_38K // #define CONFIG_MEMORY_MODEL_60K @@ -17,3 +21,4 @@ // #define CONFIG_SID_D5XX #define CONFIG_DOS_WEDGE +#define CONFIG_BCD_SAFE_INTERRUPTS diff --git a/c64/,,config_mega65.s b/c64/,,config_mega65.s index 14782cd8..33cf79eb 100644 --- a/c64/,,config_mega65.s +++ b/c64/,,config_mega65.s @@ -4,6 +4,10 @@ // +#define CONFIG_CPU_MOS_6502 +// #define CONFIG_CPU_WDC_65C02 +// #define CONFIG_CPU_WDC_65816 + // #define CONFIG_MEMORY_MODEL_38K #define CONFIG_MEMORY_MODEL_60K @@ -17,3 +21,4 @@ // #define CONFIG_SID_D5XX #define CONFIG_DOS_WEDGE +#define CONFIG_BCD_SAFE_INTERRUPTS diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index 5fa131a9..e5e4372c 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -4,6 +4,10 @@ // +#define CONFIG_CPU_MOS_6502 +// #define CONFIG_CPU_WDC_65C02 +// #define CONFIG_CPU_WDC_65816 + #define CONFIG_MEMORY_MODEL_38K // #define CONFIG_MEMORY_MODEL_60K @@ -17,3 +21,4 @@ #define CONFIG_SID_D5XX #define CONFIG_DOS_WEDGE +#define CONFIG_BCD_SAFE_INTERRUPTS diff --git a/c64/aliases/,aliases_config.s b/c64/aliases/,aliases_config.s new file mode 100644 index 00000000..58738507 --- /dev/null +++ b/c64/aliases/,aliases_config.s @@ -0,0 +1,61 @@ + + // Various configuration dependent aliases/macros/checks + + + + // Check that memory model configuration is correct + +{ + .var selected = 0; + +#if CONFIG_MEMORY_MODEL_38K + .eval selected++ +#endif +#if CONFIG_MEMORY_MODEL_60K + .eval selected++ +#endif + + .if (selected != 1) .error "Please select exactly one CONFIG_MEMORY_MODEL_* option" +} + + + + // Check that processor configuration is correct + +{ + .var selected = 0; + +#if CONFIG_CPU_MOS_6502 + .eval selected++ +#endif +#if CONFIG_CPU_WDC_65C02 + .eval selected++ +#endif +#if CONFIG_CPU_WDC_65816 + .eval selected++ +#endif + + .if (selected != 1) .error "Please select exactly one CONFIG_CPU_* option" +} + + + + // Handle processor configuration + +#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_WDC_65816 + +#define HAS_BCD_SAFE_INTERRUPTS +#define HAS_BCD_SAFE_RESET + + .pseudocommand phx { .byte $DA } + .pseudocommand phy { .byte $5A } + .pseudocommand plx { .byte $FA } + .pseudocommand ply { .byte $7A } + +#endif + + // Handle misc configuration entrues + +#if CONFIG_BCD_SAFE_INTERRUPTS +#define HAS_BCD_SAFE_INTERRUPTS +#endif \ No newline at end of file diff --git a/c64/basic/printf.s b/c64/basic/printf.s index 3266710f..efa6a4c7 100644 --- a/c64/basic/printf.s +++ b/c64/basic/printf.s @@ -139,7 +139,13 @@ printf_retreat: rts printf_printhexbyte: - // Print the hex value in .A as two digits, idea by Haubitze + + // Print the hex value in .A as two digits + +#if HAS_BCD_SAFE_INTERRUPTS + + // Idea by Haubitze + sed pha lsr @@ -155,3 +161,25 @@ printf_printhexbyte: adc #$30 cld jmp JCHROUT + +#else + + pha + lsr + lsr + lsr + lsr + ora #$30 + cmp #$3A + bcc !+ + adc #6 +!: jsr JCHROUT + pla + and #$0f + ora #$30 + cmp #$3A + bcc !+ + adc #6 +!: jmp JCHROUT + +#endif diff --git a/c64/kernal/interrupts/ea81.return_from_interrupt.s b/c64/kernal/interrupts/ea81.return_from_interrupt.s index fa799bff..4908b8ed 100644 --- a/c64/kernal/interrupts/ea81.return_from_interrupt.s +++ b/c64/kernal/interrupts/ea81.return_from_interrupt.s @@ -11,10 +11,16 @@ return_from_interrupt: // Restore registers and return // Sequence according to Compute's Mapping the 64 p73 + +#if CONFIG_CPU_MOS_6502 pla tay pla tax +#else + ply + plx +#endif pla rti diff --git a/c64/kernal/interrupts/fe47.default_nmi_handler.s b/c64/kernal/interrupts/fe47.default_nmi_handler.s index 2c89e4a0..97cdb1d6 100644 --- a/c64/kernal/interrupts/fe47.default_nmi_handler.s +++ b/c64/kernal/interrupts/fe47.default_nmi_handler.s @@ -6,10 +6,15 @@ default_nmi_handler: // Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 pha +#if CONFIG_CPU_MOS_6502 txa pha tya pha +#else + phx + phy +#endif // XXX: RS-232 support is not implemented diff --git a/c64/kernal/interrupts/irq_handler.s b/c64/kernal/interrupts/irq_handler.s index 0d7d6de9..aad1fb9d 100644 --- a/c64/kernal/interrupts/irq_handler.s +++ b/c64/kernal/interrupts/irq_handler.s @@ -10,12 +10,19 @@ irq_handler: // Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 pha +#if CONFIG_CPU_MOS_6502 txa pha tya pha +#else + phx + phy +#endif - cld // clear decimal flag, to prevent possible problems +#if CONFIG_CPU_MOS_6502 && CONFIG_BCD_SAFE_INTERRUPTS + cld // clear decimal flag to allow using it without disabling interrupts +#endif // Check if caused by BRK tsx diff --git a/c64/kernal/interrupts/nmi_handler.s b/c64/kernal/interrupts/nmi_handler.s index 6c1275a0..9c0b668d 100644 --- a/c64/kernal/interrupts/nmi_handler.s +++ b/c64/kernal/interrupts/nmi_handler.s @@ -2,7 +2,10 @@ nmi_handler: sei // don't allow IRQ to interfere, see https://www.c64-wiki.com/wiki/Interrupt - cld // clear decimal flag, to prevent possible problems + +#if CONFIG_CPU_MOS_6502 && CONFIG_BCD_SAFE_INTERRUPTS + cld // clear decimal flag to allow using it without disabling interrupts +#endif // Call interrupt routine (only if initialised) pha diff --git a/c64/kernal/printf.s b/c64/kernal/printf.s index cb87548a..599e4e15 100644 --- a/c64/kernal/printf.s +++ b/c64/kernal/printf.s @@ -139,7 +139,13 @@ printf_retreat: rts printf_printhexbyte: - // Print the hex value in .A as two digits, idea by Haubitze + + // Print the hex value in .A as two digits + +#if HAS_BCD_SAFE_INTERRUPTS + + // Idea by Haubitze + sed pha lsr @@ -155,3 +161,25 @@ printf_printhexbyte: adc #$30 cld jmp JCHROUT + +#else + + pha + lsr + lsr + lsr + lsr + ora #$30 + cmp #$3A + bcc !+ + adc #6 +!: jsr JCHROUT + pla + and #$0f + ora #$30 + cmp #$3A + bcc !+ + adc #6 +!: jmp JCHROUT + +#endif diff --git a/c64/kernal/reset_entry.s b/c64/kernal/reset_entry.s index 17b021ad..89382905 100644 --- a/c64/kernal/reset_entry.s +++ b/c64/kernal/reset_entry.s @@ -5,9 +5,10 @@ reset_entry: // The GPL program at https://github.com/Klaus2m5/6502_65C02_functional_tests/blob/master/6502_functional_test.a65 - // uses the following initial reset sequence - // affirmed by c64 PRG p269 - cld + // uses the following initial reset sequence, affirmed by c64 PRG p269 +#if !HAS_BCD_SAFE_RESET + cld // for CPUs having undefined D flag after reset +#endif ldx #$FF txs sei