Skip to content

Commit

Permalink
[KERNAL] Initial 65C816 support (X16Community#281)
Browse files Browse the repository at this point in the history
* Proof of Concept for resolving the clash of UDTIM with the 65C816's NMIB vector.

At $FFEA in the ROM is the jump table entry for UDTIM aka `jmp clock_update`.
In native mode, the 65C816 reads its NMIB vector from $FFEA as well. By
hardcoding the address for `clock_update`, which is an alias for
`softclock_timer_update`, to an address with the low byte $XX, the NMIB
handler can be hardcoded to $XX4C, as $4C is the opcode for an absolute `jmp`.
This PoC uses $EEEE for `softclock_timer_update` and $EE4C for the NMIB handler
as example values.

* Add 65C816 support for NMI, IRQ and BRK

* Add support for COP

* Add native IRQ handler and make sure BASIC starts in emulation mode

* Replace low RAM 65C816 detection variable with a runtime detection macro

* SCREEN: Don't clobber Y

* Handle DP and SP in native IRQ

* Use 03 instead of 01 for CPU detection

* Add native interrupt and emulated COP vectors and fully implement all interrupt types

* Add native and emulated ABORT handler

* Reorder segments so that C816_ABORT_NATIVE can sit at address

* Add dedicated vectors in KVECTORS

* Move the KERNAL signature to the SIGNATURE section (see X16Community/x16-emulator@23f1f14

* Fix COP and ABORT trampolines not being in low RAM

* 65c816.s: Indent with tabs

* Remove now-unused KVEC816 segment

* Move 65c816.s to drivers/x16/65c816/interrupt.s

* Fix SCREEN and IOBASE interrupt dispatch logic

* Add first draft of stack API

* fixup! Fix SCREEN and IOBASE interrupt dispatch logic

* fixup! Fix SCREEN and IOBASE interrupt dispatch logic

* STACK: Use an extra byte that is always  for code simplification

* Rename STACK_foo to stack_foo

* Native IRQ: Call the KERNAL emulated IRQ code directly in native mode if the emulated IRQ vector hasn't been replaced

* Add missing newline at end of files

* Explicitely annotate 65C816 code with address & index width

* fix minor error while rebasing

* [KERNAL] add legacy/c816 extended APIs (X16Community#280)

* [KERNAL] refactor, comment 65C816 native stack API

* rewording comments

* [KERNAL] implement native-capable jsrfar (X16Community#283)

* [KERNAL] implement native-capable jsrfar

* native jsrfar falls back to old code if in emulated mode

* fix off-by-one error

* fix up some logic, jmpfr need only be in one place

* Save a couple cycles here

* save a few more cycles w/ carry assumptions

* add assert for jsrfar3n

* saved one more cycle

* trivial changes

* trivial changes

* updates to comments

* updates to comments

* no need to preserve X in the native jsrfar

* fix stack misalignment issue in a 16-bit jsrfar call

* requested changes

* [KERNAL] typo in 816 native jsrfar RAM routine

* [KERNAL] add extapi16 #0 test reflector call

* [CI/CD] the first unit tests

* [CI/CD] update build deps

* [MONITOR] 65C816 emulation mode stack unwinding (X16Community#292)

* [META] remove CODEX, move DIAG 16->7 (X16Community#293)

---------

Co-authored-by: George Tokmaji <[email protected]>
  • Loading branch information
mooinglemur and Fulgen301 authored Mar 11, 2024
1 parent b45ccfc commit 85878c1
Show file tree
Hide file tree
Showing 104 changed files with 1,342 additions and 16,043 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
python-version: '3.9'
- name: Install Dependencies
run: |
sudo apt-get install -y make build-essential
sudo apt-get install -y make build-essential libsdl2-dev
git clone https://github.com/cc65/cc65.git
cd cc65
make -j4
Expand All @@ -31,6 +31,16 @@ jobs:
if: startsWith(github.ref, 'refs/tags/r')
run: |
RELEASE_VERSION=$(echo "$GITHUB_REF_NAME" | grep -oP '[0-9]+$') make
- name: Build Test Emulator
run: |
git clone https://github.com/X16Community/x16-emulator.git
cd x16-emulator
git checkout 65c816
make all
- name: Run Unit Tests
run: |
export PATH="$(pwd)/x16-emulator:$PATH"
make test
- name: Archive Build Result
run: |
mkdir artifact
Expand Down
45 changes: 29 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ KERNAL_CORE_SOURCES = \
kernal/cbm/nmi.s \
kernal/cbm/irq.s \
kernal/cbm/util.s \
kernal/cbm/serial.s
kernal/cbm/serial.s \
kernal/x16/extapi.s \
kernal/x16/65c816/interrupt.s \
kernal/x16/65c816/stack.s \
kernal/x16/65c816/extapi16.s

KERNAL_GRAPH_SOURCES = \
kernal/graph/graph.s \
Expand Down Expand Up @@ -176,10 +180,21 @@ GENERIC_DEPS = \
inc/banks.inc \
inc/jsrfar.inc \
inc/regs.inc \
inc/65c816.inc \
kernsup/kernsup.inc

KERNAL_DEPS = \
$(GENERIC_DEPS) \
kernal/cbm/channel/channelio.s \
kernal/cbm/channel/clall.s \
kernal/cbm/channel/close.s \
kernal/cbm/channel/errorhandler.s \
kernal/cbm/channel/load.s \
kernal/cbm/channel/messages.s \
kernal/cbm/channel/open.s \
kernal/cbm/channel/openchannel.s \
kernal/cbm/channel/save.s \
kernal/cbm/channel/x16additions.s \
$(GIT_SIGNATURE)

KEYMAP_DEPS = \
Expand Down Expand Up @@ -294,15 +309,14 @@ BANK_BINS = \
$(BUILD_DIR)/basic.bin \
$(BUILD_DIR)/monitor.bin \
$(BUILD_DIR)/charset.bin \
$(BUILD_DIR)/codex.bin \
$(BUILD_DIR)/diag.bin \
$(BUILD_DIR)/graph.bin \
$(BUILD_DIR)/demo.bin \
$(BUILD_DIR)/audio.bin \
$(BUILD_DIR)/util.bin \
$(BUILD_DIR)/bannex.bin \
$(BUILD_DIR)/x16edit-rom.bin \
$(BUILD_DIR)/basload-rom.bin \
$(BUILD_DIR)/diag.bin \
$(BUILD_DIR)/basload-rom.bin

ROM_LABELS=$(BUILD_DIR)/rom_labels.h
ROM_LST=$(BUILD_DIR)/rom_lst.h
Expand All @@ -313,6 +327,9 @@ all: $(BUILD_DIR)/rom.bin $(ROM_LABELS) $(ROM_LST)
$(BUILD_DIR)/rom.bin: $(BANK_BINS)
cat $(BANK_BINS) > $@

test: FORCE $(BUILD_DIR)/rom.bin
for f in test/unit/*/*.py; do PYTHONPATH="test/unit" python3 -B $${f}; done

x16edit_update:
@rm -rf x16edittmp
git clone https://github.com/stefan-b-jakobsson/x16-edit.git x16edittmp
Expand All @@ -330,7 +347,6 @@ basload_update:
clean:
rm -f $(GIT_SIGNATURE)
rm -rf $(BUILD_DIR)
$(MAKE) -C codex clean

$(GIT_SIGNATURE): FORCE
@mkdir -p $(BUILD_DIR)
Expand Down Expand Up @@ -393,9 +409,11 @@ $(BUILD_DIR)/charset.bin: $(CHARSET_OBJS) $(CHARSET_DEPS) $(CFG_DIR)/charset-x16
@mkdir -p $$(dirname $@)
$(LD) -C $(CFG_DIR)/charset-x16.cfg $(CHARSET_OBJS) -o $@ -m $(BUILD_DIR)/charset.map -Ln $(BUILD_DIR)/charset.sym

# Bank 7 : CodeX
$(BUILD_DIR)/codex.bin: $(CFG_DIR)/codex-x16.cfg
$(MAKE) -C codex
# Bank 7: Memory diagnostic
$(BUILD_DIR)/diag.bin: $(DIAG_OBJS) $(DIAG_DEPS) $(CFG_DIR)/diag-x16.cfg
@mkdir -p $$(dirname $@)
$(LD) -C $(CFG_DIR)/diag-x16.cfg $(DIAG_OBJS) -o $@ -m $(BUILD_DIR)/diag.map -Ln $(BUILD_DIR)/diag.sym
./scripts/relist.py $(BUILD_DIR)/diag.map $(BUILD_DIR)/diag

# Bank 8 : Graphics
$(BUILD_DIR)/graph.bin: $(GRAPH_OBJS) $(KERNAL_DEPS) $(CFG_DIR)/graph.cfg
Expand Down Expand Up @@ -446,12 +464,6 @@ $(BUILD_DIR)/basload-rom.bin: $(BASLOAD_DEPS)
(cd basload && make clean && make)
cp basload/build/basload-rom.bin $(BUILD_DIR)/basload-rom.bin

# Bank 10: Memory diagnostic
$(BUILD_DIR)/diag.bin: $(DIAG_OBJS) $(DIAG_DEPS) $(CFG_DIR)/diag-x16.cfg
@mkdir -p $$(dirname $@)
$(LD) -C $(CFG_DIR)/diag-x16.cfg $(DIAG_OBJS) -o $@ -m $(BUILD_DIR)/diag.map -Ln $(BUILD_DIR)/diag.sym
./scripts/relist.py $(BUILD_DIR)/diag.map $(BUILD_DIR)/diag

$(BUILD_DIR)/rom_labels.h: $(BANK_BINS)
./scripts/symbolize.sh 0 build/x16/kernal.sym > $@
./scripts/symbolize.sh 1 build/x16/keymap.sym >> $@
Expand All @@ -460,18 +472,19 @@ $(BUILD_DIR)/rom_labels.h: $(BANK_BINS)
./scripts/symbolize.sh 4 build/x16/basic.sym >> $@
./scripts/symbolize.sh 5 build/x16/monitor.sym >> $@
./scripts/symbolize.sh 6 build/x16/charset.sym >> $@
./scripts/symbolize.sh 7 build/x16/diag.sym >> $@
./scripts/symbolize.sh A build/x16/audio.sym >> $@
./scripts/symbolize.sh B build/x16/util.sym >> $@
./scripts/symbolize.sh C build/x16/bannex.sym >> $@
./scripts/symbolize.sh 10 build/x16/diag.sym >> $@

$(BUILD_DIR)/rom_lst.h: $(BANK_BINS)
./scripts/trace_lst.py 0 `find build/x16/kernal/ -name \*.rlst` > $@
./scripts/trace_lst.py 2 `find build/x16/dos/ -name \*.rlst` >> $@
./scripts/trace_lst.py 3 `find build/x16/fat32/ -name \*.rlst` >> $@
./scripts/trace_lst.py 4 `find build/x16/basic/ -name \*.rlst` >> $@
./scripts/trace_lst.py 5 `find build/x16/monitor/ -name \*.rlst` >> $@
./scripts/trace_lst.py 7 `find build/x16/diag/ -name \*.rlst` >> $@
./scripts/trace_lst.py A `find build/x16/audio/ -name \*.rlst` >> $@
./scripts/trace_lst.py B `find build/x16/util/ -name \*.rlst` >> $@
./scripts/trace_lst.py C `find build/x16/bannex/ -name \*.rlst` >> $@
./scripts/trace_lst.py 10 `find build/x16/diag/ -name \*.rlst` >> $@

15 changes: 13 additions & 2 deletions basic/init.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
.byte BANK_BANNEX
.endmacro

.include "65c816.inc"
.include "bannex.inc"

panic jsr clschn ;warm start basic...
panic set_carry_if_65c816
bcc pn65c816
sec
.byte $FB ; xce
clc
pn65c816 jsr clschn ;warm start basic...
lda #0 ;clear channels
sta channl
jsr stkini ;restore stack
Expand All @@ -23,7 +29,12 @@ nerror txa ;get high bit
jmp nerrox
nready jmp readyx

init jsr initv ;go init vectors
init set_carry_if_65c816
bcc in65c816
sec
.byte $FB ; xce
clc
in65c816 jsr initv ;go init vectors
jsr initcz ;go init charget & z-page
jsr initms ;go print initilization messages
stz ram_bank
Expand Down
7 changes: 1 addition & 6 deletions basic/x16additions.s
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,7 @@ monitor:
jmp clean_return

;***************
codex:
jsr bjsrfar
.word $c000
.byte BANK_CODEX
; does not return

codex: ; syntax error now that CODEX is gone
;***************
geos: ; syntax error now that GEOS is gone
ldx #errsn
Expand Down
4 changes: 2 additions & 2 deletions cfg/audio-x16.cfgtpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
MEMORY {
#include "x16.cfginc"

ROM: start = $C000, size = $3B00, fill=yes, fillval=$AA;
KSUP_CODE10: start = $FB00, size = $03A8, fill=yes, fillval=$AA;
ROM: start = $C000, size = $3A80, fill=yes, fillval=$AA;
KSUP_CODE10: start = $FA80, size = $0428, fill=yes, fillval=$AA;
KSUP_VEC10: start = $FEA8, size = $0158, fill=yes, fillval=$AA;

}
Expand Down
4 changes: 2 additions & 2 deletions cfg/bannex-x16.cfgtpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
MEMORY {
#include "x16.cfginc"

ANNEX: start = $C000, size = $3B00, fill=yes, fillval=$AA;
KSUP_CODE12: start = $FB00, size = $03A8, fill=yes, fillval=$AA;
ANNEX: start = $C000, size = $3A80, fill=yes, fillval=$AA;
KSUP_CODE12: start = $FA80, size = $0428, fill=yes, fillval=$AA;
KSUP_VEC12: start = $FEA8, size = $0158, fill=yes, fillval=$AA;
}

Expand Down
6 changes: 3 additions & 3 deletions cfg/codex-x16.cfgtpl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
MEMORY {
#include "x16.cfginc"

MAIN: file = %O, define = yes, start = $C000, size = $3AE2, fill=yes fillval=$A3;
MAIN: file = %O, define = yes, start = $C000, size = $3A72, fill=yes fillval=$A3;
RWRAM: file = "", start = $0400, size = $3FF;
BANK: file = "", start = $A000, size = $2000;
CODEX_VECS: start = $FAE2, size = $001E, fill=yes, fillval=$A0;
KSUP_CODE2: start = $FB00, size = $03A8, fill=yes, fillval=$A1;
CODEX_VECS: start = $FA72, size = $001E, fill=yes, fillval=$A0;
KSUP_CODE2: start = $FA80, size = $0418, fill=yes, fillval=$A1;
KSUP_VEC2: start = $FEA8, size = $0158, fill=yes, fillval=$A2;
}

Expand Down
22 changes: 19 additions & 3 deletions cfg/kernal-x16.cfgtpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ SEGMENTS {
I2CMUTEX: load = I2CMUTEX, type = bss;
KVAR2: load = KVAR2, type = bss;

KRAM816S: load = KRAM816S, type = bss;
GDRVVEC: load = GDRVVEC, type = bss;
KVECTORS: load = KVECTORS, type = bss;
KEYMAP: load = KEYMAP, type = bss;
Expand All @@ -32,14 +33,25 @@ SEGMENTS {
PS2: load = KERNAL, type = ro;
PS2KBD: load = KERNAL, type = ro;
PS2MOUSE: load = KERNAL, type = ro;
JOYSTICK: load = KERNAL, type = ro;
IEEESWTCH:load = KERNAL, type = ro;
SERIAL: load = KERNAL, type = ro;
MEMORY: load = KERNAL, type = ro;
LZSA: load = KERNAL, type = ro;
RS232: load = KERNAL, type = ro;
CHANNEL: load = KERNAL, type = ro;
CLOCK: load = KERNAL, type = ro;
C816_UTIL: load = KERNAL, type = ro;
C816_ABORT_NATIVE: load = KERNAL, type = ro, start = $E44C; # low byte: JMP abs, high byte equals low byte of C816_CLALL_THUNK
JOYSTICK: load = KERNAL, type = ro;
IEEESWTCH:load = KERNAL, type = ro;
C816_GETIN_THUNK: load = KERNAL, type = ro, start = $E7EF; # low byte equals high byte of C816_COP_NATIVE, high byte equals low byte of C816_BRK
CLOCK_TIMER: load = KERNAL, type = ro, start = $E94C; # low byte: JMP abs, high byte equals low byte of C816_SCRORG
C816_SCRORG: load = KERNAL, type = ro, start = $E9E9; # low byte equals high byte of CLOCK_TIMER, high byte chosen at random
C816_CLALL_THUNK: load = KERNAL, type = ro, start = $EAE4; # low byte equals high byte of C816_ABORT_NATIVE, high byte = NOP
C816_BRK: load = KERNAL, type = ro, start = $EAE7; # low byte equals high byte of C816_GETIN_THUNK, high byte = nop
C816_NMIB: load = KERNAL, type = ro, start = $EAEA; # low byte equals NOP and high byte of C816_CLALL_THUNK, high byte = NOP
C816_COP_NATIVE: load = KERNAL, type = ro, start = $EF4C; # low byte: JMP abs, high byte equals low byte of C816_GETIN_THUNK
C816_COP_EMULATED: load = KERNAL, type = ro;
C816_ABORT_EMULATED: load = KERNAL, type = ro;
I2C: load = KERNAL, type = ro;
RTC: load = KERNAL, type = ro;
NVRAM: load = KERNAL, type = ro;
Expand All @@ -55,8 +67,12 @@ SEGMENTS {
SPRITES: load = KERNAL, type = ro;
VERA_DRV: load = KERNAL, type = ro;
PALETTE: load = KERNAL, type = ro, align = $100;
KERNRAM: load = KERNAL, run = KERNRAM, type = ro, define = yes;
KRAMJFAR: load = KERNAL, run = KRAMJFAR, type = ro, define = yes;
KJFAR816: load = KERNAL, run = KJFAR816, type = ro, define = yes;
KERNRAM2: load = KERNAL, run = KERNRAM2, type = ro, define = yes;
KRAM816: load = KERNAL, run = KRAM816, type = ro, define = yes;
KRAM02B: load = KERNAL, run = KRAM02B, type = ro, define = yes;
KRAM816B: load = KERNAL, run = KRAM816B, type = ro, define = yes;
VECB0: load = KERNAL, run = VECB0, type = ro, define = yes;
JMPTBL: load = JMPTBL, type = ro;
VECTORS: load = VECTORS, type = ro;
Expand Down
4 changes: 2 additions & 2 deletions cfg/monitor-x16.cfgtpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ MEMORY {

L0220: start = $0220, size = $0019; # overlaps with top end of BASIC input line only

BANK5: start = $C000, size = $3B00, fill=yes, fillval=$AA;
KSUP_CODE2: start = $FB00, size = $03A8, fill=yes, fillval=$AA;
BANK5: start = $C000, size = $3A80, fill=yes, fillval=$AA;
KSUP_CODE2: start = $FA80, size = $0428, fill=yes, fillval=$AA;
KSUP_VEC2: start = $FEA8, size = $0158, fill=yes, fillval=$AA;
}

Expand Down
4 changes: 2 additions & 2 deletions cfg/util-x16.cfgtpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ MEMORY {
HEXEDITZP: start = $0022, size = $005E, fill=no;
HEXEDITBSS: start = $0200, size = $0050, fill=no;
MENUBSS: start = $0200, size = $0050, fill=no;
ROM: start = $C000, size = $3B00, fill=yes, fillval=$AA;
KSUP_CODE11: start = $FB00, size = $03A8, fill=yes, fillval=$AA;
ROM: start = $C000, size = $3A80, fill=yes, fillval=$AA;
KSUP_CODE11: start = $FA80, size = $0428, fill=yes, fillval=$AA;
KSUP_VEC11: start = $FEA8, size = $0158, fill=yes, fillval=$AA;

}
Expand Down
13 changes: 9 additions & 4 deletions cfg/x16.cfginc
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ ZPMATH: start = $00A9, size = $002B; # MATH
ZPBASIC: start = $00D4, size = $002B; # BASIC (last byte used: $FE)

/* $0200-$02FF: always-available variables and RAM code */
KVAR: start = $0200, size = $00BB; # KERNAL
/* start = $02BB, size = $0005; # reserved for KERNAL growth */
KVAR: start = $0200, size = $0095; # KERNAL
KRAM816S: start = $0295, size = $0003; # KERNAL: 65C816: old stack pointer
KJFAR816: start = $0298, size = $0019; # KERNAL: jsrfar3n
/* start = $02B1, size = $000F; # reserved for KERNAL growth */
I2CMUTEX: start = $02C0, size = $0001; # I2C MUTEX FLAG
GRAPHVAR: start = $02C1, size = $0003; # GRAPH BANK VARS
KERNRAM: start = $02C4, size = $0020; # KERNAL RAM code
KRAMJFAR: start = $02C4, size = $001E; # KERNAL: jsrfar3
GDRVVEC: start = $02E4, size = $001C; # framebuffer driver vectors

/* $0300-$0333: vectors */
Expand All @@ -34,7 +36,10 @@ KVECTORS: start = $0314, size = $002E; # KERNAL vectors

/* $036A-$03FF: variables and RAM code */
KVAR2: start = $036A, size = $0021; # KERNAL: screen editor state
KERNRAM2: start = $038B, size = $003F; # KERNAL: banked IRQ/NMI, fetch, stash
KERNRAM2: start = $038B, size = $0038; # KERNAL: banked IRQ/NMI, fetch, stash
KRAM816: start = $038B, size = $001D; # KERNAL: 65C816: IRQ
KRAM02B: start = $03C3, size = $0007; # KERNAL: 65C02: __irq_ret
KRAM816B: start = $03C3, size = $0007; # KERNAL: 65C816: free space
FPVARS: start = $03CA, size = $0009; # MATH
BVARS: start = $03D3, size = $002D; # BASIC

Expand Down
9 changes: 0 additions & 9 deletions codex/.gitignore

This file was deleted.

31 changes: 0 additions & 31 deletions codex/CODEX-build-notes.md

This file was deleted.

Loading

0 comments on commit 85878c1

Please sign in to comment.