Merge pull request #34 from FeralChild64/master
Various compatibility fixes
This commit is contained in:
261 files changed
+5247
-2112
No files matched your search
@@ -1,7 +1,7 @@
|
||||
|
||||
# Configuring the build
|
||||
|
||||
It's not possible to provide ROM builds that suit everyone needs - therefore configuration files were introduced, separately for each of the hardware targets:
|
||||
It's not possible to provide ROM builds that suit everyone needs - therefore configuration files were introduced, few predefined configurations are provided with sane defaults:
|
||||
|
||||
* [`c64/,,config_generic.s`](c64/,,config_generic.s)
|
||||
* [`c64/,,config_mega65.s`](c64/,,config_mega65.s)
|
||||
@@ -11,7 +11,33 @@ Just edit them and recompile the project. To enable particular option - uncommen
|
||||
|
||||
Note however, that features do not came for free - enabling them needs some additional ROM space (in BASIC segment, in KERNAL segment, or in both), which is VERY limited on the target machines. Some options might be unavailable for speecific targets - read the comments in the configuration files. Some options might also carry compatibility and/or performance hit - so choose wisely.
|
||||
|
||||
Sane defaults are already present - different for each target.
|
||||
## Hardware platform and brand
|
||||
|
||||
### `CONFIG_PLATFORM_COMMODORE_64`
|
||||
|
||||
Commodore 64 is the only hardware platform available now - and the main one, as the Open ROMs API is meant to be compatible with the Commodore 64.
|
||||
|
||||
Since Open ROMs is highly modular, it should be possible to add other platforms in the future (like 8-bit Atari computers or Commander X16), if they share the following common characteristics:
|
||||
|
||||
* MOS 6502 CPU or compatible
|
||||
* 8KB ROM area `$A000`-`$BFFF`
|
||||
* 8KB ROM area `$E000`-`$FFFF`
|
||||
|
||||
### `CONFIG_MB_MEGA_65`, `CONFIG_MB_ULTIMATE_64`
|
||||
|
||||
Select if the ROM is going to be used exclusively on the specific motherboard. It prevents from enabling options not having sense, skips initialization of C128-only registers, etc.
|
||||
|
||||
### `CONFIG_BRAND_GENERIC`
|
||||
|
||||
If you don't know which variant to choose - select this one.
|
||||
|
||||
### `CONFIG_BRAND_TESTING`
|
||||
|
||||
Use this one for any kind of testing/experimental build.
|
||||
|
||||
### `CONFIG_BRAND_MEGA_65`, `CONFIG_BRAND_ULTIMATE_64`
|
||||
|
||||
Select if you are using appropriate motherboard.
|
||||
|
||||
## Processor instruction set
|
||||
|
||||
@@ -30,10 +56,17 @@ If unsure - select this one.
|
||||
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!
|
||||
It enables some speed/size code optimizations.
|
||||
|
||||
### `CONFIG_CPU_CSG_65CE02`
|
||||
|
||||
Choose if your CPU supports the Commodore Semiconductor Group 65CE02 instruction set, like:
|
||||
|
||||
* CSG 65CE02
|
||||
* CSG 4510 - microcontroller used in the Commodore 65 prototypes
|
||||
|
||||
It enables some speed/size code optimizations.
|
||||
|
||||
### `CONFIG_CPU_WDC_65816`
|
||||
|
||||
@@ -42,9 +75,9 @@ Choose if your CPU supports the 16-bit Western Design Center 65816 instruction s
|
||||
* 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!
|
||||
It enables some speed/size code optimizations.
|
||||
|
||||
## Memory models
|
||||
## Memory model
|
||||
|
||||
Different layouts of memory are possible - but they can be selected at compile time only.
|
||||
|
||||
@@ -80,13 +113,83 @@ Cause the system to support SIDs in `$D4xx` and `$D5xx` ranges, respectively.
|
||||
|
||||
Each of them needs a couple of bytes in KERNAL segment - but they can share some code, and `$D4xx` range support replaces the standard `$D400` address handling, so exact amount depends on the exact configuration.
|
||||
|
||||
## Miscelaneous features
|
||||
## Keyboard
|
||||
|
||||
Original keyboard support routine is just horrible. It does nothing to prevent ghosting - press A+S+D at the same time - it prints F. Try to use joystick connected to control port 1 - it outputs phantom characters. The Open ROMs provides much more sophisticated routines to prevent such problems.
|
||||
|
||||
### `CONFIG_LEGACY_SCNKEY`
|
||||
|
||||
Uses old Open ROMs keyboard scanning routine, which is basically example routine by TWW/CTR, hacked to work within Kernal. It's greatest advantage is multi-key rollover, it's disadvantages - it's much less compatible (uses several bytes of memory which are normally free for user software - thus, it is considered legacy for now), does not support all the system variables (`RPTFLG` and `KEYLOG` are unsupported), and ignores the configuration options - this can be changed, but it requires some effort.
|
||||
|
||||
Needs 30-250 more space in KERNAL segment (depending on the features enabled for current default routine). If unsure - disable.
|
||||
|
||||
### `CONFIG_KEYBOARD_C128`
|
||||
|
||||
Allows to use additional keys found on the C128 keyboard. NOTE: might be buggy, on VICE emulator I can't get all the keys working.
|
||||
|
||||
Needs about 130 bytes more space in KERNAL segment. If unsure - disable.
|
||||
|
||||
### `CONFIG_KEYBOARD_C128_CAPS_LOCK`
|
||||
|
||||
Allows to use CAPS LOCK key on the C128 keyboard, this is independent from `CONFIG_KEYBOARD_C128`. Support is C64-safe (there is a protection against false-positive reading on the C64).
|
||||
|
||||
Needs about 50 bytes more space in KERNAL segment. If unsure - disable.
|
||||
|
||||
### `CONFIG_KEY_REPEAT_DEFAULT`
|
||||
|
||||
Enables key repetition by default during the startup (sets `RPTFLG`).
|
||||
|
||||
Needs 5 bytes more space in KERNAL segment.
|
||||
|
||||
### `CONFIG_KEY_REPEAT_ALWAYS`
|
||||
|
||||
Enables the key repetition and ignores `RPTFLG`.
|
||||
|
||||
Saves 22 bytes from KERNAL segment.
|
||||
|
||||
### `CONFIG_KEY_FAST_SCAN`
|
||||
|
||||
Performs somee speed optimizations in the keyboard scanning routine, at the eexpense of some more ROM space.
|
||||
|
||||
Needs 13 bytes more space in KERNAL segment. Only disable if you are running out of ROM space.
|
||||
|
||||
### `CONFIG_JOY1_CURSOR` and `CONFIG_JOY2_CURSOR`
|
||||
|
||||
Joystick movement also moves the cursor.
|
||||
|
||||
Needs about 65 bytes of ROM space to handle both joysticks.
|
||||
|
||||
## Eye candy
|
||||
|
||||
### `CONFIG_COLORS_BRAND`
|
||||
|
||||
Tries to adjust the color scheme to the selected brand. Some brands might not support this.
|
||||
|
||||
### `CONFIG_BANNER_SIMPLE`, `CONFIG_BANNER_FANCY`, `CONFIG_BANNER_BRAND`
|
||||
|
||||
Select startup banner - either a simple one, or with some colorful elements. `CONFIG_BANNER_BRAND` heavily depends on the selected brand, not all the brands support it.
|
||||
|
||||
Richer banners need more BASIC segment, varies between brands.
|
||||
|
||||
### `CONFIG_BANNER_PAL_NTSC`
|
||||
|
||||
If enabled, prints video system on startup banner. Eye candy only.
|
||||
|
||||
Feature needs some bytes in BASIC (depending on banner type) and about 25 bytes in KERNAL segment.
|
||||
|
||||
## Software features
|
||||
|
||||
### `CONFIG_PANIC_SCREEN`
|
||||
|
||||
If enabled, certain fatal errors will produce a nice bluescreen instead of just resetting the machine.
|
||||
|
||||
Feature needs over 100 bytes in KERNAL segment. If unsure - enable.
|
||||
|
||||
### `CONFIG_DOS_WEDGE`
|
||||
|
||||
If enabled, a simple DOS wedge is available from the direct mode - supports `@<drive_number>`, `@<command>`, `@$`, `@$<params>` and `@` commands.
|
||||
|
||||
Feature needs about 330 bytes in BASIC segment.
|
||||
Feature needs about 330 bytes in BASIC segment. If unsure - enable.
|
||||
|
||||
### `CONFIG_BCD_SAFE_INTERRUPTS`
|
||||
|
||||
@@ -104,4 +207,4 @@ Replaces `RTS` stubbed routines implementation with one causing a break.
|
||||
|
||||
### `CONFIG_DBG_PRINTF`
|
||||
|
||||
Makes 'printf' routine available.
|
||||
Makes `printf` routine available.
|
||||
@@ -1,17 +1,26 @@
|
||||
|
||||
# Source files
|
||||
|
||||
SRCDIR_COMMON = c64/aliases
|
||||
SRCDIR_BASIC_COMMON = $(SRCDIR_COMMON) c64/basic
|
||||
SRCDIR_KERNAL_COMMON = $(SRCDIR_COMMON) c64/kernal c64/kernal/assets c64/kernal/jumptable c64/kernal/iec c64/kernal/interrupts c64/kernal/print
|
||||
SRCDIR_COMMON = c64/aliases
|
||||
|
||||
SRCDIR_BASIC_generic = $(SRCDIR_BASIC_COMMON) c64/basic/,target_generic
|
||||
SRCDIR_BASIC_mega65 = $(SRCDIR_BASIC_COMMON) c64/basic/,target_mega65
|
||||
SRCDIR_BASIC_ultimate64 = $(SRCDIR_BASIC_COMMON) c64/basic/,target_ultimate64
|
||||
SRCDIR_BASIC = $(SRCDIR_COMMON) \
|
||||
c64/basic \
|
||||
c64/basic/commands \
|
||||
c64/basic/init \
|
||||
c64/basic/rom_revision
|
||||
|
||||
SRCDIR_KERNAL_generic = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_generic
|
||||
SRCDIR_KERNAL_mega65 = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_mega65
|
||||
SRCDIR_KERNAL_ultimate64 = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_ultimate64
|
||||
SRCDIR_KERNAL = $(SRCDIR_COMMON) \
|
||||
c64/kernal \
|
||||
c64/kernal/assets \
|
||||
c64/kernal/jumptable \
|
||||
c64/kernal/iec \
|
||||
c64/kernal/init \
|
||||
c64/kernal/interrupts \
|
||||
c64/kernal/iostack \
|
||||
c64/kernal/keyboard \
|
||||
c64/kernal/print \
|
||||
c64/kernal/screen \
|
||||
c64/kernal/stubs
|
||||
|
||||
SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc)
|
||||
|
||||
@@ -26,6 +35,7 @@ TOOL_COLLECT_DATA = build/tools/collect_data
|
||||
TOOL_COMPRESS_TEXT = build/tools/compress_text
|
||||
TOOL_PNGPREPARE = build/tools/pngprepare
|
||||
TOOL_BUILD_SEGMENT = build/tools/build_segment
|
||||
TOOL_RELEASE = build/tools/release
|
||||
TOOL_SIMILARITY = build/tools/similarity
|
||||
TOOL_ASSEMBLER = assembler/KickAss.jar
|
||||
|
||||
@@ -34,6 +44,7 @@ TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS)))
|
||||
# List of targets
|
||||
|
||||
STD_TARGET_LIST = build/kernal_generic.rom build/basic_generic.rom \
|
||||
build/kernal_testing.rom build/basic_testing.rom \
|
||||
build/kernal_mega65.rom build/basic_mega65.rom \
|
||||
build/kernal_ultimate64.rom build/basic_ultimate64.rom \
|
||||
build/chargen.rom
|
||||
@@ -59,30 +70,25 @@ all: $(STD_TARGET_LIST) $(EXT_TARGET_LIST)
|
||||
clean:
|
||||
@rm -rf build
|
||||
|
||||
updatebin: $(STD_TARGET_LIST)
|
||||
updatebin: $(STD_TARGET_LIST) $(TOOL_RELEASE)
|
||||
$(TOOL_RELEASE) -i ./build -o ./bin basic_generic.rom kernal_generic.rom basic_testing.rom kernal_testing.rom basic_mega65.rom kernal_mega65.rom basic_ultimate64.rom kernal_ultimate64.rom
|
||||
cp build/chargen.rom bin/chargen.rom
|
||||
cp build/basic_generic.rom bin/basic_generic.rom
|
||||
cp build/kernal_generic.rom bin/kernal_generic.rom
|
||||
cp build/basic_mega65.rom bin/basic_mega65.rom
|
||||
cp build/kernal_mega65.rom bin/kernal_mega65.rom
|
||||
cp build/basic_ultimate64.rom bin/basic_ultimate64.rom
|
||||
cp build/kernal_ultimate64.rom bin/kernal_ultimate64.rom
|
||||
|
||||
# Rules - tools
|
||||
|
||||
$(TOOL_PNGPREPARE): src/pngprepare.c Makefile
|
||||
$(TOOL_PNGPREPARE): src/pngprepare.c
|
||||
@mkdir -p build/tools
|
||||
$(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lpng
|
||||
|
||||
$(TOOL_COMPRESS_TEXT): src/compress_text.c Makefile
|
||||
$(TOOL_COMPRESS_TEXT): src/compress_text.c
|
||||
@mkdir -p build/tools
|
||||
$(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lm
|
||||
|
||||
build/tools/%: src/%.c Makefile
|
||||
build/tools/%: src/%.c
|
||||
@mkdir -p build/tools
|
||||
$(CC) -O2 -Wall -o $@ $<
|
||||
|
||||
build/tools/%: src/%.cc Makefile
|
||||
build/tools/%: src/%.cc src/common.h
|
||||
@mkdir -p build/tools
|
||||
$(CXX) -O2 -Wall -o $@ $<
|
||||
|
||||
@@ -94,44 +100,56 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png
|
||||
# Dependencies - BASIC and KERNAL
|
||||
|
||||
build/target_generic/OUTB.BIN build/target_generic/BASIC_combined.vs: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC_generic) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \
|
||||
c64/,,config_generic.s build/target_generic/KERNAL_combined.sym \
|
||||
$(foreach dir,$(SRCDIR_BASIC_generic),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s))
|
||||
build/target_testing/OUTB.BIN build/target_generic/BASIC_combined.vs: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \
|
||||
c64/,,config_testing.s build/target_testing/KERNAL_combined.sym \
|
||||
$(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s))
|
||||
build/target_mega65/OUTB.BIN build/target_mega65/BASIC_combined.vs: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC_mega65) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \
|
||||
c64/,,config_mega65.s build/target_mega65/KERNAL_combined.sym \
|
||||
$(foreach dir,$(SRCDIR_BASIC_mega65),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s))
|
||||
build/target_ultimate64/OUTB.BIN build/target_ultimate64/BASIC_combined.vs: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC_ultimate64) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \
|
||||
c64/,,config_ultimate64.s build/target_ultimate64/KERNAL_combined.sym \
|
||||
$(foreach dir,$(SRCDIR_BASIC_ultimate64),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s))
|
||||
|
||||
build/target_generic/OUTK.BIN build/target_generic/KERNAL_combined.vs build/target_generic/KERNAL_combined.sym: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL_generic) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \
|
||||
c64/,,config_generic.s \
|
||||
$(foreach dir,$(SRCDIR_KERNAL_generic),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s))
|
||||
build/target_testing/OUTK.BIN build/target_testing/KERNAL_combined.vs build/target_testing/KERNAL_combined.sym: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \
|
||||
c64/,,config_testing.s \
|
||||
$(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s))
|
||||
build/target_mega65/OUTK.BIN build/target_mega65/KERNAL_combined.vs build/target_mega65/KERNAL_combined.sym: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL_mega65) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \
|
||||
c64/,,config_mega65.s \
|
||||
$(foreach dir,$(SRCDIR_KERNAL_mega65),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s))
|
||||
build/target_ultimate64/OUTK.BIN build/target_ultimate64/KERNAL_combined.vs build/target_ultimate64/KERNAL_combined.sym: \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL_ultimate64) \
|
||||
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \
|
||||
c64/,,config_ultimate64.s \
|
||||
$(foreach dir,$(SRCDIR_KERNAL_ultimate64),$(wildcard $(dir)/*.s))
|
||||
$(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s))
|
||||
|
||||
build/target_generic/newrom: build/target_generic/OUTB.BIN build/target_generic/OUTK.BIN
|
||||
build/target_testing/newrom: build/target_testing/OUTB.BIN build/target_testing/OUTK.BIN
|
||||
build/target_mega65/newrom: build/target_mega65/OUTB.BIN build/target_mega65/OUTK.BIN
|
||||
build/target_ultimate64/newrom: build/target_ultimate64/OUTB.BIN build/target_ultimate64/OUTK.BIN
|
||||
|
||||
build/kernal_generic.rom: build/target_generic/newrom
|
||||
build/kernal_testing.rom: build/target_testing/newrom
|
||||
build/kernal_mega65.rom: build/target_mega65/newrom
|
||||
build/kernal_ultimate64.rom: build/target_ultimate64/newrom
|
||||
|
||||
build/basic_generic.rom: build/target_generic/newrom
|
||||
build/basic_testing.rom: build/target_testing/newrom
|
||||
build/basic_mega65.rom: build/target_mega65/newrom
|
||||
build/basic_ultimate64.rom: build/target_ultimate64/newrom
|
||||
|
||||
build/symbols_generic.vs: build/target_generic/BASIC_combined.vs build/target_generic/KERNAL_combined.vs
|
||||
build/symbols_testing.vs: build/target_testing/BASIC_combined.vs build/target_testing/KERNAL_combined.vs
|
||||
build/symbols_mega65.vs: build/target_mega65/BASIC_combined.vs build/target_mega65/KERNAL_combined.vs
|
||||
build/symbols_ultimate64.vs: build/target_ultimate64/BASIC_combined.vs build/target_ultimate64/KERNAL_combined.vs
|
||||
|
||||
@@ -145,13 +163,13 @@ build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT)
|
||||
build/target_%/OUTB.BIN build/target_%/BASIC_combined.vs:
|
||||
@mkdir -p build/target_$*
|
||||
@rm -f $@* build/target_$*/BASIC*
|
||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -s BASIC -i BASIC-$* -o OUTB.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC_$*) $(GEN_BASIC)
|
||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -s BASIC -i BASIC-$* -o OUTB.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC) $(GEN_BASIC)
|
||||
|
||||
.PRECIOUS: build/target_%/OUTK.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym
|
||||
build/target_%/OUTK.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym:
|
||||
@mkdir -p build/target_$*
|
||||
@rm -f $@* build/target_$*/KERNAL*
|
||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -s KERNAL -i KERNAL-$* -o OUTK.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL_$*) $(GEN_KERNAL)
|
||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -s KERNAL -i KERNAL-$* -o OUTK.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
||||
|
||||
.PRECIOUS: build/target_%/newrom
|
||||
build/target_%/newrom:
|
||||
@@ -183,7 +201,7 @@ build/symbols_hybrid.vs: build/target_generic/KERNAL_combined.vs
|
||||
|
||||
# Rules - platform 'Mega 65' specific
|
||||
|
||||
build/newc65.rom: build/kernal_mega65.rom build/basic_mega65.rom build/chargen.rom Makefile
|
||||
build/newc65.rom: build/kernal_mega65.rom build/basic_mega65.rom build/chargen.rom
|
||||
dd if=/dev/zero bs=4096 count=10 of=build/newc65.rom
|
||||
cat build/basic_mega65.rom build/chargen.rom build/chargen.rom build/kernal_mega65.rom >> build/newc65.rom
|
||||
dd if=/dev/zero bs=65536 count=1 of=build/padding
|
||||
@@ -192,16 +210,28 @@ build/newc65.rom: build/kernal_mega65.rom build/basic_mega65.rom build/chargen.r
|
||||
|
||||
# Rules - tests
|
||||
|
||||
.PHONY: test test_generic test_mega65 test_ultimate64 test_m65 testremote testsimilarity
|
||||
.PHONY: test test_generic test_generic_x128 test_hybrid test_testing \
|
||||
test_mega65 test_mega65_xemu test_m65 \
|
||||
test_ultimate64 \
|
||||
testremote testsimilarity
|
||||
|
||||
test: test_generic
|
||||
|
||||
test_generic: build/kernal_generic.rom build/basic_generic.rom build/symbols_generic.vs
|
||||
x64 -kernal build/kernal_generic.rom -basic build/basic_generic.rom -moncommands build/symbols_generic.vs -8 empty.d64
|
||||
|
||||
test_generic_x128: build/kernal_generic.rom build/basic_generic.rom build/symbols_generic.vs
|
||||
x128 -go64 -kernal64 build/kernal_generic.rom -basic64 build/basic_generic.rom -moncommands build/symbols_generic.vs -8 empty.d64
|
||||
|
||||
test_testing: build/kernal_testing.rom build/basic_testing.rom build/symbols_testing.vs
|
||||
x64 -kernal build/kernal_testing.rom -basic build/basic_testing.rom -moncommands build/symbols_testing.vs -8 empty.d64
|
||||
|
||||
test_mega65: build/kernal_mega65.rom build/basic_mega65.rom build/symbols_mega65.vs
|
||||
x64 -kernal build/kernal_mega65.rom -basic build/basic_mega65.rom -moncommands build/symbols_mega65.vs -8 empty.d64
|
||||
|
||||
test_mega65_xemu: build/newc65.rom
|
||||
../xemu/build/bin/xc65.native -dmarev 2 -rom build/newc65.rom
|
||||
|
||||
test_ultimate64: build/kernal_ultimate64.rom build/basic_ultimate64.rom build/symbols_ultimate64.vs
|
||||
x64 -kernal build/kernal_ultimate64.rom -basic build/basic_ultimate64.rom -moncommands build/symbols_ultimate64.vs -8 empty.d64
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
Here are the features of the Open ROMs not found in the original ROMs from the 80s (many of them are [configurable](CONFIG.md)):
|
||||
|
||||
* improved keyboard scanning, supports multi-key roll-over and rejection of spurious joystick input
|
||||
* joystick (port 1) can be used to move text cursor
|
||||
* improved keyboard scanning, supports anti-ghosting and is resistant to joystick interference (one variant even supports multi-keyy rollover)
|
||||
* joystick can be used to move text cursor
|
||||
* uses RAM under ROM and I/O: 61438 bytes free
|
||||
* cold/warm start silences multiple SID chips - all $D4xx and $D5xx addresses
|
||||
* wark start due to BRK prints out the instruction address
|
||||
@@ -29,7 +29,7 @@ The following ROM features are currently missing:
|
||||
* tape support
|
||||
* RS-232 support
|
||||
* breaking Kernal routines with RUN/STOP key
|
||||
* NMI andling is incomplete
|
||||
* NMI handling is incomplete
|
||||
|
||||
|
||||
# API status
|
||||
@@ -62,8 +62,8 @@ Note: vectors at `$0300` are not supported yet - for now only the locations belo
|
||||
| `(00306)` | `$A71A` | `QPLOP` | NOT DONE | some implementation exists, but not connected here |
|
||||
| `(00308)` | `$A7E4` | `GONE` | NOT DONE | some implementation exists, but not connected here |
|
||||
| `(0030A)` | `$AE86` | `EVAL` | NOT DONE | some implementation exists, but not connected here |
|
||||
| `($A000)` | | cold start | PARTIAL | |
|
||||
| `($A002)` | | warm start | PARTIAL | |
|
||||
| `($A000)` | `$E394` | cold start | PARTIAL | |
|
||||
| `($A002)` | `$E3B7` | warm start | PARTIAL | |
|
||||
|
||||
<br />
|
||||
|
||||
@@ -76,10 +76,15 @@ Not all of them - only these we want to have implemented.
|
||||
| Address | Name | Status | Remarks |
|
||||
| :-------: | :----------- | :------: | :------------------------------------------------: |
|
||||
| `$A004` | revision str | DONE | |
|
||||
| `$A68E` | RUNC | NOT DONE | |
|
||||
| `$A7AE` | NEWSTT | NOT DONE | |
|
||||
| `$A408` | REASON | NOT DONE | |
|
||||
| `$A453` | (unknown) | NOT DONE | |
|
||||
| `$A533` | LINKPRG | DONE | |
|
||||
| `$A644` | new | NOT DONE | |
|
||||
| `$A659` | set txt ptr | NOT DONE | |
|
||||
| `$A68E` | RUNC | DONE | |
|
||||
| `$A7AE` | NEWSTT | PARTIAL | redirected to RUN command |
|
||||
| `$AB1E` | STROUT | DONE | |
|
||||
| `$BDCD` | LINPRT | NOT DONE | |
|
||||
| `$BDCD` | LINPRT | DONE | temporary implementation |
|
||||
| `$E3BF` | INIT | NOT DONE | |
|
||||
| `$E422` | INITMSG | DONE | |
|
||||
| `$E453` | RVECT | NOT DONE | |
|
||||
@@ -94,53 +99,53 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on
|
||||
|
||||
<br />
|
||||
|
||||
| Address | Unofficial | Name | Status | Remarks |
|
||||
| :-------: | :--------: | :---------- | :------: | :------------------------------------------------: |
|
||||
| `($028F)` | | `KEYLOG` | NOT DONE | |
|
||||
| `$FF81` | `$FF5B` | `CINT` | DONE | |
|
||||
| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete |
|
||||
| `$FF87` | `$FD50` | `RAMTAS` | DONE | |
|
||||
| `$FF8A` | `$FD15` | `RESTOR` | DONE | |
|
||||
| `$FF8D` | `$FD1A` | `VECTOR` | DONE | |
|
||||
| `$FF90` | | `SETMSG` | DONE | |
|
||||
| `$FF93` | | `SECOND` | DONE | |
|
||||
| `$FF96` | | `TKSA` | DONE | |
|
||||
| `$FF99` | | `MEMTOP` | DONE | |
|
||||
| `$FF9C` | | `MEMBOT` | DONE | |
|
||||
| `$FF9F` | | `SCNKEY` | DONE | could be better integrated with ROM (aliases) |
|
||||
| `$FFA2` | | `SETTMO` | DONE | |
|
||||
| `$FFA5` | | `ACPTR` | DONE | |
|
||||
| `$FFA8` | | `CIOUT` | DONE | |
|
||||
| `$FFAB` | | `UNTLK` | DONE | |
|
||||
| `$FFAE` | | `UNLSN` | DONE | |
|
||||
| `$FFB1` | | `LISTEN` | DONE | |
|
||||
| `$FFB4` | | `TALK` | DONE | |
|
||||
| `$FFB7` | | `READST` | DONE | |
|
||||
| `$FFBA` | | `SETFLS` | DONE | |
|
||||
| `$FFBD` | | `SETNAM` | DONE | |
|
||||
| `$FFC0` | `$F34A` | `OPEN` | DONE | |
|
||||
| `$FFC3` | `$F291` | `CLOSE` | DONE | |
|
||||
| `$FFC6` | `$F20E` | `CHKIN` | DONE | |
|
||||
| `$FFC9` | `$F250` | `CKOUT` | PARTIAL | |
|
||||
| `$FFCC` | `$F333` | `CLRCHN` | DONE | |
|
||||
| `$FFCF` | `$F157` | `CHRIN` | PARTIAL | |
|
||||
| `$FFD2` | `$F1CA` | `CHROUT` | PARTIAL | |
|
||||
| `$FFD5` | `$F49E` | `LOAD` | PARTIAL | not yet clear what's this entry doing |
|
||||
| `($0330)` | `$F4A5` | `LOAD` | PARTIAL | no VERIFY support, no STOP key, check $F49E addr |
|
||||
| `$FFD8` | `$F5DD` | `SAVE` | NOT DONE | |
|
||||
| `($0332)` | `$F5ED` | `SAVE` | NOT DONE | |
|
||||
| `$FFDB` | | `SETTIM` | DONE | |
|
||||
| `$FFDE` | | `RDTIM` | DONE | |
|
||||
| `$FFE1` | `$F6ED` | `STOP` | DONE | |
|
||||
| `$FFE4` | `$F13E` | `GETIN` | PARTIAL | only some devices supported |
|
||||
| `$FFE7` | `$F32F` | `CLALL` | DONE | |
|
||||
| `$FFEA` | | `UDTIM` | DONE | |
|
||||
| `$FFED` | | `SCREEN` | DONE | |
|
||||
| `$FFF0` | `$E50A` | `PLOT` | PARTIAL | |
|
||||
| `$FFF3` | | `IOBASE` | DONE | |
|
||||
| `($FFFA)` | | NMI vec | PARTIAL | |
|
||||
| `($FFFC)` | | RESET vec | PARTIAL | |
|
||||
| `($FFFE)` | | IRQ/BRK vec | PARTIAL | |
|
||||
| Address | Unofficial | Name | Status | Remarks |
|
||||
| :-------: | :--------: | :---------- | :------: | :--------------------------------------------------: |
|
||||
| `($028F)` | | `KEYLOG` | DONE | |
|
||||
| `$FF81` | `$FF5B` | `CINT` | DONE | |
|
||||
| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization might be incomplete |
|
||||
| `$FF87` | `$FD50` | `RAMTAS` | PARTIAL | probably shouldn't touch VIC and CIA's |
|
||||
| `$FF8A` | `$FD15` | `RESTOR` | DONE | |
|
||||
| `$FF8D` | `$FD1A` | `VECTOR` | DONE | |
|
||||
| `$FF90` | | `SETMSG` | DONE | |
|
||||
| `$FF93` | | `SECOND` | DONE | |
|
||||
| `$FF96` | | `TKSA` | DONE | |
|
||||
| `$FF99` | `$FE25` | `MEMTOP` | DONE | |
|
||||
| `$FF9C` | | `MEMBOT` | DONE | |
|
||||
| `$FF9F` | | `SCNKEY` | DONE | |
|
||||
| `$FFA2` | | `SETTMO` | DONE | |
|
||||
| `$FFA5` | | `ACPTR` | DONE | |
|
||||
| `$FFA8` | | `CIOUT` | DONE | |
|
||||
| `$FFAB` | | `UNTLK` | DONE | |
|
||||
| `$FFAE` | | `UNLSN` | DONE | |
|
||||
| `$FFB1` | | `LISTEN` | DONE | |
|
||||
| `$FFB4` | | `TALK` | DONE | |
|
||||
| `$FFB7` | | `READST` | DONE | |
|
||||
| `$FFBA` | | `SETFLS` | DONE | |
|
||||
| `$FFBD` | | `SETNAM` | DONE | |
|
||||
| `$FFC0` | `$F34A` | `OPEN` | DONE | |
|
||||
| `$FFC3` | `$F291` | `CLOSE` | DONE | |
|
||||
| `$FFC6` | `$F20E` | `CHKIN` | DONE | |
|
||||
| `$FFC9` | `$F250` | `CKOUT` | PARTIAL | |
|
||||
| `$FFCC` | `$F333` | `CLRCHN` | DONE | |
|
||||
| `$FFCF` | `$F157` | `CHRIN` | PARTIAL | |
|
||||
| `$FFD2` | `$F1CA` | `CHROUT` | PARTIAL | |
|
||||
| `$FFD5` | `$F49E` | `LOAD` | PARTIAL | not yet clear what's this entry doing |
|
||||
| `($0330)` | `$F4A5` | `LOAD` | PARTIAL | no VERIFY support, no STOP key, check $F49E addr |
|
||||
| `$FFD8` | `$F5DD` | `SAVE` | NOT DONE | |
|
||||
| `($0332)` | `$F5ED` | `SAVE` | NOT DONE | |
|
||||
| `$FFDB` | | `SETTIM` | DONE | |
|
||||
| `$FFDE` | | `RDTIM` | DONE | |
|
||||
| `$FFE1` | `$F6ED` | `STOP` | DONE | |
|
||||
| `$FFE4` | `$F13E` | `GETIN` | PARTIAL | only keyboard supported |
|
||||
| `$FFE7` | `$F32F` | `CLALL` | DONE | |
|
||||
| `$FFEA` | | `UDTIM` | DONE | |
|
||||
| `$FFED` | | `SCREEN` | DONE | |
|
||||
| `$FFF0` | `$E50A` | `PLOT` | DONE | |
|
||||
| `$FFF3` | | `IOBASE` | DONE | |
|
||||
| `($FFFA)` | | NMI vec | PARTIAL | |
|
||||
| `($FFFC)` | `$FCE2` | RESET vec | PARTIAL | |
|
||||
| `($FFFE)` | | IRQ/BRK vec | PARTIAL | |
|
||||
|
||||
<br />
|
||||
|
||||
@@ -150,17 +155,31 @@ Not all of them - only these we want to have implemented.
|
||||
|
||||
<br />
|
||||
|
||||
| Address | Name | Status | Remarks |
|
||||
| :-------: | :------------------ | :------: | :------------------------------------------------: |
|
||||
| `$E544` | clear screen | DONE | |
|
||||
| `$E50C` | set cursor position | PARTIAL | |
|
||||
| `$E5A0` | setup VIC II & IO | PARTIAL | |
|
||||
| `$EA31` | default IRQ | PARTIAL | |
|
||||
| `$EA7E` | ack CIA1 + below | DONE | |
|
||||
| `$EA81` | ret from IRQ/NMI | DONE | |
|
||||
| `$FD30` | default vectors | DONE | |
|
||||
| `$FE47` | default NMI | PARTIAL | |
|
||||
| `$FE66` | default BRK | DONE | |
|
||||
| `$FF80` | revision byte | DONE | |
|
||||
| Address | Name | Status | Remarks |
|
||||
| :-------: | :--------------------------- | :------: | :------------------------------------------------: |
|
||||
| `$E518` | legacy part of CINT | DONE | |
|
||||
| `$E51B` | init screen keyboard, no VIC | DONE | |
|
||||
| `$E544` | clear screen | DONE | |
|
||||
| `$E50C` | set cursor position | PARTIAL | |
|
||||
| `$E566` | home cursor | NOT DONE | |
|
||||
| `$E5A0` | setup VIC II & IO | DONE | |
|
||||
| `$E6B6` | advance cursor | NOT DONE | |
|
||||
| `$E701` | previous line | NOT DONE | |
|
||||
| `$E716` | screen CHROUT | NOT DONE | |
|
||||
| `$E8EA` | scroll line | NOT DONE | |
|
||||
| `$E96C` | insert line on top | NOT DONE | |
|
||||
| `$E9FF` | clear line | NOT DONE | |
|
||||
| `$EA31` | default IRQ | PARTIAL | |
|
||||
| `$EA7E` | ack CIA1 + below | DONE | |
|
||||
| `$EA81` | ret from IRQ/NMI | DONE | |
|
||||
| `$F142` | get key from buffer | DONE | |
|
||||
| `$F646` | IEC close | NOT DONE | |
|
||||
| `$FD30` | default vectors | DONE | |
|
||||
| `$FD90` | (unknown) | NOT DONE | |
|
||||
| `$FD90` | (unknown) | NOT DONE | |
|
||||
| `$FE2D` | memtop set part | DONE | |
|
||||
| `$FE47` | default NMI | PARTIAL | |
|
||||
| `$FE66` | default BRK | DONE | |
|
||||
| `$FF80` | revision byte | DONE | |
|
||||
|
||||
<br />
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+56
-1
@@ -1,16 +1,44 @@
|
||||
|
||||
.const CONFIG_ID = $00 // should be 1 byte, different for each config file!
|
||||
|
||||
//
|
||||
// Please read CONFIG.md before modifying this file!
|
||||
//
|
||||
|
||||
// Idea:
|
||||
// - sane defaults for the original Commodore 64/128 machines
|
||||
// - do not enable features which are a significant compatibility risk
|
||||
|
||||
|
||||
// Hardware platform and brand
|
||||
|
||||
#define CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// #define CONFIG_MB_MEGA_65
|
||||
// #define CONFIG_MB_ULTIMATE_64
|
||||
|
||||
#define CONFIG_BRAND_GENERIC
|
||||
// #define CONFIG_BRAND_TESTING
|
||||
// #define CONFIG_BRAND_MEGA_65
|
||||
// #define CONFIG_BRAND_ULTIMATE_64
|
||||
|
||||
|
||||
// Processor instruction set
|
||||
|
||||
#define CONFIG_CPU_MOS_6502
|
||||
// #define CONFIG_CPU_WDC_65C02
|
||||
// #define CONFIG_CPU_CSG_65CE02
|
||||
// #define CONFIG_CPU_WDC_65816
|
||||
|
||||
|
||||
// Memory model
|
||||
|
||||
#define CONFIG_MEMORY_MODEL_38K
|
||||
// #define CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
// Multiple SID support
|
||||
|
||||
// #define CONFIG_SID_2ND
|
||||
.const CONFIG_SID_2ND_ADDRESS = $D420
|
||||
|
||||
@@ -20,9 +48,36 @@
|
||||
// #define CONFIG_SID_D4XX
|
||||
// #define CONFIG_SID_D5XX
|
||||
|
||||
|
||||
// Keyboard settings
|
||||
|
||||
// #define CONFIG_LEGACY_SCNKEY
|
||||
#define CONFIG_KEYBOARD_C128 // incomplete
|
||||
#define CONFIG_KEYBOARD_C128_CAPS_LOCK
|
||||
// #define CONFIG_KEY_REPEAT_DEFAULT
|
||||
// #define CONFIG_KEY_REPEAT_ALWAYS
|
||||
#define CONFIG_KEY_FAST_SCAN
|
||||
#define CONFIG_JOY1_CURSOR
|
||||
#define CONFIG_JOY2_CURSOR
|
||||
|
||||
|
||||
// Eye candy
|
||||
|
||||
#define CONFIG_COLORS_BRAND
|
||||
// #define CONFIG_BANNER_SIMPLE
|
||||
#define CONFIG_BANNER_FANCY
|
||||
// #define CONFIG_BANNER_BRAND
|
||||
#define CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
|
||||
// Software features
|
||||
|
||||
#define CONFIG_PANIC_SCREEN
|
||||
#define CONFIG_DOS_WEDGE
|
||||
#define CONFIG_BCD_SAFE_INTERRUPTS
|
||||
#define CONFIG_EXTENDED_SCNKEY // for now has to be enabled
|
||||
|
||||
|
||||
// Debug options
|
||||
|
||||
// #define CONFIG_DBG_STUBS_BRK
|
||||
// #define CONFIG_DBG_PRINTF
|
||||
+60
-3
@@ -1,15 +1,45 @@
|
||||
|
||||
.const CONFIG_ID = $01 // should be 1 byte, different for each config file!
|
||||
|
||||
//
|
||||
// Please read CONFIG.md before modifying this file!
|
||||
//
|
||||
|
||||
// Idea:
|
||||
// - sane defaults for the Mega 65 FPGA computer
|
||||
// - do not enable features which are a significant compatibility risk
|
||||
// - unless VICE gains Commodore 65 (or at least Flash8 cartridge) emulation support,
|
||||
// do not enable CPU-specific optimizations; ROMs would be hard to test
|
||||
|
||||
|
||||
// Hardware platform and brand
|
||||
|
||||
#define CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
#define CONFIG_MB_MEGA_65
|
||||
// #define CONFIG_MB_ULTIMATE_64
|
||||
|
||||
// #define CONFIG_BRAND_GENERIC
|
||||
// #define CONFIG_BRAND_TESTING
|
||||
#define CONFIG_BRAND_MEGA_65
|
||||
// #define CONFIG_BRAND_ULTIMATE_64
|
||||
|
||||
|
||||
// Processor instruction set
|
||||
|
||||
#define CONFIG_CPU_MOS_6502
|
||||
// #define CONFIG_CPU_WDC_65C02
|
||||
// #define CONFIG_CPU_CSG_65CE02
|
||||
// #define CONFIG_CPU_WDC_65816
|
||||
|
||||
// #define CONFIG_MEMORY_MODEL_38K
|
||||
#define CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
// Memory model configuration
|
||||
|
||||
#define CONFIG_MEMORY_MODEL_38K
|
||||
// #define CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
// Multiple SID support
|
||||
|
||||
#define CONFIG_SID_2ND
|
||||
.const CONFIG_SID_2ND_ADDRESS = $D420
|
||||
@@ -20,9 +50,36 @@
|
||||
// #define CONFIG_SID_D4XX
|
||||
// #define CONFIG_SID_D5XX
|
||||
|
||||
|
||||
// Keyboard settings
|
||||
|
||||
// #define CONFIG_LEGACY_SCNKEY
|
||||
// #define CONFIG_KEYBOARD_C128 // incomplete
|
||||
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
|
||||
// #define CONFIG_KEY_REPEAT_DEFAULT
|
||||
// #define CONFIG_KEY_REPEAT_ALWAYS
|
||||
#define CONFIG_KEY_FAST_SCAN
|
||||
#define CONFIG_JOY1_CURSOR
|
||||
#define CONFIG_JOY2_CURSOR
|
||||
|
||||
|
||||
// Eye candy
|
||||
|
||||
#define CONFIG_COLORS_BRAND
|
||||
// #define CONFIG_BANNER_SIMPLE
|
||||
// #define CONFIG_BANNER_FANCY
|
||||
#define CONFIG_BANNER_BRAND
|
||||
// #define CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
|
||||
// Software features
|
||||
|
||||
#define CONFIG_PANIC_SCREEN
|
||||
#define CONFIG_DOS_WEDGE
|
||||
#define CONFIG_BCD_SAFE_INTERRUPTS
|
||||
#define CONFIG_EXTENDED_SCNKEY // for now has to be enabled
|
||||
|
||||
|
||||
// Debug options
|
||||
|
||||
// #define CONFIG_DBG_STUBS_BRK
|
||||
// #define CONFIG_DBG_PRINTF
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
.const CONFIG_ID = $F0 // should be 1 byte, different for each config file!
|
||||
|
||||
//
|
||||
// Please read CONFIG.md before modifying this file!
|
||||
//
|
||||
|
||||
// Idea:
|
||||
// - enable compatibility-risky features
|
||||
// - enable code not normally used - to make sure they still compile
|
||||
|
||||
|
||||
|
||||
// Hardware platform and brand
|
||||
|
||||
#define CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// #define CONFIG_MB_MEGA_65
|
||||
// #define CONFIG_MB_ULTIMATE_64
|
||||
|
||||
// #define CONFIG_BRAND_GENERIC
|
||||
#define CONFIG_BRAND_TESTING
|
||||
// #define CONFIG_BRAND_MEGA_65
|
||||
// #define CONFIG_BRAND_ULTIMATE_64
|
||||
|
||||
|
||||
// Processor instruction set
|
||||
|
||||
#define CONFIG_CPU_MOS_6502
|
||||
// #define CONFIG_CPU_WDC_65C02
|
||||
// #define CONFIG_CPU_CSG_65CE02
|
||||
// #define CONFIG_CPU_WDC_65816
|
||||
|
||||
|
||||
// Memory model configuration
|
||||
|
||||
// #define CONFIG_MEMORY_MODEL_38K
|
||||
#define CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
// Multiple SID support
|
||||
|
||||
#define CONFIG_SID_2ND
|
||||
.const CONFIG_SID_2ND_ADDRESS = $D420
|
||||
|
||||
// #define CONFIG_SID_3RD
|
||||
.const CONFIG_SID_3RD_ADDRESS = $D440
|
||||
|
||||
// #define CONFIG_SID_D4XX
|
||||
// #define CONFIG_SID_D5XX
|
||||
|
||||
|
||||
// Keyboard settings
|
||||
|
||||
#define CONFIG_LEGACY_SCNKEY
|
||||
// #define CONFIG_KEYBOARD_C128 // incomplete
|
||||
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
|
||||
// #define CONFIG_KEY_REPEAT_DEFAULT
|
||||
// #define CONFIG_KEY_REPEAT_ALWAYS
|
||||
#define CONFIG_KEY_FAST_SCAN
|
||||
#define CONFIG_JOY1_CURSOR
|
||||
#define CONFIG_JOY2_CURSOR
|
||||
|
||||
|
||||
// Eye candy
|
||||
|
||||
// #define CONFIG_COLORS_BRAND
|
||||
// #define CONFIG_BANNER_SIMPLE
|
||||
#define CONFIG_BANNER_FANCY
|
||||
// #define CONFIG_BANNER_BRAND
|
||||
// #define CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
|
||||
// Software features
|
||||
|
||||
#define CONFIG_PANIC_SCREEN
|
||||
#define CONFIG_DOS_WEDGE
|
||||
#define CONFIG_BCD_SAFE_INTERRUPTS
|
||||
|
||||
|
||||
// Debug options
|
||||
|
||||
// #define CONFIG_DBG_STUBS_BRK
|
||||
#define CONFIG_DBG_PRINTF
|
||||
@@ -1,16 +1,44 @@
|
||||
|
||||
.const CONFIG_ID = $02 // should be 1 byte, different for each config file!
|
||||
|
||||
//
|
||||
// Please read CONFIG.md before modifying this file!
|
||||
//
|
||||
|
||||
// Idea:
|
||||
// - sane defaults for the Ultimate 64 FPGA computer
|
||||
// - do not enable features which are a significant compatibility risk
|
||||
|
||||
|
||||
// Hardware platform and brand
|
||||
|
||||
#define CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// #define CONFIG_MB_MEGA_65
|
||||
#define CONFIG_MB_ULTIMATE_64
|
||||
|
||||
// #define CONFIG_BRAND_GENERIC
|
||||
// #define CONFIG_BRAND_TESTING
|
||||
// #define CONFIG_BRAND_MEGA_65
|
||||
#define CONFIG_BRAND_ULTIMATE_64
|
||||
|
||||
|
||||
// Processor instruction set
|
||||
|
||||
#define CONFIG_CPU_MOS_6502
|
||||
// #define CONFIG_CPU_WDC_65C02
|
||||
// #define CONFIG_CPU_CSG_65CE02
|
||||
// #define CONFIG_CPU_WDC_65816
|
||||
|
||||
|
||||
// Memory model configuration
|
||||
|
||||
#define CONFIG_MEMORY_MODEL_38K
|
||||
// #define CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
// Multiple SID support
|
||||
|
||||
// #define CONFIG_SID_2ND
|
||||
.const CONFIG_SID_2ND_ADDRESS = $D420
|
||||
|
||||
@@ -20,9 +48,36 @@
|
||||
#define CONFIG_SID_D4XX
|
||||
#define CONFIG_SID_D5XX
|
||||
|
||||
|
||||
// Keyboard settings
|
||||
|
||||
// #define CONFIG_LEGACY_SCNKEY
|
||||
// #define CONFIG_KEYBOARD_C128 // incomplete
|
||||
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
|
||||
// #define CONFIG_KEY_REPEAT_DEFAULT
|
||||
// #define CONFIG_KEY_REPEAT_ALWAYS
|
||||
#define CONFIG_KEY_FAST_SCAN
|
||||
#define CONFIG_JOY1_CURSOR
|
||||
#define CONFIG_JOY2_CURSOR
|
||||
|
||||
|
||||
// Eye candy
|
||||
|
||||
#define CONFIG_COLORS_BRAND
|
||||
// #define CONFIG_BANNER_SIMPLE
|
||||
#define CONFIG_BANNER_FANCY
|
||||
// #define CONFIG_BANNER_BRAND
|
||||
#define CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
|
||||
// Software features
|
||||
|
||||
#define CONFIG_PANIC_SCREEN
|
||||
#define CONFIG_DOS_WEDGE
|
||||
#define CONFIG_BCD_SAFE_INTERRUPTS
|
||||
#define CONFIG_EXTENDED_SCNKEY // for now has to be enabled
|
||||
|
||||
|
||||
// Debug options
|
||||
|
||||
// #define CONFIG_DBG_STUBS_BRK
|
||||
// #define CONFIG_DBG_PRINTF
|
||||
+131
-12
@@ -1,9 +1,102 @@
|
||||
|
||||
// Various configuration dependent aliases/macros/checks
|
||||
//
|
||||
// Various configuration dependent aliases/macros/checks
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Check that memory model configuration is correct
|
||||
// Check that platform configuration is correct
|
||||
|
||||
{
|
||||
.var selected = 0;
|
||||
|
||||
#if CONFIG_PLATFORM_COMMODORE_64
|
||||
.eval selected++
|
||||
#endif
|
||||
|
||||
.if (selected != 1) .error "Please select exactly one CONFIG_PLATFORM_* option"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that motherboard extras configuration is correct
|
||||
|
||||
{
|
||||
.var selected = 0;
|
||||
|
||||
#if CONFIG_MB_MEGA_65
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_MB_ULTIMATE_64
|
||||
.eval selected++
|
||||
#endif
|
||||
|
||||
.if (selected > 1) .error "Please select at most one CONFIG_MB_* option"
|
||||
|
||||
#if !CONFIG_PLATFORM_COMMODORE_64 && CONFIG_BRAND_MEGA_65 &&
|
||||
.error "CONFIG_BRAND_MEGA_65 can only be used with CONFIG_PLATFORM_COMMODORE_64"
|
||||
#endif
|
||||
#if !CONFIG_PLATFORM_COMMODORE_64 && CONFIG_BRAND_ULTIMATE_64 &&
|
||||
.error "CONFIG_BRAND_ULTIMATE_64 can only be used with CONFIG_PLATFORM_COMMODORE_64"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that brand configuration is correct
|
||||
|
||||
{
|
||||
.var selected = 0;
|
||||
|
||||
#if CONFIG_BRAND_GENERIC
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_BRAND_TESTING
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_BRAND_MEGA_65
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_BRAND_ULTIMATE_64
|
||||
.eval selected++
|
||||
#endif
|
||||
|
||||
.if (selected != 1) .error "Please select exactly one CONFIG_BRAND_* option"
|
||||
|
||||
#if CONFIG_MB_MEGA_65 && !(CONFIG_BRAND_MEGA_65 || CONFIG_BRAND_TESTING)
|
||||
.error "Please select brand either matching the CONFIG_MB_*, or a testing one"
|
||||
#endif
|
||||
#if CONFIG_MB_ULTIMATE_64 && !(CONFIG_BRAND_ULTIMATE_64 || CONFIG_BRAND_TESTING)
|
||||
.error "Please select brand either matching the CONFIG_MB_*, or a testing one"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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_CSG_65CE02
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_CPU_WDC_65816
|
||||
.eval selected++
|
||||
#endif
|
||||
|
||||
.if (selected != 1) .error "Please select exactly one CONFIG_CPU_* option"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that memory model configuration is correct
|
||||
|
||||
{
|
||||
.var selected = 0;
|
||||
@@ -20,32 +113,54 @@
|
||||
|
||||
|
||||
|
||||
// Check that processor configuration is correct
|
||||
// Check that startup banner configuration is correct
|
||||
|
||||
{
|
||||
.var selected = 0;
|
||||
|
||||
#if CONFIG_CPU_MOS_6502
|
||||
#if CONFIG_BANNER_SIMPLE
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_CPU_WDC_65C02
|
||||
#if CONFIG_BANNER_FANCY
|
||||
.eval selected++
|
||||
#endif
|
||||
#if CONFIG_CPU_WDC_65816
|
||||
#if CONFIG_BANNER_BRAND
|
||||
.eval selected++
|
||||
#endif
|
||||
|
||||
.if (selected != 1) .error "Please select exactly one CONFIG_CPU_* option"
|
||||
.if (selected != 1) .error "Please select exactly one CONFIG_BANNER_* option"
|
||||
|
||||
#if CONFIG_BANNER_BRAND && !CONFIG_BRAND_MEGA_65
|
||||
.error "CONFIG_BANNER_BRAND is not supported for your CONFIG_BRAND_*"
|
||||
#endif
|
||||
|
||||
#if CONFIG_BANNER_BRAND && CONFIG_BRAND_MEGA_65 && CONFIG_SHOW_PAL_NTSC
|
||||
.error "MEGA65 brand banner does not support showing PAL/NTSC"
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle processor configuration
|
||||
// Check if keyboard options are correct
|
||||
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_WDC_65816
|
||||
{
|
||||
#if CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C128_CAPS_LOCK)
|
||||
.error "CONFIG_LEGACY_SCNKEY and CONFIG_KEYBOARD_C128* are mutually exclusive"
|
||||
#endif
|
||||
|
||||
#if (CONFIG_MB_MEGA_65 || CONFIG_MB_ULTIMATE_64) && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C128_CAPS_LOCK)
|
||||
.error "Selected CONFIG_MB_* is not compatible with CONFIG_KEYBOARD_C128*"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle processor configuration
|
||||
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
||||
|
||||
#define HAS_BCD_SAFE_INTERRUPTS
|
||||
#define HAS_BCD_SAFE_RESET
|
||||
|
||||
.pseudocommand phx { .byte $DA }
|
||||
.pseudocommand phy { .byte $5A }
|
||||
@@ -54,13 +169,17 @@
|
||||
|
||||
#endif
|
||||
|
||||
// Handle misc configuration entrues
|
||||
|
||||
|
||||
// Handle configuration of various features
|
||||
|
||||
#if CONFIG_BCD_SAFE_INTERRUPTS
|
||||
#define HAS_BCD_SAFE_INTERRUPTS
|
||||
#endif
|
||||
|
||||
// Stub configuration
|
||||
|
||||
|
||||
// Handle configuration of debug infrastructure
|
||||
|
||||
.macro STUB_IMPLEMENTATION_RTS() {
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// Provide pseudocommands to make CPU optimizations easier
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// These are not exactly for optimization - but to encourage proper usage of panic screen
|
||||
//
|
||||
|
||||
.pseudocommand panic code
|
||||
{
|
||||
// If case no panic screen is used, we can skip providing error codes within Kernal
|
||||
#if CONFIG_PANIC_SCREEN || !SEGMENT_KERNAL
|
||||
lda code
|
||||
#endif
|
||||
jmp ($E4B7)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Stack manipulation - some CPUs will leave .A unchanged, some will use it as temporary storage, so consider .A trashed
|
||||
//
|
||||
|
||||
|
||||
.pseudocommand phx_trash_a
|
||||
{
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
||||
phx
|
||||
#else
|
||||
txa
|
||||
pha
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand phy_trash_a
|
||||
{
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
||||
phy
|
||||
#else
|
||||
tya
|
||||
pha
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand plx_trash_a
|
||||
{
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
||||
plx
|
||||
#else
|
||||
pla
|
||||
tax
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand ply_trash_a
|
||||
{
|
||||
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
||||
ply
|
||||
#else
|
||||
pla
|
||||
tay
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Branches with far offsets, substitutes by Bxx + JMP for CPUs not supporting the instruction
|
||||
//
|
||||
|
||||
|
||||
.pseudocommand bcs_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $B3, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bcc __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bcc_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $93, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bcs __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand beq_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $F3, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bne __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bne_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $D3, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
beq __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bmi_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $33, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bpl __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bpl_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $13, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bmi __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bvc_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $53, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bvs __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
|
||||
.pseudocommand bvs_far dst
|
||||
{
|
||||
#if CONFIG_CPU_CSG_65CE02
|
||||
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
||||
.byte $73, mod(offset, $100), floor(offset / $100)
|
||||
#else
|
||||
bvc __l
|
||||
jmp dst
|
||||
__l:
|
||||
#endif
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
|
||||
// Error codes for 'panic' pseudocommand
|
||||
|
||||
.const P_ERR_NONE = $00
|
||||
.const P_ERR_ROM_MISMATCH = $01 // this value has to be stable as long as possible
|
||||
|
||||
|
||||
// Kernal error codes - returned in the A register
|
||||
// Described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
|
||||
//
|
||||
// Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide
|
||||
// Names of hardware registers - names from C64 Programmer's Reference Guide, sometimes slightly modified
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// CPU memory registers
|
||||
|
||||
.label CPU_D6510 = $00
|
||||
@@ -61,7 +64,14 @@
|
||||
.label VIC_SP5COL = $D02C
|
||||
.label VIC_SP6COL = $D02D
|
||||
.label VIC_SP7COL = $D02E
|
||||
|
||||
|
||||
#if !CONFIG_MB_MEGA_65 && !CONFIG_MB_ULTIMATE_64
|
||||
|
||||
.label VIC_XSCAN = $D02F // C128 only
|
||||
.label VIC_CLKRATE = $D030 // C128 only
|
||||
|
||||
#endif
|
||||
|
||||
// SID registers
|
||||
|
||||
.label __SID_BASE = $D400 // base address of the chip
|
||||
@@ -154,3 +164,13 @@
|
||||
.const BIT_CIA2_PRA_DAT_OUT = $20 // 1 - low (pulled), 0 - high (released)
|
||||
.const BIT_CIA2_PRA_CLK_IN = $40 // 0 - low (pulled), 1 - high (released)
|
||||
.const BIT_CIA2_PRA_DAT_IN = $80 // 0 - low (pulled), 1 - high (released)
|
||||
|
||||
#if CONFIG_MB_MEGA_65
|
||||
|
||||
.const C65_EXTKEYS_PR = $D607
|
||||
.const C65_EXTKEYS_DDR = $D608
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
//
|
||||
// PETSCII codes for all the supported keys, for all the keyboards
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64
|
||||
// - [CM128] Compute's Mapping the Commodore 128
|
||||
// - https://github.com/MEGA65/c65-specifications/blob/master/c65manualupdated.txt
|
||||
// - https://en.wikipedia.org/wiki/PETSCII
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Not really PETSCII codes, but bitmask values for SHFLAG variable
|
||||
// [CM64] page 68, [CM128] page 212
|
||||
|
||||
.const KEY_FLAG_SHIFT = %00000001
|
||||
.const KEY_FLAG_VENDOR = %00000010
|
||||
.const KEY_FLAG_CTRL = %00000100
|
||||
.const KEY_FLAG_ALT = %00001000 // C65 / C128
|
||||
.const KEY_CAPS_LOCK = %00010000 // C65 / C128
|
||||
.const KEY_FLAG_NO_SCRL = %00100000 // C65 / C128, Open ROMs unofficial
|
||||
|
||||
|
||||
// Note - the following PETSCII codes are currently unassigned, can be used for further extensions:
|
||||
//
|
||||
// $01, $04, $06, $0A, $0B, $0C, $0F, $18, $82
|
||||
|
||||
|
||||
.const KEY_NA = $00 // to indicate that no key is presed
|
||||
|
||||
|
||||
// PETSCII codes for our extended screen editor XXX implement these
|
||||
|
||||
.const KEY_BOTTOM = $02 // CTRL+B - Open ROMs unofficial, DolphinDOS compatible
|
||||
.const KEY_TAB_FW = $8F // CTRL+>, TAB - Open ROMs unofficial, original TAB conflicts with C64 PETSCII
|
||||
.const KEY_TAB_BW = $80 // CTRL+<, SHIFT+TAB - Open ROMs unofficial, original TAB conflicts with C64 PETSCII
|
||||
|
||||
|
||||
// PETSCII codes for certain C128 and C65 functionalities XXX implement these
|
||||
|
||||
.const KEY_BELL = $07 // C65 / C128, no key
|
||||
.const KEY_ESC = $1B // C65 / C128
|
||||
|
||||
|
||||
// PETSCII codes for programmable keys
|
||||
|
||||
.const KEY_STOP = $03
|
||||
.const KEY_RUN = $83
|
||||
|
||||
.const KEY_F1 = $85
|
||||
.const KEY_F2 = $86
|
||||
.const KEY_F3 = $87
|
||||
.const KEY_F4 = $88
|
||||
.const KEY_F5 = $89
|
||||
.const KEY_F6 = $8A
|
||||
.const KEY_F7 = $8B
|
||||
.const KEY_F8 = $8C
|
||||
|
||||
.const KEY_F9 = $10 // C65
|
||||
.const KEY_F10 = $15 // C65
|
||||
.const KEY_F11 = $16 // C65
|
||||
.const KEY_F12 = $17 // C65
|
||||
.const KEY_F13 = $19 // C65
|
||||
.const KEY_F14 = $1A // C65
|
||||
|
||||
.const KEY_HELP = $84 // C65, also used for our C128 support
|
||||
|
||||
|
||||
// PETSCII codes for cursor keys
|
||||
|
||||
.const KEY_CRSR_UP = $91
|
||||
.const KEY_CRSR_DOWN = $11
|
||||
.const KEY_CRSR_LEFT = $9D
|
||||
.const KEY_CRSR_RIGHT = $1D
|
||||
|
||||
|
||||
// PETSCII codes for colors
|
||||
|
||||
.const KEY_RVS_ON = $12 // CTRL+9
|
||||
.const KEY_RVS_OFF = $92 // CTRL+0
|
||||
|
||||
.const KEY_BLACK = $90 // CTRL+1
|
||||
.const KEY_WHITE = $05 // CTRL+2
|
||||
.const KEY_RED = $1C // CTRL+3
|
||||
.const KEY_CYAN = $9F // CTRL+4
|
||||
.const KEY_PURPLE = $9C // CTRL+5
|
||||
.const KEY_GREEN = $1E // CTRL+6
|
||||
.const KEY_BLUE = $1F // CTRL+7
|
||||
.const KEY_YELLOW = $9E // CTRL+8
|
||||
|
||||
.const KEY_ORANGE = $81 // VENDOR+1
|
||||
.const KEY_BROWN = $95 // VENDOR+2
|
||||
.const KEY_LT_RED = $96 // VENDOR+3
|
||||
.const KEY_GREY_1 = $97 // VENDOR+4
|
||||
.const KEY_GREY_2 = $98 // VENDOR+5
|
||||
.const KEY_LT_GREEN = $99 // VENDOR+6
|
||||
.const KEY_LT_BLUE = $9A // VENDOR+7
|
||||
.const KEY_GREY_3 = $9B // VENDOR+8
|
||||
|
||||
|
||||
// PETSCII codes for case toggle
|
||||
|
||||
.const KEY_SHIFT_ON = $09 // no key
|
||||
.const KEY_SHIFT_OFF = $08 // no key
|
||||
.const KEY_TXT = $0E // no key
|
||||
.const KEY_GFX = $8E // no key
|
||||
|
||||
|
||||
// PETSCII codes for other non-printable characters
|
||||
|
||||
.const KEY_RETURN = $0D
|
||||
.const KEY_CLR = $93
|
||||
.const KEY_HOME = $13
|
||||
.const KEY_INS = $94
|
||||
.const KEY_DEL = $14
|
||||
|
||||
|
||||
// PETSCII codes for printable characters
|
||||
|
||||
.const KEY_SPACE = $20
|
||||
.const KEY_EXCLAMATION = $21
|
||||
.const KEY_QUOTE = $22
|
||||
.const KEY_HASH = $23
|
||||
.const KEY_DOLLAR = $24
|
||||
.const KEY_PERCENT = $25
|
||||
.const KEY_AMPERSAND = $26
|
||||
.const KEY_APOSTROPHE = $27
|
||||
.const KEY_R_BRACKET_L = $28
|
||||
.const KEY_R_BRACKET_R = $29
|
||||
.const KEY_ASTERISK = $2A
|
||||
.const KEY_PLUS = $2B
|
||||
.const KEY_COMA = $2C
|
||||
.const KEY_MINUS = $2D
|
||||
.const KEY_FULLSTOP = $2E
|
||||
.const KEY_SLASH = $2F
|
||||
|
||||
.const KEY_0 = $30
|
||||
.const KEY_1 = $31
|
||||
.const KEY_2 = $32
|
||||
.const KEY_3 = $33
|
||||
.const KEY_4 = $34
|
||||
.const KEY_5 = $35
|
||||
.const KEY_6 = $36
|
||||
.const KEY_7 = $37
|
||||
.const KEY_8 = $38
|
||||
.const KEY_9 = $39
|
||||
.const KEY_COLON = $3A
|
||||
.const KEY_SEMICOLON = $3B
|
||||
.const KEY_LT = $3C
|
||||
.const KEY_EQ = $3D
|
||||
.const KEY_GT = $3E
|
||||
.const KEY_QUESTION = $3F
|
||||
|
||||
// XXX finish this: $4x, $5x, $6x, $7x, $Ax, $Bx, $Cx, $Dx, $Ex, $Fx
|
||||
@@ -104,51 +104,22 @@
|
||||
.label CNTDN = $A5 // -- NOT IMPLEMENTED --
|
||||
.label BUFPNT = $A6 // -- NOT IMPLEMENTED --
|
||||
.label INBIT = $A7 // -- NOT IMPLEMENTED --
|
||||
|
||||
#if CONFIG_EXTENDED_SCNKEY
|
||||
|
||||
// Reuse RS232 variables, since they should not be used by other things.
|
||||
// Carefully avoid $A7 which is used by 64NET
|
||||
.label KeyQuantity = $A8 // 1 byte
|
||||
.label BufferNew = $A9 // 3 bytes
|
||||
|
||||
#else
|
||||
#if !CONFIG_LEGACY_SCNKEY
|
||||
.label BITCI = $A8 // -- NOT IMPLEMENTED --
|
||||
.label RINONE = $A9 // -- NOT IMPLEMENTED --
|
||||
.label RIDDATA = $AA // -- NOT IMPLEMENTED --
|
||||
.label RIPRTY = $AB // -- NOT IMPLEMENTED --
|
||||
|
||||
#endif
|
||||
|
||||
.label SAL = $AC // $AC-$AD -- NOT IMPLEMENTED -- (implemented screen part)
|
||||
.label EAL = $AE // $AE-$AF -- NOT IMPLEMENTED -- [!] used also by screen editor, for temporary color storage when scrolling
|
||||
.label CMP0 = $B0 // $B0-$B1 temporary tape storage, [!] here used for BRK instruction address
|
||||
.label TAPE1 = $B2 // $B2-$B3 tape buffer pointer
|
||||
|
||||
#if CONFIG_EXTENDED_SCNKEY
|
||||
|
||||
// Reuse RS232 variables, since they should not be used by other things.
|
||||
// This one should be initialized in cinit to $FF
|
||||
.label BufferQuantity = $B4 // 1 byte
|
||||
|
||||
#else
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY
|
||||
.label BITTS = $B4 // -- NOT IMPLEMENTED --
|
||||
|
||||
#endif
|
||||
|
||||
.label NXTBIT = $B5 // -- NOT IMPLEMENTED --
|
||||
|
||||
#if CONFIG_EXTENDED_SCNKEY
|
||||
|
||||
// Reuse RS232 variables, since they should not be used by other things.
|
||||
// Carefully avoiding $A7 which is used by 64NET
|
||||
.label TempZP = $B6 // 1 byte
|
||||
|
||||
#else
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY
|
||||
.label RODATA = $B6 // -- NOT IMPLEMENTED --
|
||||
|
||||
#endif
|
||||
|
||||
.label FNLEN = $B7 // current file name length
|
||||
@@ -182,7 +153,7 @@
|
||||
.label INSRT = $D8 // insert mode flag/counter
|
||||
.label LDTBL = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details
|
||||
.label USER = $F3 // $F3-$F4 pointer to current color RAM location
|
||||
.label KEYTAB = $F5 // $F5-$F6 -- NOT IMPLEMENTED --
|
||||
.label KEYTAB = $F5 // $F5-$F6 pointer to keyboard lookup table
|
||||
.label RIBUF = $F7 // $F7-$F8 -- NOT IMPLEMENTED --
|
||||
.label ROBUF = $F9 // $F9-$FA -- NOT IMPLEMENTED --
|
||||
// $FB $FB-$FE -- UNUSED -- free for user software
|
||||
@@ -200,13 +171,8 @@
|
||||
|
||||
.label BUF = $200 // $200-$250, BASIC line editor input buffer (81 bytes)
|
||||
|
||||
#if CONFIG_EXTENDED_SCNKEY
|
||||
|
||||
// $250-$258 is the 81st - 88th characters in BASIC input, a carry over from VIC-20
|
||||
// and not used on C64, so safe for us to use, probably.
|
||||
.label ScanResult = $250 // 8 bytes
|
||||
|
||||
#endif
|
||||
// and not used on C64 - they are used if CONFIG_LEGACY_SCNKEY is enabled.
|
||||
|
||||
// [!] XXX document $251-$258 usage
|
||||
.label LAT = $259 // $259-$262, logical file numbers (table, 10 bytes)
|
||||
@@ -220,7 +186,7 @@
|
||||
.label GDCOL = $287 // color of character under cursor
|
||||
.label HIBASE = $288 // high byte of start of screen
|
||||
.label XMAX = $289 // max keyboard buffer size
|
||||
.label RPTFLG = $28A // -- NOT IMPLEMENTED --
|
||||
.label RPTFLG = $28A // whether to repeat keys (highest bit set = repeat)
|
||||
.label KOUNT = $28B // key repeat counter
|
||||
.label DELAY = $28C // -- NOT IMPLEMENTED --
|
||||
.label SHFLAG = $28D // bucky keys (SHIFT/CTRL/C=) flags
|
||||
@@ -228,25 +194,14 @@
|
||||
.label KEYLOG = $28F // $28F-$290 routine to setup keyboard decoding
|
||||
.label MODE = $291 // flag, is case switch allowed
|
||||
.label AUTODN = $292 // -- NOT IMPLEMENTED -- screen scroll disable
|
||||
|
||||
#if CONFIG_EXTENDED_SCNKEY
|
||||
|
||||
// Reuse RS232 variables, since they should not be used by other things.
|
||||
// This one should be initialized in cinit to $FF
|
||||
.label BufferOld = $293 // 3 bytes
|
||||
.label Buffer = $297 // 4 bytes
|
||||
|
||||
#else
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY
|
||||
.label M51CRT = $293 // -- NOT IMPLEMENTED -- mock 6551
|
||||
.label M51CDR = $294 // -- NOT IMPLEMENTED -- mock 6551
|
||||
.label M51AJB = $295 // $295-$296 -- NOT IMPLEMENTED -- mock 6551
|
||||
.label RSSTAT = $297 // -- NOT IMPLEMENTED -- mock 6551, RS-232 status
|
||||
.label BITNUM = $298 // -- NOT IMPLEMENTED --
|
||||
.label BAUDOF = $299 // $299-$29A -- NOT IMPLEMENTED --
|
||||
|
||||
#endif
|
||||
|
||||
.label RIDBE = $29B // -- NOT IMPLEMENTED --
|
||||
.label RIDBS = $29C // -- NOT IMPLEMENTED --
|
||||
.label RODBS = $29D // -- NOT IMPLEMENTED --
|
||||
@@ -275,7 +230,7 @@
|
||||
#if SEGMENT_BASIC
|
||||
.label shift_mem_up = tiny_nmi_handler + shift_mem_up_routine - tiny_nmi_handler_routine
|
||||
.label shift_mem_down = tiny_nmi_handler + shift_mem_down_routine - tiny_nmi_handler_routine
|
||||
#endif // SEGMENT_BASIC
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
@@ -4,10 +4,21 @@
|
||||
#import "KERNAL_combined.sym"
|
||||
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
.label panic = KERNAL.panic
|
||||
#endif
|
||||
|
||||
.label hw_entry_reset = KERNAL.hw_entry_reset
|
||||
|
||||
#if CONFIG_DBG_PRINTF
|
||||
.label printf = KERNAL.printf
|
||||
#endif
|
||||
|
||||
.label plot_set = KERNAL.plot_set
|
||||
.label print_hex_byte = KERNAL.print_hex_byte
|
||||
.label print_return = KERNAL.print_return
|
||||
.label print_space = KERNAL.print_space
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
.label print_pal_ntsc = KERNAL.print_pal_ntsc
|
||||
#endif
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
|
||||
.text " OPEN ROMS, "
|
||||
.byte $00
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
|
||||
.text " OPEN ROMS FOR ULTIMATE 64"
|
||||
.byte $0D, $0D
|
||||
.text " "
|
||||
.byte $00
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
This address is called at least by the Simon's BASIC cartridge.
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
setup_keydecode:
|
||||
REASON:
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
This routine is probably used by many cartridges and other software to initialize parts of the system. At least the UCart uses it - see here:
|
||||
- https://www.elektroda.pl/rtvforum/topic3293027.html
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,7 @@
|
||||
This routine is used to launch other software. It is used by:
|
||||
|
||||
- Uncrunch (see https://github.com/mist64/pucrunch/blob/master/uncrunch.asm)
|
||||
- FileBrowser64 (FB64) - found by debugging
|
||||
|
||||
and probably others.
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
//
|
||||
// Well-known BASIC routine, described in:
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 95
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=64721&sid=bc400a5a6d404f8f092e4d32a92f5de7
|
||||
//
|
||||
|
||||
LINKPRG:
|
||||
|
||||
// Start by getting pointer to the first line
|
||||
jsr init_oldtxt
|
||||
|
||||
linkprg_loop:
|
||||
// Is the pointer to the end of the program
|
||||
ldy #1
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr peek_under_roms
|
||||
cmp #$00
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (OLDTXT),y
|
||||
#endif
|
||||
|
||||
bne !+
|
||||
|
||||
// End of program
|
||||
rts
|
||||
!:
|
||||
// Now search forward to find the end of the line
|
||||
// Skip forward pointer and line number
|
||||
ldy #4
|
||||
|
||||
linkprg_end_of_line_search:
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr peek_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (OLDTXT),y
|
||||
#endif
|
||||
|
||||
cmp #$00
|
||||
beq !+
|
||||
|
||||
// Not yet end of line
|
||||
iny
|
||||
bne linkprg_end_of_line_search
|
||||
|
||||
// line too long
|
||||
jmp do_STRING_TOO_LONG_error
|
||||
|
||||
!:
|
||||
// Found end of line, so update pointer
|
||||
|
||||
// First, skip over the $00 char
|
||||
iny
|
||||
|
||||
// Now overwrite the pointer (carefully)
|
||||
//
|
||||
tya
|
||||
clc
|
||||
adc OLDTXT+0
|
||||
pha
|
||||
php
|
||||
ldy #0
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr poke_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
sta (OLDTXT),y
|
||||
#endif
|
||||
|
||||
plp
|
||||
lda OLDTXT+1
|
||||
adc #0
|
||||
ldy #1
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
jsr poke_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
sta (OLDTXT),y
|
||||
#endif
|
||||
|
||||
sta OLDTXT+1
|
||||
pla
|
||||
sta OLDTXT+0
|
||||
|
||||
jmp linkprg_loop
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
This routine is probably used by many cartridges and other software to initialize parts of the system. At least the UCart uses it - see here:
|
||||
- https://www.elektroda.pl/rtvforum/topic3293027.html
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
// XXX provide documentation and real implementation
|
||||
|
||||
new:
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,6 @@
|
||||
This routine is used to launch other software. It is used by:
|
||||
|
||||
- Exomizer (see https://github.com/bitshifters/exomizer/blob/master/exomizer/exomizer115.txt)
|
||||
- FileBrowser64 (FB64) - found by debugging
|
||||
|
||||
and probably others.
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
// see: https://www.lemon64.com/forum/viewtopic.php?t=64721&sid=bc400a5a6d404f8f092e4d32a92f5de7
|
||||
// https://www.lemon64.com/forum/viewtopic.php?t=70680&sid=3ff66caf7f5fdf2a3c2ff2ee31fc3fd8
|
||||
|
||||
setcharptr:
|
||||
STUB_IMPLEMENTATION()
|
||||
+24
-2
@@ -1,5 +1,27 @@
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
// Well-known BASIC routine, described in:
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 97
|
||||
// - https://www.c64-wiki.com/wiki/BASIC-ROM
|
||||
// - https://csdb.dk/forums/?roomid=11&topicid=137233
|
||||
//
|
||||
|
||||
// XXX use this routine to initialize TXTPTR
|
||||
|
||||
RUNC:
|
||||
STUB_IMPLEMENTATION()
|
||||
// According to WIKI, we should load $7A/$7B with $2B-1/$2C-1), this does not makes sense.
|
||||
// But CSDB claims, that it should 'set current character pointer to start of basic - 1' - this
|
||||
// looks sane, also checked that the original BASIC routine does this (short test program)
|
||||
|
||||
// Let's initialize TXTPTR using TXTTAB
|
||||
|
||||
lda TXTTAB+0
|
||||
sec
|
||||
sbc #$01
|
||||
sta TXTPTR+0
|
||||
|
||||
lda TXTTAB+1
|
||||
sbc #$00
|
||||
sta TXTPTR+1
|
||||
|
||||
rts
|
||||
@@ -1,3 +1,9 @@
|
||||
This routine is mentionned in the cartridge writing tutorial here: https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image
|
||||
This routine is used to launch other software. It is used by:
|
||||
|
||||
- Exomizer (see https://github.com/bitshifters/exomizer/blob/master/exomizer/exomizer115.txt)
|
||||
- FileBrowser64 (FB64) - found by debugging
|
||||
|
||||
and probably others. It is also mentionned in the cartridge writing tutorial here:
|
||||
|
||||
- https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image
|
||||
|
||||
We have to implement (or at least provide stub), otherwise cartridges will crash.
|
||||
+15
-2
@@ -1,5 +1,18 @@
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
// Well-known BASIC routine, described in:
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 97
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=64721&sid=bc400a5a6d404f8f092e4d32a92f5de7
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=70680&sid=3ff66caf7f5fdf2a3c2ff2ee31fc3fd8
|
||||
// - https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image
|
||||
|
||||
NEWSTT:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
// XXX Real implementation is more complicated, it's actually a part
|
||||
// of the BASIC main loop. It is, however, often called by various
|
||||
// utilities to simply run the software which was just loaded or
|
||||
// uncompressed.
|
||||
|
||||
// For now, let's cheat a little - this should provide some compatibility:
|
||||
|
||||
jmp cmd_run
|
||||
@@ -7,9 +7,8 @@ STROUT:
|
||||
// Setup pointer
|
||||
sty FRESPC+1
|
||||
sta FRESPC+0
|
||||
|
||||
txa
|
||||
pha
|
||||
|
||||
phx_trash_a
|
||||
|
||||
// Get offset ready
|
||||
ldy #$00
|
||||
@@ -29,6 +28,6 @@ STROUT:
|
||||
iny
|
||||
bne !-
|
||||
!:
|
||||
pla
|
||||
pla // XXX can we use plx_trash_a here?
|
||||
tax
|
||||
rts
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
basic_do_error:
|
||||
// Save error number
|
||||
txa
|
||||
pha
|
||||
phx_trash_a
|
||||
|
||||
// Print ? at start
|
||||
jsr print_return
|
||||
@@ -11,8 +10,7 @@ basic_do_error:
|
||||
jsr JCHROUT
|
||||
|
||||
// Print main part of error message
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
jsr print_packed_message
|
||||
|
||||
// Print ERROR at end
|
||||
|
||||
@@ -112,26 +112,6 @@ not_a_token:
|
||||
cmp #$3a
|
||||
beq basic_skip_char
|
||||
|
||||
#if CONFIG_DOS_WEDGE
|
||||
|
||||
// Are we in direct mode?
|
||||
// DOS Wedge is a hacky solution (inelegant, but convenient),
|
||||
// BASIC programmers should implement communication with drives
|
||||
// the standard way, handling channels properly. Besides,
|
||||
// current implementation does not support characters under ROM
|
||||
ldx CURLIN+1
|
||||
cpx #$ff
|
||||
bne !+
|
||||
// We are in direct mode, allow wedge to handle '@' sign
|
||||
// XXX Maybe it should be allowed only as the first command?
|
||||
cmp #$40
|
||||
bne !+
|
||||
jsr basic_consume_character
|
||||
jmp wedge_dos
|
||||
!:
|
||||
|
||||
#endif // CONFIG_DOS_WEDGE
|
||||
|
||||
// If all else fails, it's a syntax error
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
|
||||
+28
-11
@@ -7,6 +7,10 @@ basic_main_loop:
|
||||
// Tell user we are ready
|
||||
jsr ready_message
|
||||
|
||||
// Enable Kernal messages
|
||||
lda #$80
|
||||
jsr JSETMSG
|
||||
|
||||
basic_read_next_line:
|
||||
// Read a line of input
|
||||
ldx #$00
|
||||
@@ -35,12 +39,13 @@ got_line_of_input:
|
||||
|
||||
// Strip leading spaces from the line
|
||||
remove_leading_spaces:
|
||||
lda $0200
|
||||
lda BUF
|
||||
cmp #$20
|
||||
bne !+
|
||||
ldx #1
|
||||
rsl_l1: lda $0200,x
|
||||
sta $01ff,x
|
||||
rsl_l1:
|
||||
lda BUF,x
|
||||
sta BUF-1,x
|
||||
inx
|
||||
cpx __tokenise_work1
|
||||
bne rsl_l1
|
||||
@@ -57,11 +62,23 @@ rsl_l1: lda $0200,x
|
||||
lda __tokenise_work1
|
||||
beq basic_read_next_line
|
||||
|
||||
#if CONFIG_DOS_WEDGE
|
||||
|
||||
// Check if DOS wedge should take over
|
||||
lda BUF
|
||||
cmp #$40 // '@'
|
||||
bne !+
|
||||
ldx __tokenise_work1 // here is the size of input
|
||||
jmp wedge_dos
|
||||
!:
|
||||
|
||||
#endif // CONFIG_DOS_WEDGE
|
||||
|
||||
// Else, tokenise the line
|
||||
jsr tokenise_line
|
||||
|
||||
// Has the user entered a line of BASIC beginning with a number?
|
||||
lda $0200
|
||||
lda BUF
|
||||
cmp #$30
|
||||
bcc not_a_line
|
||||
cmp #$39
|
||||
@@ -78,9 +95,9 @@ rsl_l1: lda $0200,x
|
||||
sta __tokenise_work1
|
||||
|
||||
// Try to read line number
|
||||
lda #<$0200
|
||||
lda #<BUF
|
||||
sta TXTPTR+0
|
||||
lda #>$0200
|
||||
lda #>BUF
|
||||
sta TXTPTR+1
|
||||
|
||||
jsr basic_parse_line_number
|
||||
@@ -94,13 +111,13 @@ rsl_l1: lda $0200,x
|
||||
// Skip any spaces after the line number
|
||||
ldx __tokenise_work1
|
||||
skip_spaces:
|
||||
lda $0200,x
|
||||
lda BUF,x
|
||||
cmp #$20
|
||||
bne !+
|
||||
inx
|
||||
bne skip_spaces
|
||||
!: stx __tokenise_work1
|
||||
|
||||
|
||||
// First, clear all variables, so that we only have to shove BASIC text around.
|
||||
// (We could later remove this requirement, and the only effect should be
|
||||
// to slow things down, and that you might have to either CLR if there is no
|
||||
@@ -131,9 +148,9 @@ not_a_line:
|
||||
// Actually interpret the line
|
||||
|
||||
// Setup pointer to the statement
|
||||
lda #<$0200
|
||||
lda #<BUF
|
||||
sta TXTPTR+0
|
||||
lda #>$0200
|
||||
lda #>BUF
|
||||
sta TXTPTR+1
|
||||
|
||||
// There is no stored line, so zero that pointer out
|
||||
@@ -144,7 +161,7 @@ not_a_line:
|
||||
// Put invalid line number in current line number value,
|
||||
// so that we know we are in direct mode
|
||||
// (Compute's Mapping the 64 p19)
|
||||
lda #$ff
|
||||
lda #$FF
|
||||
sta CURLIN+1
|
||||
|
||||
jmp basic_execute_statement
|
||||
@@ -7,4 +7,6 @@
|
||||
|
||||
|
||||
LINPRT:
|
||||
STUB_IMPLEMENTATION()
|
||||
// XXX This is temporary, to allow some software to work!
|
||||
// To be replaced by real impleementation.
|
||||
jmp print_integer
|
||||
@@ -1,31 +0,0 @@
|
||||
cmd_sys:
|
||||
|
||||
jsr basic_end_of_statement_check
|
||||
bcc !+
|
||||
|
||||
// SYS requires an argument
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
!:
|
||||
jsr basic_parse_line_number
|
||||
|
||||
// setup call
|
||||
lda #$4C // JMP opcode
|
||||
sta USRPOK
|
||||
lda LINNUM+0
|
||||
sta USRADD+0
|
||||
lda LINNUM+1
|
||||
sta USRADD+1
|
||||
|
||||
// Setup the register values
|
||||
lda SPREG
|
||||
pha
|
||||
ldy SYREG
|
||||
ldx SXREG
|
||||
lda SAREG
|
||||
plp
|
||||
|
||||
// Call the routine.
|
||||
jsr USRPOK
|
||||
|
||||
jmp basic_execute_statement
|
||||
@@ -1,5 +1,5 @@
|
||||
cmd_stop:
|
||||
ldx #38 // "BREAK"
|
||||
ldx #30 // "BREAK"
|
||||
jsr print_packed_message
|
||||
|
||||
// Are we in direct mode
|
||||
@@ -8,7 +8,7 @@ cmd_stop:
|
||||
beq !+
|
||||
|
||||
// Not direct mode
|
||||
ldx #37
|
||||
ldx #31
|
||||
jsr print_packed_message
|
||||
|
||||
lda CURLIN+1
|
||||
@@ -4,10 +4,7 @@
|
||||
cmd_list:
|
||||
|
||||
// Set current line pointer to start of memory
|
||||
lda TXTTAB+0
|
||||
sta OLDTXT+0
|
||||
lda TXTTAB+1
|
||||
sta OLDTXT+1
|
||||
jsr init_oldtxt
|
||||
|
||||
list_loop:
|
||||
|
||||
@@ -82,16 +79,20 @@ list_print_loop:
|
||||
cmp #$22
|
||||
bne list_not_quote
|
||||
lda QTSW
|
||||
eor #$ff
|
||||
eor #$FF
|
||||
sta QTSW
|
||||
lda #$22
|
||||
jmp list_is_literal
|
||||
|
||||
list_not_quote:
|
||||
// Check quote mode, and display as literal if required
|
||||
ldx QTSW
|
||||
bne list_is_literal
|
||||
|
||||
cmp #$7f
|
||||
cmp #$FF
|
||||
beq list_is_pi
|
||||
|
||||
cmp #$7F
|
||||
bcc list_is_literal
|
||||
|
||||
// Display a token
|
||||
@@ -99,8 +100,7 @@ list_not_quote:
|
||||
// Save registers
|
||||
tax
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
|
||||
// Get pointer to compressed keyword list
|
||||
lda #<packed_keywords
|
||||
@@ -118,8 +118,7 @@ list_not_quote:
|
||||
ldy #$ff
|
||||
jsr packed_word_search
|
||||
|
||||
pla
|
||||
tay
|
||||
ply_trash_a
|
||||
pla
|
||||
|
||||
cmp #$8f
|
||||
@@ -132,7 +131,12 @@ list_not_quote:
|
||||
list_not_rem:
|
||||
|
||||
iny
|
||||
bne list_print_loop
|
||||
bne list_print_loop // branch always
|
||||
|
||||
list_is_pi:
|
||||
lda #$7E
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
list_is_literal:
|
||||
jsr JCHROUT
|
||||
@@ -140,9 +144,6 @@ list_is_literal:
|
||||
bne list_print_loop
|
||||
|
||||
list_end_of_line:
|
||||
// Clear reverse flag
|
||||
lda #$92
|
||||
jsr JCHROUT
|
||||
// Print end of line
|
||||
jmp print_return
|
||||
|
||||
@@ -11,15 +11,6 @@ cmd_load:
|
||||
// middle of a program. For safety, we do.
|
||||
jsr basic_do_clr
|
||||
|
||||
// Setup Kernal to print control messages or not
|
||||
lda #$80 // display control messages and omit error messages
|
||||
ldx CURLIN+1
|
||||
cpx #$FF
|
||||
beq !+
|
||||
lda #$00 // direct mode - don't display anything
|
||||
!:
|
||||
jsr JSETMSG
|
||||
|
||||
// Set filename and length
|
||||
lda #$00
|
||||
sta FNLEN
|
||||
@@ -102,7 +93,9 @@ got_loadaddress:
|
||||
lda #$00 // LOAD not verify
|
||||
jsr JLOAD
|
||||
php
|
||||
pha
|
||||
jsr print_return
|
||||
pla
|
||||
plp
|
||||
bcc !+
|
||||
|
||||
@@ -121,7 +114,7 @@ got_loadaddress:
|
||||
// Now relink the loaded program, as we cannot trust the line
|
||||
// links supplied. For example, the VICE virtual drive emulation
|
||||
// always supplies $0101 as the address of the next line.
|
||||
jsr basic_relink_program
|
||||
jsr LINKPRG
|
||||
|
||||
// After LOADing, we either start the program from the beginning,
|
||||
// or go back to the READY prompt if LOAD was called from direct mode.
|
||||
@@ -131,87 +124,3 @@ got_loadaddress:
|
||||
|
||||
// XXX - should run program if LOAD was used in program mode
|
||||
jmp basic_main_loop
|
||||
|
||||
|
||||
basic_relink_program:
|
||||
|
||||
// Start by getting pointer to the first line
|
||||
jsr init_oldtxt
|
||||
|
||||
basic_relink_loop:
|
||||
// Is the pointer to the end of the program
|
||||
ldy #1
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr peek_under_roms
|
||||
cmp #$00
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (OLDTXT),y
|
||||
#endif
|
||||
|
||||
bne !+
|
||||
|
||||
// End of program
|
||||
rts
|
||||
!:
|
||||
// Now search forward to find the end of the line
|
||||
// Skip forward pointer and line number
|
||||
ldy #4
|
||||
end_of_line_search:
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr peek_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (OLDTXT),y
|
||||
#endif
|
||||
|
||||
cmp #$00
|
||||
beq !+
|
||||
|
||||
// Not yet end of line
|
||||
iny
|
||||
bne end_of_line_search
|
||||
|
||||
// line too long
|
||||
jmp do_STRING_TOO_LONG_error
|
||||
|
||||
!:
|
||||
// Found end of line, so update pointer
|
||||
|
||||
// First, skip over the $00 char
|
||||
iny
|
||||
|
||||
// Now overwrite the pointer (carefully)
|
||||
//
|
||||
tya
|
||||
clc
|
||||
adc OLDTXT+0
|
||||
pha
|
||||
php
|
||||
ldy #0
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<OLDTXT+0
|
||||
jsr poke_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
sta (OLDTXT),y
|
||||
#endif
|
||||
|
||||
plp
|
||||
lda OLDTXT+1
|
||||
adc #0
|
||||
ldy #1
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
jsr poke_under_roms
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
sta (OLDTXT),y
|
||||
#endif
|
||||
|
||||
sta OLDTXT+1
|
||||
pla
|
||||
sta OLDTXT+0
|
||||
|
||||
jmp basic_relink_loop
|
||||
File renamed without changes.
File renamed without changes.
@@ -2,11 +2,12 @@ cmd_run:
|
||||
// RUN clears all variables
|
||||
jsr basic_do_clr
|
||||
cmd_goto:
|
||||
// Disable Kernal messages
|
||||
lda #$00
|
||||
jsr JSETMSG
|
||||
|
||||
// Reset line pointer to first line of program.
|
||||
lda TXTTAB+0
|
||||
sta OLDTXT+0
|
||||
lda TXTTAB+1
|
||||
sta OLDTXT+1
|
||||
jsr init_oldtxt
|
||||
|
||||
jsr basic_end_of_statement_check
|
||||
bcs !+
|
||||
@@ -0,0 +1,68 @@
|
||||
cmd_sys:
|
||||
|
||||
jsr basic_end_of_statement_check
|
||||
bcc !+
|
||||
|
||||
// SYS requires an argument
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
!:
|
||||
//
|
||||
// XXX Temporary ugly hack to support 'SYS PI*656'
|
||||
//
|
||||
|
||||
ldy #$00
|
||||
|
||||
cmd_sys_hack_loop:
|
||||
lda (TXTPTR), y
|
||||
cmp cmd_sys_hack_str, y
|
||||
bne cmd_sys_hack_not_needed
|
||||
lda (TXTPTR), y
|
||||
beq cmd_sys_hack_apply
|
||||
iny
|
||||
bne cmd_sys_hack_loop // branch always
|
||||
|
||||
cmd_sys_hack_apply:
|
||||
|
||||
lda #<2060
|
||||
sta LINNUM+0
|
||||
lda #>2060
|
||||
sta LINNUM+1
|
||||
bne cmd_sys_setup_call // always jumps
|
||||
|
||||
cmd_sys_hack_not_needed:
|
||||
|
||||
//
|
||||
// XXX End of hack
|
||||
//
|
||||
|
||||
jsr basic_parse_line_number
|
||||
|
||||
cmd_sys_setup_call:
|
||||
lda #$4C // JMP opcode
|
||||
sta USRPOK
|
||||
lda LINNUM+0
|
||||
sta USRADD+0
|
||||
lda LINNUM+1
|
||||
sta USRADD+1
|
||||
|
||||
// Setup the register values
|
||||
lda SPREG
|
||||
pha
|
||||
ldy SYREG
|
||||
ldx SXREG
|
||||
lda SAREG
|
||||
plp
|
||||
|
||||
// Call the routine.
|
||||
jsr USRPOK
|
||||
|
||||
jmp basic_execute_statement
|
||||
|
||||
|
||||
//
|
||||
// XXX Temporary ugly hack to support 'SYS PI*656'
|
||||
//
|
||||
|
||||
cmd_sys_hack_str:
|
||||
.byte $FF, $AC, $36, $35, $36, $00
|
||||
File renamed without changes.
@@ -150,7 +150,7 @@ do_basic_error:
|
||||
beq !+
|
||||
|
||||
// We were in a program, so show IN <line>
|
||||
ldx #37
|
||||
ldx #31
|
||||
jsr print_packed_message
|
||||
|
||||
lda CURLIN+1
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
//
|
||||
// Well-known BASIC routine, described in:
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 212
|
||||
//
|
||||
// Prints the start-up messages
|
||||
//
|
||||
|
||||
INITMSG:
|
||||
|
||||
// Print startup banner, up to 255 characters
|
||||
ldx #$00
|
||||
!:
|
||||
lda startup_banner, x
|
||||
beq !+ // 0 means end of banner
|
||||
jsr JCHROUT
|
||||
inx
|
||||
bne !-
|
||||
|
||||
!:
|
||||
// Print PAL/NTSC
|
||||
ldx #30 // NTSC
|
||||
lda TVSFLG
|
||||
beq !+
|
||||
ldx #31 // PAL
|
||||
!:
|
||||
jsr print_packed_message
|
||||
|
||||
// Work out free bytes, display them
|
||||
jsr basic_do_new
|
||||
sec
|
||||
lda MEMSIZ+0
|
||||
sbc TXTTAB+0
|
||||
tax
|
||||
lda MEMSIZ+1
|
||||
sbc TXTTAB+1
|
||||
|
||||
jsr print_integer
|
||||
jsr print_space
|
||||
|
||||
// Print rest of the start up message
|
||||
ldx #34
|
||||
jmp print_packed_message
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,7 +1,9 @@
|
||||
// BASIC Cold start entry point
|
||||
// Compute's Mapping the 64 p211
|
||||
|
||||
basic_cold_start:
|
||||
//
|
||||
// Continuation of the BASIC cold start routine
|
||||
//
|
||||
|
||||
basic_cold_start_internal:
|
||||
|
||||
// Setup vectors at $300
|
||||
ldy #$0B
|
||||
@@ -1,6 +1,9 @@
|
||||
// Clear screen etc, show READY prompt.
|
||||
|
||||
basic_warm_start:
|
||||
//
|
||||
// Continuation of the BASIC cold start routine
|
||||
//
|
||||
|
||||
basic_warm_start_real:
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
// We need our helpers to get to filenames under ROMs or IO area
|
||||
@@ -8,6 +11,7 @@ basic_warm_start:
|
||||
#endif
|
||||
|
||||
// If warm start caused by BRK, print it address
|
||||
// XXX sys 58235 also triggers this - to be fixed
|
||||
lda CMP0
|
||||
ora CMP0+1
|
||||
beq !+
|
||||
@@ -0,0 +1,22 @@
|
||||
// BASIC Cold start entry point
|
||||
// Compute's Mapping the 64 p211
|
||||
|
||||
basic_cold_start:
|
||||
|
||||
// Before doing anything, check if we have a compatible BASIC/KERNAL pair
|
||||
|
||||
ldy #(__rom_revision_basic_end - rom_revision_basic - 1)
|
||||
!:
|
||||
lda rom_revision_basic, y
|
||||
cmp rom_revision_kernal, y
|
||||
beq !+
|
||||
|
||||
panic #P_ERR_ROM_MISMATCH
|
||||
|
||||
!:
|
||||
dey
|
||||
bpl !--
|
||||
|
||||
// Remaining part wouldn't fit here
|
||||
|
||||
jmp basic_cold_start_internal
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
The address of the BASIC cold start routine (see Compute's Mapping the Commodore 64, page 211) is well known, see for example here:
|
||||
|
||||
- https://www.lemon64.com/forum/viewtopic.php?t=70680&sid=3ff66caf7f5fdf2a3c2ff2ee31fc3fd8
|
||||
|
||||
Fixing this routine also has a great advantage for us - since it's address lies in the uppeer ROM region, it's easier to bailout
|
||||
when someone tries to use our 'kernal.rom' with the original 'basic.rom'.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Clear screen etc, show READY prompt.
|
||||
|
||||
basic_warm_start:
|
||||
|
||||
jmp basic_warm_start_real
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
This is a well-known address, needed even for some BASIC programming - it's a common target for a SYS command. See for example here:
|
||||
|
||||
- http://ready64.org/articoli/_files/043_pokesc64.txt
|
||||
sys 58235 - Warm Start
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
//
|
||||
// Well-known BASIC routine, described in:
|
||||
//
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 212
|
||||
//
|
||||
// Prints the start-up messages
|
||||
//
|
||||
|
||||
INITMSG:
|
||||
jmp initmsg_real
|
||||
File renamed without changes.
@@ -0,0 +1,21 @@
|
||||
|
||||
//
|
||||
// Print out the amount of free bytes - for the startup banner
|
||||
//
|
||||
|
||||
|
||||
initmsg_bytes_free:
|
||||
|
||||
jsr basic_do_new
|
||||
sec
|
||||
lda MEMSIZ+0
|
||||
sbc TXTTAB+0
|
||||
tax
|
||||
lda MEMSIZ+1
|
||||
sbc TXTTAB+1
|
||||
|
||||
jsr print_integer
|
||||
|
||||
// Print rest of the start up message
|
||||
ldx #34
|
||||
jmp print_packed_message
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
// Routine is too long to fit in the original location
|
||||
|
||||
|
||||
initmsg_real:
|
||||
|
||||
#if CONFIG_BANNER_SIMPLE
|
||||
|
||||
lda #<startup_banner
|
||||
ldy #>startup_banner
|
||||
jsr STROUT
|
||||
|
||||
ldx #$02
|
||||
ldy #$02
|
||||
jsr plot_set
|
||||
|
||||
lda #<rom_revision_basic_string
|
||||
ldy #>rom_revision_basic_string
|
||||
jsr STROUT
|
||||
|
||||
ldx #$04
|
||||
ldy #$02
|
||||
jsr plot_set
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
jsr print_pal_ntsc
|
||||
#endif
|
||||
|
||||
jsr initmsg_bytes_free
|
||||
|
||||
ldx #$07
|
||||
ldy #$00
|
||||
jmp plot_set
|
||||
|
||||
#elif CONFIG_BANNER_FANCY
|
||||
|
||||
lda #<rainbow_logo
|
||||
ldy #>rainbow_logo
|
||||
jsr STROUT
|
||||
|
||||
ldx #$01
|
||||
ldy #$0A
|
||||
jsr plot_set
|
||||
|
||||
lda #<startup_banner
|
||||
ldy #>startup_banner
|
||||
jsr STROUT
|
||||
|
||||
ldx #$03
|
||||
ldy #$0A
|
||||
jsr plot_set
|
||||
|
||||
lda #<pre_revision_string
|
||||
ldy #>pre_revision_string
|
||||
jsr STROUT
|
||||
|
||||
lda #<rom_revision_basic_string
|
||||
ldy #>rom_revision_basic_string
|
||||
jsr STROUT
|
||||
|
||||
ldx #$05
|
||||
ldy #$00
|
||||
jsr plot_set
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
jsr print_pal_ntsc
|
||||
#endif
|
||||
|
||||
jsr initmsg_bytes_free
|
||||
|
||||
ldx #$07
|
||||
ldy #$00
|
||||
jmp plot_set
|
||||
|
||||
#elif CONFIG_BANNER_BRAND && CONFIG_BRAND_MEGA_65
|
||||
|
||||
lda #<startup_banner
|
||||
ldy #>startup_banner
|
||||
jsr STROUT
|
||||
|
||||
lda #<rom_revision_basic_string
|
||||
ldy #>rom_revision_basic_string
|
||||
jsr STROUT
|
||||
|
||||
ldx #$03
|
||||
ldy #$12
|
||||
jsr plot_set
|
||||
|
||||
jsr initmsg_bytes_free
|
||||
|
||||
ldx #$05
|
||||
ldy #$00
|
||||
jmp plot_set
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,72 @@
|
||||
|
||||
// Target-specific hooks
|
||||
//
|
||||
// Startup banner, to be displayed during cold start
|
||||
//
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
.macro BANNER_TEXT() {
|
||||
|
||||
// New banner from Retrofan
|
||||
#if CONFIG_BRAND_GENERIC
|
||||
.text "OPEN ROMS GENERIC BUILD"
|
||||
#elif CONFIG_BRAND_TESTING
|
||||
.text "OPEN ROMS TESTING BUILD"
|
||||
#elif CONFIG_BRAND_MEGA_65
|
||||
.text "OPEN ROMS FOR MEGA65"
|
||||
#elif CONFIG_BRAND_ULTIMATE_64
|
||||
.text "OPEN ROMS FOR ULTIMATE 64"
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
startup_banner:
|
||||
|
||||
#if CONFIG_BANNER_SIMPLE
|
||||
|
||||
.text " "
|
||||
BANNER_TEXT()
|
||||
.byte $00
|
||||
|
||||
#elif CONFIG_BANNER_FANCY
|
||||
|
||||
BANNER_TEXT()
|
||||
.byte $00
|
||||
|
||||
rainbow_logo:
|
||||
|
||||
{
|
||||
#if CONFIG_COLORS_BRAND && CONFIG_BRAND_MEGA_65
|
||||
|
||||
.var SET_COLOR_0 = $05
|
||||
.var SET_COLOR_1 = $9A
|
||||
.var SET_COLOR_2 = $1E
|
||||
.var SET_COLOR_3 = $9E
|
||||
.var SET_COLOR_4 = $96
|
||||
|
||||
#else
|
||||
|
||||
.var SET_COLOR_0 = $05
|
||||
.var SET_COLOR_1 = $1C
|
||||
.var SET_COLOR_2 = $9E
|
||||
.var SET_COLOR_3 = $1E
|
||||
.var SET_COLOR_4 = $9F
|
||||
|
||||
#endif
|
||||
|
||||
.byte SET_COLOR_1, $12, $A4, $A4, $A4, $A4, $A4, $A4, $A4, $0D
|
||||
.byte SET_COLOR_2, $12, $A4, $A4, $A4, $A4, $A4, $A4, $0D
|
||||
.byte SET_COLOR_3, $12, $A4, $A4, $A4, $A4, $A4, $0D
|
||||
.byte SET_COLOR_4, $12, $A4, $A4, $A4, $A4, $92
|
||||
.byte SET_COLOR_0, $00
|
||||
}
|
||||
|
||||
pre_revision_string:
|
||||
|
||||
.text "RELEASE "
|
||||
.byte $00
|
||||
|
||||
#elif CONFIG_BANNER_BRAND && CONFIG_BRAND_MEGA_65
|
||||
|
||||
// Fancy Mega65 banner - from Retrofan
|
||||
.byte $9a, $12, $20, $20, $7f, $a9, $20, $20, $1f, $20, $9a, $20, $20, $20
|
||||
.byte $20, $1f, $20, $9a, $a9, $20, $20, $20, $92, $a1, $1f, $12, $20, $9a, $a9, $20
|
||||
.byte $20, $20, $7f, $1f, $20, $20, $9a, $a3, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20
|
||||
@@ -21,7 +83,7 @@
|
||||
.byte $20, $20, $1f, $20, $20, $96, $a3, $a3, $a3, $a3, $1f
|
||||
.byte $92, $0D, $0D, $05, $00
|
||||
|
||||
// Original Deft-supplied banner
|
||||
// Original Mega65 banner - supplied by Deft
|
||||
// .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
// .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
// .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9A,$92,$20,$05,$20,$20,$20
|
||||
@@ -38,4 +100,4 @@
|
||||
// .byte $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D
|
||||
// .byte $0D,$05,$92,$00
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -5,8 +5,7 @@
|
||||
print_integer:
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
phx_trash_a
|
||||
|
||||
// Clear temporary output
|
||||
lda #$00
|
||||
|
||||
@@ -32,15 +32,13 @@ packed_message_search:
|
||||
|
||||
found_message_in_token_stream:
|
||||
// Now print each word in the message
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
lda packed_message_tokens,y
|
||||
cmp #$ff
|
||||
beq !+
|
||||
jsr print_packed_word
|
||||
jsr print_space
|
||||
pla
|
||||
tay
|
||||
ply_trash_a
|
||||
iny
|
||||
bne found_message_in_token_stream
|
||||
!:
|
||||
@@ -139,16 +137,14 @@ next_packed_word_char:
|
||||
tax
|
||||
|
||||
// Save Y so it doesn't get clobbered by CHROUT
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
|
||||
// X=1-14 = first 14 chars, so subtract one
|
||||
lda packed_message_chars-1,x
|
||||
jsr JCHROUT
|
||||
|
||||
// See if there is a char in the low nybl to print
|
||||
pla
|
||||
tay
|
||||
ply_trash_a
|
||||
lda (FRESPC),y
|
||||
and #$0f
|
||||
beq end_of_packed_word
|
||||
@@ -158,8 +154,7 @@ next_packed_word_char:
|
||||
has_lo_nybl_char:
|
||||
// We need to print the low nybl char as well
|
||||
tax
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
|
||||
// Skip lower nybls of $F or $0 in nybl packed
|
||||
// bytes, as these do not encode characters
|
||||
@@ -173,8 +168,7 @@ has_nybl:
|
||||
lda packed_message_chars-1,x
|
||||
jsr JCHROUT
|
||||
!:
|
||||
pla
|
||||
tay
|
||||
ply_trash_a
|
||||
// FALLTHROUGH
|
||||
|
||||
no_lo_nybl_char:
|
||||
@@ -204,8 +198,7 @@ next_is_literal_char:
|
||||
unpack_literal_char:
|
||||
// Output the literal char, and ready for next char
|
||||
iny
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
lda (FRESPC),y
|
||||
jsr JCHROUT
|
||||
pla
|
||||
@@ -222,7 +215,6 @@ is_uncommon_char:
|
||||
|
||||
// We need to print the low nybl char as well
|
||||
tax
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
|
||||
jmp has_nybl
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,2 @@
|
||||
|
||||
Special case - we need a constant memory location where we can put an ID and a revision string. According to Compute's Mapping the Commodore 64 (page 117) this area is unused - so a perfect place.
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
//
|
||||
// !!! PROPOSAL ONLY !!! PROPOSAL ONLY !!! NOT FOR USING EXTERNALLY YET !!!
|
||||
//
|
||||
//
|
||||
// Do not change! Locations of the following data should be constant - now and forever!
|
||||
//
|
||||
// If you want to integrate Open ROMs support in your emulator, FPGA ccomputer, etc. - this
|
||||
// is the official way to recognize the ROM and it's revision.
|
||||
//
|
||||
|
||||
|
||||
rom_revision_basic:
|
||||
|
||||
// $BF52
|
||||
|
||||
.text "OR" // project signature, after "Open ROMs"
|
||||
.byte CONFIG_ID // config file ID, might change between revisions
|
||||
|
||||
rom_revision_basic_string:
|
||||
|
||||
// $BF55
|
||||
|
||||
.text "(DEVEL SNAPSHOT)" // actual ROM revision string; up to 16 characters
|
||||
.byte $00 // marks the end of string
|
||||
|
||||
__rom_revision_basic_end:
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
Special case - we need a constant memory location where we can put an ID and a revision string. According to Compute's Mapping the Commodore 64 (page 213) this area is unused - so a perfect place.
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
//
|
||||
// !!! PROPOSAL ONLY !!! PROPOSAL ONLY !!! NOT FOR USING EXTERNALLY YET !!!
|
||||
//
|
||||
//
|
||||
// Do not change! Locations of the following data should be constant - now and forever!
|
||||
//
|
||||
// If you want to integrate Open ROMs support in your emulator, FPGA ccomputer, etc. - this
|
||||
// is the official way to recognize the ROM and it's revision.
|
||||
//
|
||||
|
||||
|
||||
// $E4B7
|
||||
|
||||
// This vector is to be used by non-Kernal ROMs, if they want to
|
||||
// complain about incompatible ROM releases - don't use it directly,
|
||||
// use a 'panic' pseudocommand with error code (will be passed using .A)
|
||||
// #P_ERR_ROM_MISMATCH - it should remain stable even between releases
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
.word panic
|
||||
#else
|
||||
.word hw_entry_reset
|
||||
#endif
|
||||
|
||||
|
||||
rom_revision_kernal:
|
||||
|
||||
// $E4B9
|
||||
|
||||
.text "OR" // project signature, after "Open ROMs"
|
||||
.byte CONFIG_ID // config file ID, might change between revisions
|
||||
|
||||
rom_revision_kernal_string:
|
||||
|
||||
// $E4BC
|
||||
|
||||
.text "(DEVEL SNAPSHOT)" // actual ROM revision string; up to 16 characters
|
||||
.byte $00 // marks the end of string
|
||||
|
||||
__rom_revision_kernal_end:
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
//
|
||||
// Startup banner, to be displayed durin cold start
|
||||
//
|
||||
|
||||
startup_banner:
|
||||
TARGET_HOOK_BANNER()
|
||||
+19
-3
@@ -1,8 +1,15 @@
|
||||
|
||||
#if CONFIG_DOS_WEDGE
|
||||
|
||||
// .X has to contain size of the buffer
|
||||
|
||||
wedge_dos:
|
||||
|
||||
// Prepare buffer - finish it with '0'
|
||||
|
||||
lda #$00
|
||||
sta BUF,x
|
||||
|
||||
// Close all the channels, so that wedge has full control
|
||||
jsr JCLALL
|
||||
|
||||
@@ -12,6 +19,16 @@ wedge_dos:
|
||||
ldy #$0F
|
||||
jsr JSETFLS
|
||||
|
||||
// Setup necessary parts of BASIC
|
||||
|
||||
lda #<(BUF+1)
|
||||
sta TXTPTR+0
|
||||
lda #>(BUF+1)
|
||||
sta TXTPTR+1
|
||||
|
||||
lda #$FF
|
||||
sta CURLIN+1
|
||||
|
||||
// Now we have to check what the user wants us to do
|
||||
|
||||
// Check if user asked for a status
|
||||
@@ -210,13 +227,12 @@ wedge_dos_clean_exit:
|
||||
jsr JCLALL
|
||||
// Print new line
|
||||
jsr print_return
|
||||
jmp basic_end_of_line
|
||||
jmp basic_main_loop
|
||||
|
||||
wedge_dos_basic_error:
|
||||
pha
|
||||
jsr JCLALL
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
dex
|
||||
jmp do_basic_error
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,6 +0,0 @@
|
||||
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
// XXX disabled for now - the current file opening API is not
|
||||
// really suitable for easy usage from Kernal
|
||||
// jsr u64_load
|
||||
}
|
||||
@@ -5,40 +5,74 @@
|
||||
|
||||
// Double underscore prevents labels from being passed to VICE (would confuse monitor)
|
||||
|
||||
.label __MSG_KERNAL_SEARCHING_FOR = __kernal_message_searching_for - __kernal_messages_start
|
||||
.label __MSG_KERNAL_LOADING = __kernal_message_loading - __kernal_messages_start
|
||||
.label __MSG_KERNAL_VERIFYING = __kernal_message_verifying - __kernal_messages_start
|
||||
.label __MSG_KERNAL_SAVING = __kernal_message_saving - __kernal_messages_start
|
||||
.label __MSG_KERNAL_FROM_HEX = __kernal_message_from_hex - __kernal_messages_start
|
||||
.label __MSG_KERNAL_TO_HEX = __kernal_message_to_hex - __kernal_messages_start
|
||||
.label __MSG_KERNAL_SEARCHING_FOR = __msg_kernalsearching_for - __msg_kernal_first
|
||||
.label __MSG_KERNAL_LOADING = __msg_kernalloading - __msg_kernal_first
|
||||
.label __MSG_KERNAL_VERIFYING = __msg_kernalverifying - __msg_kernal_first
|
||||
.label __MSG_KERNAL_SAVING = __msg_kernalsaving - __msg_kernal_first
|
||||
.label __MSG_KERNAL_FROM_HEX = __msg_kernalfrom_hex - __msg_kernal_first
|
||||
.label __MSG_KERNAL_TO_HEX = __msg_kernalto_hex - __msg_kernal_first
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
.label __MSG_KERNAL_PAL = __msg_kernalpal - __msg_kernal_first
|
||||
.label __MSG_KERNAL_NTSC = __msg_kernalntsc - __msg_kernal_first
|
||||
#endif
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
.label __MSG_KERNAL_PANIC = __msg_kernalpanic - __msg_kernal_first
|
||||
.label __MSG_KERNAL_PANIC_ROM_MISMATCH = __msg_kernalpanic_rom_mismatch - __msg_kernal_first
|
||||
#endif
|
||||
|
||||
|
||||
__kernal_messages_start:
|
||||
__msg_kernal_first:
|
||||
|
||||
__kernal_message_searching_for:
|
||||
__msg_kernalsearching_for:
|
||||
.byte $0D
|
||||
.text "SEARCHING FOR"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
__kernal_message_loading:
|
||||
__msg_kernalloading:
|
||||
.byte $0D
|
||||
.text "LOADIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
__kernal_message_verifying:
|
||||
__msg_kernalverifying:
|
||||
.byte $0D
|
||||
.text "VERIFYIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
__kernal_message_saving:
|
||||
__msg_kernalsaving:
|
||||
.byte $0D
|
||||
.text "SAVIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
__kernal_message_from_hex:
|
||||
__msg_kernalfrom_hex:
|
||||
.text " FROM "
|
||||
.byte $80 + $24 // end of string mark + '$'
|
||||
|
||||
__kernal_message_to_hex:
|
||||
__msg_kernalto_hex:
|
||||
.text " TO "
|
||||
.byte $80 + $24 // end of string mark + '$'
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
__msg_kernalpal:
|
||||
.text "PAL,"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
__msg_kernalntsc:
|
||||
.text "NTSC,"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
#endif // CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
|
||||
__msg_kernalpanic:
|
||||
.text "KERNAL PANI"
|
||||
.byte $80 + $43 // end of string mark + 'C'
|
||||
|
||||
__msg_kernalpanic_rom_mismatch:
|
||||
.text " - ROM MISMATC"
|
||||
.byte $80 + $48 // end of string mark + 'H'
|
||||
|
||||
#endif // CONFIG_PANIC_SCREEN
|
||||
@@ -1,72 +0,0 @@
|
||||
// Key board matrixes: unshifted, shifted, control and C= modified
|
||||
// 64 bytes for each
|
||||
|
||||
|
||||
keyboard_matrixes:
|
||||
// Unshifted matrix built by refering to
|
||||
// Compute's Mapping the 64 p38-39
|
||||
// and C64 PRG pages 379-381
|
||||
.byte $14,$0D,$1D,$88,$85,$86,$87,17
|
||||
.byte $33,87,$41,$34,$5A,83,$45,$00
|
||||
.byte $35,$52,$44,$36,$43,$46,$54,88
|
||||
.byte $37,$59,$47,$38,$42,$48,$55,$56
|
||||
.byte $39,$49,$4A,$30,$4D,$4B,$4F,$4E
|
||||
.byte $2B,$50,$4C,45,46,58,$40,44
|
||||
.byte $5C,$2A,59,$13,$00,$3D,$5E,$2F
|
||||
.byte $31,$5F,$00,$32,$20,$00,$51,$03
|
||||
|
||||
// Shifted keyboard
|
||||
// Values computed by running a program like:
|
||||
// 10 GETA$:IFA$=""GOTO10
|
||||
// 20 ?ASC(A$):GOTO10
|
||||
// and converting the values
|
||||
.byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91
|
||||
.byte $23,$77,$61,$24,$7A,$73,$65,$00
|
||||
.byte $25,$72,$64,$26,$63,$66,$74,$78
|
||||
.byte $27,$79,$67,$28,$62,$68,$75,$76
|
||||
.byte $29,$69,$6A,$92,$6D,$6B,$6F,$6E
|
||||
.byte $DB,$70,$6C,$DD,$3E,$5B,$BA,$3C
|
||||
.byte $A9,$C0,$5D,$93,$00,$3D,$DE,$3F
|
||||
.byte $21,$5F,$00,$22,$A0,$00,$71,$83
|
||||
|
||||
// Vendor key modified keyboard
|
||||
.byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91
|
||||
.byte $96,$B3,$B0,$97,$AD,$AE,$B1,$00
|
||||
.byte $98,$B2,$AC,$99,$BC,$BB,$A3,$BD
|
||||
.byte $9A,$B7,$A5,$9B,$BF,$B4,$B8,$BE
|
||||
.byte $30,$A2,$B5,$30,$A7,$A1,$B9,$AA
|
||||
.byte $A6,$AF,$B6,$DC,$3E,$5B,$A4,$3C
|
||||
.byte $A8,$DF,$5D,$93,$00,$3D,$DE,$3F
|
||||
.byte $81,$5F,$00,$95,$a0,$00,$AB,$83
|
||||
|
||||
// Control modified keyboard
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $1C,$17,$01,$9F,$1A,$13,$05,$00
|
||||
.byte $9C,$12,$04,$1E,$03,$06,$14,$18
|
||||
.byte $1F,$19,$07,$9E,$02,$08,$15,$16
|
||||
.byte $12,$09,$0A,$92,$0D,$0B,$0F,$0E
|
||||
.byte $00,$10,$0C,$00,$00,$1B,$00,$00
|
||||
.byte $1C,$00,$1D,$00,$00,$1F,$1E,$00
|
||||
.byte $90,$06,$00,$05,$00,$00,$11,$00
|
||||
|
||||
|
||||
keyboard_matrix_lookup:
|
||||
// Work out if normal, shifted, control or Vendor
|
||||
// modified keyboard.
|
||||
// Table contains the offsets into keyboard_matrixes
|
||||
// that should be used for different values of
|
||||
// the bottom 3 bits of key_bucky_state
|
||||
// Interaction is simple to work out when playing
|
||||
// with a C64:
|
||||
// CONTROL trumps SHIFT or Vendor
|
||||
// Vendor + SHIFT = DOES NOTHING
|
||||
// All 3 does CONTROL
|
||||
.byte $00 // Normal
|
||||
.byte $40 // Shifted
|
||||
.byte $80 // Control
|
||||
.byte $80 // Control + SHIFT
|
||||
.byte $C0 // Vendor
|
||||
.byte $C0 // Vendor + SHIFT
|
||||
.byte $80 // Vendor+ CTRL
|
||||
.byte $80 // Vendor + CTRL + SHIFT
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// We have the following variables:
|
||||
// BLNSW (cursor blink switch)
|
||||
// BLNCT (cursor blink countdown)
|
||||
// GDBLN (cursor saved character)
|
||||
// BLNON (if cursor is visible)
|
||||
// GDCOL (colour under cursor)
|
||||
// USER (current screen line colour pointer)
|
||||
// PNT (current screen line pointer)
|
||||
// PNTR (current screen x position)
|
||||
|
||||
show_cursor_if_enabled:
|
||||
lda BLNSW
|
||||
beq !+
|
||||
rts
|
||||
!: lda BLNON
|
||||
beq show_cursor
|
||||
rts
|
||||
|
||||
show_cursor:
|
||||
// Set cursor as though it had just finished the off phase,
|
||||
// so that the call to blink_cursor paints it
|
||||
lda #$00
|
||||
sta BLNCT
|
||||
sta BLNON
|
||||
jsr blink_cursor
|
||||
// Then set the timeout to 1 frame, so that the cursor
|
||||
// blinks under key repeat conditions, like on the original KERNAL
|
||||
lda #$01
|
||||
sta BLNCT
|
||||
rts
|
||||
|
||||
blink_cursor:
|
||||
// Is the cursor enabled?
|
||||
lda BLNSW
|
||||
bne no_blink_cursor
|
||||
|
||||
// Do we need to redraw things?
|
||||
dec BLNCT
|
||||
bpl no_blink_cursor
|
||||
|
||||
// Check if cursor was visible or not, and toggle
|
||||
lda BLNON
|
||||
bne undraw_cursor
|
||||
draw_cursor:
|
||||
jsr calculate_screen_line_pointer
|
||||
|
||||
ldy PNTR
|
||||
lda (PNT),y
|
||||
sta GDBLN
|
||||
eor #$80
|
||||
sta (PNT),y
|
||||
// Also set cursor colour
|
||||
lda (USER),y
|
||||
sta GDCOL
|
||||
lda COLOR
|
||||
sta (USER),y
|
||||
|
||||
lda #1
|
||||
sta BLNON
|
||||
|
||||
jmp reset_blink_timer
|
||||
|
||||
undraw_cursor:
|
||||
jsr calculate_screen_line_pointer
|
||||
|
||||
lda GDBLN
|
||||
ldy PNTR
|
||||
sta (PNT),y
|
||||
lda GDCOL
|
||||
sta (USER),y
|
||||
|
||||
lda #0
|
||||
sta BLNON
|
||||
// Fall through
|
||||
reset_blink_timer:
|
||||
// Rest blink counter
|
||||
// (Compute's Mapping the 64, p39-40)
|
||||
lda #20
|
||||
sta BLNCT
|
||||
no_blink_cursor:
|
||||
rts
|
||||
|
||||
disable_cursor:
|
||||
lda #$80
|
||||
sta BLNSW
|
||||
// FALL THROUGH
|
||||
hide_cursor_if_visible:
|
||||
lda BLNON
|
||||
bne undraw_cursor
|
||||
rts
|
||||
|
||||
enable_cursor:
|
||||
lda #$00
|
||||
sta BLNSW
|
||||
rts
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 229
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y, possibly .A (XXX - see [CM64], page 213)
|
||||
//
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
chkin_real:
|
||||
|
||||
// Store Y for preservation
|
||||
tya
|
||||
pha
|
||||
phy_trash_a
|
||||
|
||||
// Reset status
|
||||
jsr kernalstatus_reset
|
||||
@@ -59,6 +58,7 @@ chkin_set_device:
|
||||
// FALLTROUGH
|
||||
|
||||
// Common part for booth CHKIN and CKOUT
|
||||
// XXX add CPU-dependent optimizations here
|
||||
|
||||
chkinout_end:
|
||||
tax
|
||||
|
||||
+16
-75
@@ -9,6 +9,7 @@
|
||||
//
|
||||
|
||||
// XXX keyboard part currently does not preserve register Y, to be fixed!
|
||||
// XXX try to make chrin_real unnecessary (try to fit this into original location)
|
||||
|
||||
// Reads a byte of input, unless from keyboard.
|
||||
// If from keyboard, then it gets a whole line of input, and returns the first char.
|
||||
@@ -43,8 +44,7 @@ chrin_done_fail:
|
||||
chrin_keyboard:
|
||||
|
||||
// Save X
|
||||
txa
|
||||
pha
|
||||
phx_trash_a
|
||||
|
||||
chrin_repeat:
|
||||
|
||||
@@ -64,8 +64,7 @@ chrin_repeat:
|
||||
// Return carriage return and clear pending input flag
|
||||
lda #$00
|
||||
sta CRSW
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
clc
|
||||
lda #$0d
|
||||
rts
|
||||
@@ -73,33 +72,31 @@ chrin_repeat:
|
||||
not_end_of_input:
|
||||
// Return next byte of waiting input and advance index
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
lda (LXSP),y
|
||||
jsr screen_code_to_petscii
|
||||
inc CRSW
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
read_from_keyboard:
|
||||
|
||||
jsr enable_cursor
|
||||
|
||||
jsr cursor_enable
|
||||
|
||||
// Wait for a key
|
||||
lda NDX
|
||||
beq chrin_repeat
|
||||
|
||||
lda KEYD
|
||||
cmp #$0d
|
||||
cmp #$0D
|
||||
bne not_enter
|
||||
|
||||
jsr disable_cursor
|
||||
|
||||
jsr cursor_disable
|
||||
|
||||
jsr pop_keyboard_buffer
|
||||
|
||||
jsr hide_cursor_if_visible
|
||||
|
||||
jsr cursor_hide_if_visible
|
||||
|
||||
// It was enter.
|
||||
// Note that we have a line of input to return, and return the first byte thereof
|
||||
// after computing and storing its length.
|
||||
@@ -112,7 +109,7 @@ read_from_keyboard:
|
||||
sta LXSP+1
|
||||
|
||||
// Calculate length
|
||||
jsr get_current_line_logical_length
|
||||
jsr screen_get_current_line_logical_length
|
||||
tay
|
||||
iny
|
||||
!: dey
|
||||
@@ -126,8 +123,7 @@ read_from_keyboard:
|
||||
sta CRSW
|
||||
// Return first char of line
|
||||
ldy #$00
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
lda (LXSP),y
|
||||
jsr screen_code_to_petscii
|
||||
clc
|
||||
@@ -137,74 +133,19 @@ empty_line:
|
||||
// For an empty line, just return the carriage return
|
||||
// (and don't forget to actually print the carriage return, so that
|
||||
// the cursor advances and screen scrolls as required)
|
||||
pla
|
||||
tax
|
||||
plx_trash_a
|
||||
clc
|
||||
lda #$0d
|
||||
rts
|
||||
|
||||
not_enter:
|
||||
|
||||
// Print character
|
||||
lda KEYD
|
||||
// XXX add support for SHIFT + RUN/STOP ($84) and function keys (should be configurable)
|
||||
jsr CHROUT
|
||||
|
||||
jsr pop_keyboard_buffer
|
||||
|
||||
// Keep looking for input from keyboard until carriage return
|
||||
jmp chrin_repeat
|
||||
|
||||
pop_keyboard_buffer:
|
||||
// Pop key out of keyboard buffer
|
||||
// Disable interrupts while reading from keyboard buffer
|
||||
// so that no race conditions can occur
|
||||
sei
|
||||
ldx #$00
|
||||
ldy #$01
|
||||
!: lda KEYD,y
|
||||
sta KEYD,x
|
||||
inx
|
||||
iny
|
||||
cpy XMAX
|
||||
bne !-
|
||||
dec NDX
|
||||
cli
|
||||
|
||||
rts
|
||||
|
||||
screen_code_to_petscii:
|
||||
cmp #$1b
|
||||
bcs not_alpha
|
||||
|
||||
clc
|
||||
adc #$40
|
||||
rts
|
||||
|
||||
not_alpha:
|
||||
cmp #$40
|
||||
bcs not_punctuation
|
||||
|
||||
rts
|
||||
|
||||
not_punctuation:
|
||||
cmp #$5b
|
||||
bcs not_shifted
|
||||
|
||||
clc
|
||||
adc #$80
|
||||
|
||||
rts
|
||||
|
||||
not_shifted:
|
||||
|
||||
cmp #$80
|
||||
bcs not_vendor
|
||||
|
||||
// $60-$7F -> $A0-$BF
|
||||
|
||||
clc
|
||||
adc #$40
|
||||
|
||||
// FALLTROUGH
|
||||
not_vendor:
|
||||
rts
|
||||
|
||||
@@ -1,889 +0,0 @@
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 278/279
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||
//
|
||||
|
||||
|
||||
chrout_real:
|
||||
|
||||
sta SCHAR
|
||||
|
||||
// Save X and Y values
|
||||
// (Confirmed by writing a test program that X and Y
|
||||
// don't get modified, in agreement with C64 PRG's
|
||||
// description of CHROUT)
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
php
|
||||
|
||||
// Determine the device number
|
||||
lda DFLTO
|
||||
|
||||
cmp #$03 // screen
|
||||
beq chrout_screen
|
||||
|
||||
jsr iec_check_devnum
|
||||
bcs chrout_done_unknown_device // not a supported device
|
||||
|
||||
chrout_iec:
|
||||
|
||||
lda SCHAR
|
||||
jsr JCIOUT
|
||||
bcc chrout_done
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
chrout_done_fail:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
sec // indicate failure
|
||||
rts
|
||||
|
||||
chrout_done_unknown_device:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
|
||||
// End wioth error
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
chrout_done:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
lda SCHAR
|
||||
clc // indicate success
|
||||
rts
|
||||
|
||||
chrout_screen:
|
||||
|
||||
// Crude implementation of character output
|
||||
sei // XXX why do we need to disable interrupts?
|
||||
|
||||
jsr hide_cursor_if_visible
|
||||
|
||||
lda SCHAR
|
||||
tax
|
||||
|
||||
// Check for special characters
|
||||
|
||||
cmp #$00
|
||||
bne not_00
|
||||
jmp chrout_done
|
||||
not_00:
|
||||
|
||||
// Linefeed (simply ignored)
|
||||
// Trivia: BASIC does CRLF with READY. prompt
|
||||
cmp #$0a
|
||||
bne not_0a
|
||||
jmp chrout_done
|
||||
not_0a:
|
||||
|
||||
// Carriage return
|
||||
cmp #$0d
|
||||
bne not_0d
|
||||
// RETURN clears quote and insert modes
|
||||
lda #$00
|
||||
sta QTSW
|
||||
sta INSRT
|
||||
jmp screen_advance_to_next_line
|
||||
not_0d:
|
||||
|
||||
cmp #$94
|
||||
bne not_94
|
||||
|
||||
// Insert (shift-DELETE)
|
||||
|
||||
// Abort if line already max length, ie 79th char is not a space
|
||||
jsr get_current_line_logical_length
|
||||
cmp #79
|
||||
bne definitely_not_too_long
|
||||
tay
|
||||
lda (PNT),y
|
||||
cmp #$20
|
||||
beq definitely_not_too_long
|
||||
|
||||
// Line is too long to extend
|
||||
jmp chrout_done
|
||||
|
||||
definitely_not_too_long:
|
||||
// Work out if line needs to be expanded, and if so expand it
|
||||
ldy #39
|
||||
lda (PNT),y
|
||||
cmp #$20
|
||||
beq no_need_to_extend
|
||||
|
||||
jsr screen_grow_logical_line
|
||||
|
||||
no_need_to_extend:
|
||||
// Shuffle chars towards end of line
|
||||
jsr get_current_line_logical_length
|
||||
tay
|
||||
!:
|
||||
// Note: While the following routine is obvious to any skilled
|
||||
// in the art as the most obvious simple and efficient solution,
|
||||
// if the screen writes are before the colour writes, it results
|
||||
// in a relatively long verbatim stretch of bytes when compared to
|
||||
// the C64 KERNAL. Thus we have swapped the order, just to reduce
|
||||
// the potential for any argument of copyright infringement, even
|
||||
// though we really don't believe that the routine can be copyrighted
|
||||
// due to the lack of creativity.
|
||||
dey
|
||||
lda (USER),y
|
||||
iny
|
||||
sta (USER),y
|
||||
dey
|
||||
lda (PNT),y
|
||||
iny
|
||||
sta (PNT),y
|
||||
|
||||
dey
|
||||
cpy PNTR
|
||||
bne !-
|
||||
|
||||
// Increase insert mode count (which causes quote-mode like behaviour)
|
||||
inc INSRT
|
||||
|
||||
// Put space in the inserted gap
|
||||
lda #$20
|
||||
sta (PNT),y
|
||||
|
||||
jmp chrout_done
|
||||
not_94:
|
||||
|
||||
// DELETE in insert mode embeds control character
|
||||
ldx INSRT
|
||||
bne not_14
|
||||
|
||||
cmp #$14
|
||||
bne not_14
|
||||
|
||||
// Delete
|
||||
ldx PNTR
|
||||
bne delete_non_zero_column
|
||||
delete_at_column_0:
|
||||
ldy TBLX
|
||||
bne not_row_0
|
||||
// delete from row 0, col 0 does nothing
|
||||
jmp chrout_done
|
||||
not_row_0:
|
||||
// Column 0 delete just moves us to the end of the
|
||||
// previous line, without actually deleting anything
|
||||
dec TBLX
|
||||
jsr get_current_line_logical_length
|
||||
lda LNMX
|
||||
|
||||
sta PNTR
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
|
||||
delete_non_zero_column:
|
||||
// Copy rest of line down
|
||||
jsr get_current_line_logical_length
|
||||
ldy PNTR
|
||||
cpy LNMX
|
||||
beq done_delete
|
||||
dey
|
||||
!:
|
||||
iny
|
||||
lda (PNT),y
|
||||
dey
|
||||
sta (PNT),y
|
||||
iny
|
||||
lda (USER),y
|
||||
dey
|
||||
sta (USER),y
|
||||
iny
|
||||
cpy LNMX
|
||||
bne !-
|
||||
|
||||
// Clear char at end of line
|
||||
jsr get_current_line_logical_length
|
||||
tay
|
||||
lda #$20
|
||||
sta (PNT),y
|
||||
|
||||
done_delete:
|
||||
dec PNTR
|
||||
jmp chrout_done
|
||||
not_14:
|
||||
|
||||
// Check for quote mode
|
||||
ldx QTSW
|
||||
bne is_quote_mode
|
||||
ldx INSRT
|
||||
bne is_quote_mode
|
||||
jmp not_quote_mode
|
||||
|
||||
is_quote_mode:
|
||||
// Is it a control code?
|
||||
// control codes are $00-$1f and $80-$9f
|
||||
// (from reading C64 PRG p379-381)
|
||||
// so we can just check if bits 5 or 6 are set, and if so,
|
||||
// then it isn't a control character.
|
||||
pha
|
||||
and #$60
|
||||
bne !+
|
||||
|
||||
// Yes, a control code in quote mode means we display it as a reverse character
|
||||
pla
|
||||
|
||||
// Low control codes are just +$80
|
||||
clc
|
||||
adc #$80
|
||||
// If it overflowed, then it is a high control code,
|
||||
// so we need to make it be $80 + $40 + char
|
||||
// as we will have flipped back to just $00 + char, we should
|
||||
// now add $c0 if C is set from overflow
|
||||
bcc low_ctrl_char
|
||||
adc #$bf // C=1, so adding $BF + C = add $C0
|
||||
low_ctrl_char:
|
||||
jmp output_literal_char
|
||||
!:
|
||||
pla
|
||||
not_quote_mode:
|
||||
|
||||
// Check for colours
|
||||
ldx #$f
|
||||
colour_check_loop:
|
||||
cmp colour_codes,x
|
||||
bne !+
|
||||
stx COLOR
|
||||
jmp chrout_done
|
||||
!: dex
|
||||
bpl colour_check_loop
|
||||
|
||||
// Compute's Mapping the 64 p38
|
||||
cmp #$12
|
||||
bne not_12
|
||||
lda #$80
|
||||
sta RVS
|
||||
jmp chrout_done
|
||||
not_12:
|
||||
// Compute's Mapping the 64 p 38
|
||||
cmp #$92
|
||||
bne not_92
|
||||
lda #$00
|
||||
sta RVS
|
||||
jmp chrout_done
|
||||
not_92:
|
||||
|
||||
// Check for cursor movement keys
|
||||
cmp #$11
|
||||
bne not_11
|
||||
lda PNTR
|
||||
clc
|
||||
adc #40
|
||||
sta PNTR
|
||||
// We need to advance the pointer manually, as normalising
|
||||
// now will break things. The pointer update is required
|
||||
// so that we can tell if we really are on the bottom phys
|
||||
// screen line or not
|
||||
jsr scroll_up_if_on_last_line
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
not_11:
|
||||
cmp #$1d
|
||||
bne not_1d
|
||||
inc PNTR
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
not_1d:
|
||||
cmp #$91
|
||||
bne not_91
|
||||
lda PNTR
|
||||
sec
|
||||
sbc #40
|
||||
sta PNTR
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
not_91:
|
||||
cmp #$9d
|
||||
bne not_9d
|
||||
dec PNTR
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
not_9d:
|
||||
|
||||
// Home cursor
|
||||
cmp #$13
|
||||
bne not_13
|
||||
lda #0
|
||||
sta PNTR
|
||||
sta TBLX
|
||||
jsr calculate_screen_line_pointer
|
||||
jmp chrout_done
|
||||
not_13:
|
||||
|
||||
// Clear screen
|
||||
cmp #$93
|
||||
bne not_clearscreen
|
||||
jsr clear_screen
|
||||
jmp chrout_done
|
||||
|
||||
not_clearscreen:
|
||||
|
||||
// Convert PETSCII to screen code
|
||||
|
||||
// Don't print other control codes
|
||||
cmp #$1f
|
||||
bcs !+
|
||||
jmp chrout_done
|
||||
!:
|
||||
|
||||
// Codes $C0-$DF become $40-$5F
|
||||
// But
|
||||
cmp #$e0
|
||||
bcs !+
|
||||
cmp #$c0
|
||||
bcc !+
|
||||
|
||||
and #$7f
|
||||
jmp output_literal_char // not high char
|
||||
|
||||
!:
|
||||
// Range $20-$3F is unchanged
|
||||
cmp #$40
|
||||
bcc output_literal_char // not high char
|
||||
|
||||
// Unshifted letters and symbols from $40-$5F
|
||||
// all end up being -$40
|
||||
// (C64 PRG p376)
|
||||
|
||||
// But anything >= $80 needs to be -$40
|
||||
// (C64 PRG p380-381)
|
||||
// And bit 7 should be cleared, only to be
|
||||
// set by reverse video
|
||||
sec
|
||||
sbc #$40
|
||||
|
||||
// Fix shifted chars by adding $20 again
|
||||
cmp #$20
|
||||
bcc output_literal_char // not high char
|
||||
cmp #$40
|
||||
bcs output_literal_char // not high char
|
||||
clc
|
||||
adc #$20
|
||||
|
||||
output_literal_char:
|
||||
|
||||
// Write normal character on the screen
|
||||
|
||||
pha
|
||||
|
||||
ldy PNTR
|
||||
ora RVS // Compute's Mapping the 64 p38
|
||||
sta (PNT),y
|
||||
|
||||
// Decrement number of chars waiting to be inserted
|
||||
lda INSRT
|
||||
beq !+
|
||||
dec INSRT
|
||||
!:
|
||||
pla
|
||||
cmp #$22
|
||||
bne not_quote
|
||||
|
||||
// Toggle quote flag if required
|
||||
lda QTSW
|
||||
eor #$80
|
||||
sta QTSW
|
||||
|
||||
not_quote:
|
||||
|
||||
// Set colour
|
||||
lda COLOR
|
||||
sta (USER),y
|
||||
|
||||
// Advance the column, and scroll screen down if we need
|
||||
// to insert a 2nd line in this logical line.
|
||||
// (eg Compute's Mapping the 64 p41)
|
||||
ldx TBLX
|
||||
iny
|
||||
sty PNTR
|
||||
cpy #40
|
||||
bne !+
|
||||
jsr screen_grow_logical_line
|
||||
ldy PNTR
|
||||
!:
|
||||
cpy #80
|
||||
bcc no_screen_advance_to_next_line
|
||||
lda #0
|
||||
sta PNTR
|
||||
jmp screen_advance_to_next_line
|
||||
no_screen_advance_to_next_line:
|
||||
jmp chrout_done
|
||||
|
||||
screen_grow_logical_line:
|
||||
ldy TBLX
|
||||
// Don't grow line if it is already grown
|
||||
lda LDTBL,y
|
||||
bpl !+
|
||||
jmp not_last_line // doneb grow line
|
||||
!:
|
||||
lda #$80
|
||||
sta LDTBL,y
|
||||
|
||||
// Now make space for the extra line added.
|
||||
// If we are on the last physical line of the screen,
|
||||
// Then we need to scroll the screen up
|
||||
jsr scroll_up_if_on_last_line
|
||||
|
||||
// Scroll screen down to make space
|
||||
// As we are scrolling down, we start from the end,
|
||||
// and work backwards. We can't be as simple and efficient
|
||||
// here as we are for scrolling up, because we don't know
|
||||
// how much must be scrolled.
|
||||
// Simple solution is to work out how many physical lines
|
||||
// need shifting down, and then move lines at a time after
|
||||
// initialising the pointers to the end area of the screen.
|
||||
ldx #25-2
|
||||
ldy #0
|
||||
count_rows_loop:
|
||||
dex
|
||||
lda LDTBL,y
|
||||
bpl !+
|
||||
dex
|
||||
!: iny
|
||||
cpy TBLX
|
||||
bne count_rows_loop
|
||||
|
||||
cpx #0
|
||||
beq no_copy_down
|
||||
bmi no_copy_down
|
||||
|
||||
// Set pointers to end of screen line, and one line
|
||||
// above. (It is always one physical line, because
|
||||
// this can only happen when expanding a line from 40 to
|
||||
// 80 characters).
|
||||
// XXX - This is not very efficient, and longer than it
|
||||
// needs to be. Better would be to work out size to
|
||||
// copy, and count it down in a pointer somewhere, so
|
||||
// that loop iteration logic is simpler.
|
||||
lda HIBASE
|
||||
clc
|
||||
adc #3
|
||||
sta PNT+1
|
||||
sta SAL+1
|
||||
lda #>$DBC0
|
||||
sta EAL+1
|
||||
sta USER+1
|
||||
|
||||
lda #<$03C0
|
||||
sta PNT+0
|
||||
sta USER+0
|
||||
// souce address is line above
|
||||
sec
|
||||
sbc #40
|
||||
sta SAL+0
|
||||
sta EAL+0
|
||||
|
||||
copy_line_down_loop:
|
||||
ldy #39
|
||||
cl_inner:
|
||||
lda (EAL),y
|
||||
sta (USER),y
|
||||
lda (SAL),y
|
||||
sta (PNT),y
|
||||
dey
|
||||
bpl cl_inner
|
||||
|
||||
// Decrement all pointers by 40
|
||||
// Low bytes are in common pairs
|
||||
|
||||
// Old source is new destination
|
||||
// Use different registers to minimise byte similarity with C64 KERNAl
|
||||
ldy SAL+1
|
||||
sty PNT+1
|
||||
lda EAL+1
|
||||
ldy SAL+0
|
||||
sta USER+1
|
||||
sty PNT+0
|
||||
sty USER+0
|
||||
|
||||
// Decrementing source pointers
|
||||
lda SAL+0
|
||||
sec
|
||||
sbc #<40
|
||||
sta SAL+0
|
||||
sta EAL+0
|
||||
lda SAL+1
|
||||
sbc #>40
|
||||
sta SAL+1
|
||||
// convert to screen equivalent
|
||||
sec
|
||||
sbc HIBASE
|
||||
clc
|
||||
adc #>$D800
|
||||
sta EAL+1
|
||||
|
||||
dex
|
||||
bne copy_line_down_loop
|
||||
|
||||
no_copy_down:
|
||||
jsr calculate_screen_line_pointer
|
||||
|
||||
// Erase newly inserted line
|
||||
ldy #79
|
||||
!:
|
||||
lda COLOR
|
||||
sta (USER),y
|
||||
lda #$20
|
||||
sta (PNT),y
|
||||
dey
|
||||
cpy #40
|
||||
bne !-
|
||||
|
||||
rts
|
||||
|
||||
not_last_line:
|
||||
rts
|
||||
|
||||
scroll_up_if_on_last_line:
|
||||
|
||||
// Colour RAM is always in fixed place, so is easiest
|
||||
// to use to check if we are on the last line.
|
||||
// The last line is at $D800 + 24*40 = $DBC0
|
||||
lda USER+1
|
||||
cmp #>$DBC0
|
||||
bne not_last_line
|
||||
|
||||
lda USER+0
|
||||
cmp #<$DBC0
|
||||
beq is_last_line
|
||||
|
||||
jsr get_current_line_logical_length
|
||||
clc
|
||||
adc USER+0
|
||||
cmp #<$DBE7-1
|
||||
bcc not_last_line
|
||||
|
||||
is_last_line:
|
||||
|
||||
dec TBLX
|
||||
|
||||
// FALL THROUGH
|
||||
|
||||
scroll_screen_up:
|
||||
// Now scroll the whole screen up either one or two lines
|
||||
// based on whether the first screen line is linked or not.
|
||||
|
||||
// Get pointers to start of screen + colour RAM
|
||||
lda HIBASE
|
||||
sta PNT+1
|
||||
sta SAL+1
|
||||
lda #>$D800
|
||||
sta USER+1
|
||||
sta EAL+1
|
||||
lda #$00
|
||||
sta PNT+0
|
||||
sta USER+0
|
||||
|
||||
// Get pointers to screen/colour RAM source
|
||||
lda LDTBL+0
|
||||
bmi !+
|
||||
lda #40
|
||||
.byte $2C // BIT $nnnn to skip next instruction
|
||||
!:
|
||||
lda #80
|
||||
sta SAL+0
|
||||
sta EAL+0
|
||||
|
||||
// Copy first three pages
|
||||
ldy #$00
|
||||
ldx #3
|
||||
scroll_copy_loop:
|
||||
lda (EAL),y
|
||||
sta (USER),y
|
||||
lda (SAL),y
|
||||
sta (PNT),y
|
||||
|
||||
iny
|
||||
bne scroll_copy_loop
|
||||
|
||||
inc SAL+1
|
||||
inc PNT+1
|
||||
inc EAL+1
|
||||
inc USER+1
|
||||
dex
|
||||
bne scroll_copy_loop
|
||||
|
||||
// Copy last partial page
|
||||
// We need to copy 1000-(3*256)-line length
|
||||
// = 232 - line length
|
||||
lda SAL+0
|
||||
lda #232
|
||||
sec
|
||||
sbc SAL+0
|
||||
tax
|
||||
scroll_copy_loop2:
|
||||
lda (EAL),y
|
||||
sta (USER),y
|
||||
lda (SAL),y
|
||||
sta (PNT),y
|
||||
iny
|
||||
dex
|
||||
bne scroll_copy_loop2
|
||||
|
||||
// Fill in scrolled up area
|
||||
ldx SAL+0
|
||||
scroll_copy_loop3:
|
||||
lda COLOR
|
||||
sta (USER),y
|
||||
lda #$20
|
||||
sta (PNT),y
|
||||
iny
|
||||
dex
|
||||
bne scroll_copy_loop3
|
||||
|
||||
// Shift line linkage list
|
||||
ldy #0
|
||||
ldx #24
|
||||
link_copy:
|
||||
lda LDTBL+1,y
|
||||
sta LDTBL+0,y
|
||||
iny
|
||||
dex
|
||||
bne link_copy
|
||||
// Clear line link flag of last line
|
||||
stx LDTBL+24
|
||||
|
||||
// Restore correct line pointers
|
||||
jsr calculate_screen_line_pointer
|
||||
|
||||
rts
|
||||
|
||||
get_current_line_logical_length:
|
||||
ldy TBLX
|
||||
lda LDTBL,y
|
||||
bpl line_not_linked_del
|
||||
lda #79
|
||||
.byte $2c // BIT absolute mode, which we use to skip the next two instruction bytes
|
||||
line_not_linked_del:
|
||||
lda #39
|
||||
sta LNMX
|
||||
rts
|
||||
|
||||
screen_advance_to_next_line:
|
||||
|
||||
// jsr hide_cursor_if_visible
|
||||
|
||||
// Go to start of line
|
||||
lda #0
|
||||
sta PNTR
|
||||
// Advance line number
|
||||
ldy TBLX
|
||||
|
||||
// Do quick fix to line pointer to work out if it is off
|
||||
// the bottom of the screen.
|
||||
ldx #40
|
||||
lda LDTBL,y
|
||||
bmi !+
|
||||
.byte $2c
|
||||
!: ldx #80
|
||||
txa
|
||||
clc
|
||||
adc PNT+0
|
||||
sta PNT+0
|
||||
lda PNT+1
|
||||
adc #0
|
||||
sta PNT+1
|
||||
|
||||
inc TBLX
|
||||
|
||||
// Check if it will trigger scrolling
|
||||
// Work out if we have gone off the bottom of the screen?
|
||||
// 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4),
|
||||
// then we are off the bottom of the screen
|
||||
lda PNT+1
|
||||
sec
|
||||
sbc HIBASE
|
||||
cmp #3
|
||||
bcc !+
|
||||
lda PNT+0
|
||||
cmp #$e7
|
||||
bcc !+
|
||||
|
||||
// Off the bottom of the screen
|
||||
jsr scroll_screen_up
|
||||
!:
|
||||
|
||||
jsr calculate_screen_line_pointer
|
||||
|
||||
jmp chrout_done
|
||||
|
||||
add_40_to_screen_x:
|
||||
lda PNTR
|
||||
clc
|
||||
adc #40
|
||||
sta PNTR
|
||||
rts
|
||||
|
||||
normalise_screen_x_y:
|
||||
// Normalise X and Y values
|
||||
|
||||
// If X < 0, then make X = X + 40 (or 80, if previous line is linked)
|
||||
!: lda PNTR
|
||||
bpl x_not_negative
|
||||
dec TBLX
|
||||
// Check that we didn't go backwards off the top of the screen
|
||||
bpl !+
|
||||
lda #0
|
||||
sta TBLX
|
||||
|
||||
!: jsr add_40_to_screen_x
|
||||
|
||||
// Check if line is linked, if so, add 40 again
|
||||
ldy TBLX
|
||||
lda LDTBL,y
|
||||
bpl !+
|
||||
jsr add_40_to_screen_x
|
||||
!:
|
||||
|
||||
x_not_negative:
|
||||
// Work out if X is too big
|
||||
ldy TBLX
|
||||
lda LDTBL,y
|
||||
bpl !+
|
||||
lda #79
|
||||
.byte $2C // BIT $nnnn, used to skip next instruction
|
||||
!: lda #39
|
||||
cmp PNTR
|
||||
bcs x_not_too_big
|
||||
|
||||
// X value is too big, so subtract 40 and increment Y
|
||||
lda PNTR
|
||||
sec
|
||||
sbc #40
|
||||
sta PNTR
|
||||
inc TBLX
|
||||
|
||||
x_not_too_big:
|
||||
|
||||
// Make sure Y isn't negative
|
||||
lda TBLX
|
||||
bpl !+
|
||||
lda #0
|
||||
sta TBLX
|
||||
!:
|
||||
// Make sure Y isn't too large for absolute size of
|
||||
// screen
|
||||
cmp #24
|
||||
bcc !+
|
||||
lda #24
|
||||
sta TBLX
|
||||
!:
|
||||
// Make sure Y isn't too much for the screen, taking
|
||||
// into account the line link table
|
||||
ldy #24 // max allowable line
|
||||
ldx #0
|
||||
link_count_loop:
|
||||
lda LDTBL,x
|
||||
bpl !+
|
||||
dey
|
||||
!: inx
|
||||
cpx #25
|
||||
bne link_count_loop
|
||||
tya
|
||||
cmp TBLX
|
||||
bcs y_ok
|
||||
sta TBLX
|
||||
y_ok:
|
||||
rts
|
||||
|
||||
calculate_screen_line_pointer:
|
||||
jsr normalise_screen_x_y
|
||||
|
||||
// Reset pointer to start of screen
|
||||
lda HIBASE
|
||||
sta PNT+1
|
||||
lda #0
|
||||
sta PNT+0
|
||||
|
||||
// Add 40 for every line, or 80 if the lines are linked
|
||||
ldx TBLX
|
||||
|
||||
!:
|
||||
// Stop if we have counted enough lines
|
||||
beq !+
|
||||
|
||||
// Add 40 or 80 based on whether the line is linked
|
||||
// or not.
|
||||
ldy #40
|
||||
// -1 offset is because we count down from N to 1, not
|
||||
// N-1 to 0.
|
||||
lda LDTBL-1,x
|
||||
bpl cslp_l1
|
||||
ldy #80
|
||||
cslp_l1:
|
||||
// Add computed line length to pointer value
|
||||
tya
|
||||
clc
|
||||
adc PNT+0
|
||||
sta PNT+0
|
||||
lda PNT+1
|
||||
adc #0
|
||||
sta PNT+1
|
||||
|
||||
// Loop back to next line
|
||||
dex
|
||||
jmp !-
|
||||
!:
|
||||
|
||||
// FALL THROUGH
|
||||
|
||||
update_colour_line_pointer:
|
||||
// Now setup pointer to colour RAM
|
||||
lda PNT+0
|
||||
sta USER+0
|
||||
lda PNT+1
|
||||
sec
|
||||
sbc HIBASE
|
||||
clc
|
||||
adc #>$d800
|
||||
sta USER+1
|
||||
|
||||
rts
|
||||
|
||||
advance_screen_pointer_40_bytes:
|
||||
lda PNT+0
|
||||
clc
|
||||
adc #<40
|
||||
sta PNT+0
|
||||
sta USER+0
|
||||
lda PNT+1
|
||||
adc #>40
|
||||
sta PNT+1
|
||||
sec
|
||||
sbc HIBASE
|
||||
clc
|
||||
adc #>$D800
|
||||
sta USER+1
|
||||
|
||||
jmp update_colour_line_pointer
|
||||
@@ -1,105 +0,0 @@
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 280
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 242
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
|
||||
cint_real:
|
||||
|
||||
// According to [CM64], this routine checks for PAL/NTSC. It's definitely not done
|
||||
// within the 'BRK' part, this can be easily checked - POKE something
|
||||
// to address 678 on a real C64, press STOP+RESTORE, the value won't change
|
||||
|
||||
// Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable
|
||||
// see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc
|
||||
|
||||
lda #$C8 // preparation, as the VIC might be uninitialized
|
||||
sta VIC_SCROLX
|
||||
|
||||
cint_w0:
|
||||
lda VIC_RASTER
|
||||
cint_w1:
|
||||
cmp VIC_RASTER
|
||||
beq cint_w1
|
||||
bmi cint_w0
|
||||
|
||||
// Result in A, if no interrupt happened during the test:
|
||||
// #$37 -> 312 rasterlines, PAL, VIC 6569
|
||||
// #$06 -> 263 rasterlines, NTSC, VIC 6567R8
|
||||
// #$05 -> 262 rasterlines, NTSC, VIC 6567R56A
|
||||
|
||||
cmp #$07
|
||||
bcs cint_pal
|
||||
|
||||
cint_ntsc:
|
||||
|
||||
// NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
// is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles
|
||||
|
||||
ldy #<17045
|
||||
ldx #>17045
|
||||
|
||||
sty CIA1_TIMALO
|
||||
stx CIA1_TIMAHI
|
||||
|
||||
lda #$00
|
||||
beq !+
|
||||
|
||||
cint_pal:
|
||||
|
||||
lda #$01
|
||||
!:
|
||||
sta TVSFLG
|
||||
|
||||
// Setup KEYLOG vector - XXX is it proper place?
|
||||
|
||||
lda #<setup_keydecode
|
||||
sta KEYLOG+0
|
||||
lda #>setup_keydecode
|
||||
sta KEYLOG+1
|
||||
|
||||
cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start?
|
||||
|
||||
jsr setup_vicii
|
||||
|
||||
// Initialise cursor blink flags (Compute's Mapping the 64 p215)
|
||||
lda #$00
|
||||
sta BLNSW
|
||||
|
||||
// Set keyboard decode vector (Compute's Mapping the 64 p215)
|
||||
|
||||
// Set initial variables for our improved keyboard scan routine
|
||||
lda #$FF
|
||||
ldx #6
|
||||
!: sta BufferOld,x
|
||||
dex
|
||||
bpl !-
|
||||
sta BufferQuantity
|
||||
|
||||
// Set key repeat delay (Compute's Mapping the 64 p215)
|
||||
// Making some numbers up here: Repeat every ~1/10th sec
|
||||
// But require key to be held for ~1/3sec before
|
||||
// repeating (Compute's Mapping the 64 p58)
|
||||
ldx #22-2 // Fudge factor to match speed
|
||||
stx DELAY
|
||||
|
||||
// Set current colour for text (Compute's Mapping the 64 p215)
|
||||
ldx #$01 // default is light blue ($0E), but we use a different one
|
||||
stx COLOR
|
||||
|
||||
// Set maximum keyboard buffer size (Compute's Mapping the 64 p215)
|
||||
ldx #10
|
||||
stx XMAX
|
||||
// Put non-zero value in MODE to enable case switch
|
||||
stx MODE
|
||||
|
||||
// Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html)
|
||||
jsr clrchn_reset
|
||||
|
||||
// Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215)
|
||||
jmp clear_screen
|
||||
@@ -25,7 +25,7 @@ clrchn_real:
|
||||
// Handle IEC output device
|
||||
jsr UNLSN
|
||||
!:
|
||||
clrchn_reset: // entry needed by CHRIN
|
||||
clrchn_reset: // entry needed by setup_vicii
|
||||
// Set input device number to keyboard
|
||||
lda #$00
|
||||
sta DFLTN
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
setup_vicii:
|
||||
|
||||
// XXX there is more to setup within this routine
|
||||
|
||||
// Set up default IO values (Compute's Mapping the 64 p215)
|
||||
lda #$1B // Enable text mode
|
||||
sta VIC_SCROLY
|
||||
lda #$C8 // 40 column etc
|
||||
sta VIC_SCROLX
|
||||
|
||||
// Compute's Mapping the 64, p156
|
||||
// We use a different colour scheme of white text on all blue
|
||||
lda #$06
|
||||
sta VIC_EXTCOL
|
||||
sta VIC_BGCOL0
|
||||
|
||||
// Turn off sprites (observed hanging around after running programs and resetting)
|
||||
lda #$00
|
||||
sta VIC_SPENA
|
||||
|
||||
rts
|
||||
+2
-19
@@ -8,26 +8,9 @@
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
// XXX currently does not preserve registers, to be fixed!
|
||||
|
||||
GETIN:
|
||||
|
||||
// Wait for a key
|
||||
lda NDX
|
||||
bne !+
|
||||
// XXX this should be a dispatcher for several different devices!
|
||||
|
||||
// Nothing in keyboard buffer to read
|
||||
sec
|
||||
lda #$00
|
||||
rts
|
||||
|
||||
!:
|
||||
lda KEYD
|
||||
pha
|
||||
|
||||
jsr pop_keyboard_buffer
|
||||
|
||||
pla
|
||||
clc
|
||||
|
||||
rts
|
||||
jmp read_kb_buf
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with CHKIN
|
||||
|
||||
CHROUT:
|
||||
jmp chrout_real
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 278/279
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||
//
|
||||
|
||||
CHROUT:
|
||||
|
||||
sta SCHAR
|
||||
|
||||
// Save X and Y values
|
||||
// (Confirmed by writing a test program that X and Y
|
||||
// don't get modified, in agreement with C64 PRG's
|
||||
// description of CHROUT)
|
||||
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
php
|
||||
|
||||
// Determine the device number
|
||||
lda DFLTO
|
||||
|
||||
cmp #$03 // screen
|
||||
bne !+
|
||||
jmp chrout_screen
|
||||
!:
|
||||
jsr iec_check_devnum
|
||||
bcs chrout_done_unknown_device // not a supported device
|
||||
|
||||
chrout_iec:
|
||||
|
||||
lda SCHAR
|
||||
jsr JCIOUT
|
||||
bcc chrout_done_success
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
chrout_done_fail:
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
|
||||
sec // indicate failure
|
||||
rts
|
||||
|
||||
chrout_done_unknown_device:
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
|
||||
// End wioth error
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
chrout_done_success:
|
||||
|
||||
plp
|
||||
|
||||
// Restore X and Y
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
|
||||
lda SCHAR
|
||||
clc // indicate success
|
||||
rts
|
||||
@@ -36,9 +36,6 @@ LOAD:
|
||||
jsr install_ram_routines
|
||||
#endif
|
||||
|
||||
// Allow platform-specific routine to takeover the flow
|
||||
TARGET_HOOK_LOAD()
|
||||
|
||||
// Check whether we support the requested device
|
||||
lda FA
|
||||
and #$FC
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
Address adjusted to support $FE2D - routine which is probably used by many cartridges and other software to initialize parts of the system. At least the UCart uses it - see here:
|
||||
- https://www.elektroda.pl/rtvforum/topic3293027.html
|
||||
@@ -14,9 +14,10 @@ MEMTOP:
|
||||
|
||||
ldy MEMSIZK+1
|
||||
ldx MEMSIZK+0
|
||||
rts
|
||||
|
||||
memtop_set:
|
||||
// FALLTROUGH
|
||||
|
||||
memtop_set: // for compatibility reasons this has to start at $FE2D
|
||||
|
||||
sty MEMSIZK+1
|
||||
stx MEMSIZK+0
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with OPEN
|
||||
|
||||
CINT:
|
||||
jmp cint_real
|
||||
@@ -1,10 +0,0 @@
|
||||
// Home the cursor
|
||||
// (Compute's Mapping the 64 p216)
|
||||
|
||||
home_cursor:
|
||||
|
||||
lda #$00
|
||||
sta PNTR // x position
|
||||
sta TBLX // y position
|
||||
|
||||
jmp set_pointer_to_current_screen_line
|
||||
File renamed without changes.
@@ -14,10 +14,8 @@ iec_return_success:
|
||||
lda #$00
|
||||
sta C3PO
|
||||
// Restore registers
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
// Report success
|
||||
clc
|
||||
rts
|
||||
@@ -30,9 +28,7 @@ iec_return_DEVICE_NOT_FOUND:
|
||||
lda #$00
|
||||
sta C3PO
|
||||
// Restore registers
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
// Report error
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user