aboutsummaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2022-09-16 07:34:44 +0100
committerJuan J. Martinez <jjm@usebox.net>2022-09-16 12:05:09 +0100
commit1ef0d697a62eff28115d6642c850ba4d01ef6a89 (patch)
tree23d7fdb24453a3a1378f81d021567616492bbdbd /game
parent290c74b70661bcde314f73fde2be888e5aed47e0 (diff)
downloadubox-msx-lib-1ef0d697a62eff28115d6642c850ba4d01ef6a89.tar.gz
ubox-msx-lib-1ef0d697a62eff28115d6642c850ba4d01ef6a89.zip
Added CAS support to the example game
Diffstat (limited to 'game')
-rw-r--r--game/Makefile5
-rw-r--r--game/data/loading.pngbin0 -> 8188 bytes
-rw-r--r--game/src/Makefile26
-rw-r--r--game/src/cas/loader.bas1
-rw-r--r--game/src/cas/loader.z80219
-rw-r--r--game/src/crt0.z80115
6 files changed, 309 insertions, 57 deletions
diff --git a/game/Makefile b/game/Makefile
index 3fe43f3..347d37b 100644
--- a/game/Makefile
+++ b/game/Makefile
@@ -6,6 +6,9 @@ all: generated bin build
cd src && ../../tools/mkdeps.py -b ../build -I ../generated:../../include ./ Makefile.deps
make -C src all
+cas: all
+ make -C src cas
+
generated:
mkdir -p ./generated
@@ -18,7 +21,7 @@ build:
openmsx: all
make -C src openmsx
-.PHONY: all clean default
+.PHONY: all cas clean default
clean:
rm -rf ./generated ./bin ./build
make -C src clean
diff --git a/game/data/loading.png b/game/data/loading.png
new file mode 100644
index 0000000..ce196ef
--- /dev/null
+++ b/game/data/loading.png
Binary files differ
diff --git a/game/src/Makefile b/game/src/Makefile
index b05ef4e..3ca267a 100644
--- a/game/src/Makefile
+++ b/game/src/Makefile
@@ -32,6 +32,9 @@ all: $(TMPDIR)/$(TARGET).rom
@$(CHKSIZE) $(ROM_MAX) 4000 $(TMPDIR)/$(TARGET).map
@cp $(TMPDIR)/$(TARGET).rom $(OUTDIR)
+cas: $(TMPDIR)/$(TARGET).cas
+ @cp $(TMPDIR)/$(TARGET).cas $(OUTDIR)
+
openmsx: all
openmsx -carta $(OUTDIR)/$(TARGET).rom -machine msx1
@@ -51,10 +54,31 @@ $(TMPDIR)/$(TARGET).rom: $(OBJS) $(TMPDIR)/crt0.rel $(UBOX_LIBS)
hex2bin -e bin -p 00 -l $(ROM_MAX) $(TMPDIR)/$(TARGET).ihx
@cp $(TMPDIR)/$(TARGET).bin $(TMPDIR)/$(TARGET).rom
+LOADER_ADDR=0xe000
+LOADER_WORK_ADDR=0x8000
+$(TMPDIR)/$(TARGET).cas: $(TMPDIR)/$(TARGET).rom cas/loader.bas $(TMPDIR)/loader.bin $(TMPDIR)/loading.ap
+ apultra -v $(TMPDIR)/$(TARGET).rom $(TMPDIR)/$(TARGET).ap
+ ../../tools/mkcas.py --name $(TARGET) $@ ascii cas/loader.bas
+ ../../tools/mkcas.py -a --name loader --addr $(LOADER_ADDR) --exec $(LOADER_ADDR) $@ binary $(TMPDIR)/loader.bin
+ ../../tools/mkcas.py -a --addr $(LOADER_WORK_ADDR) $@ custom-header $(TMPDIR)/loading.ap
+ ../../tools/mkcas.py -a --addr $(LOADER_WORK_ADDR) $@ custom-header $(TMPDIR)/$(TARGET).ap
+
+$(TMPDIR)/loader.bin: $(TMPDIR)/loader.rel
+ $(CC) $(CFLAGS) $(LDFLAGS) --code-loc $(LOADER_ADDR) --data-loc 0 -lap $< -o $(TMPDIR)/loader.ihx
+ hex2bin -p 00 $(TMPDIR)/loader.ihx
+
+$(TMPDIR)/loading.ap: ../data/loading.png
+ ../../tools/png2scr.py ../data/loading.png > $(TMPDIR)/loading.bin
+ apultra -v $(TMPDIR)/loading.bin $(TMPDIR)/loading.ap
+
+$(TMPDIR)/loader.rel: cas/loader.z80
+ $(AS) -g -o $@ $<
+
clean:
rm -f $(TMPDIR)/*
rm -f $(OUTDIR)/$(TARGET).rom
+ rm -f $(OUTDIR)/$(TARGET).cas
-.PHONY: all clean
+.PHONY: all cas clean
include Makefile.deps
diff --git a/game/src/cas/loader.bas b/game/src/cas/loader.bas
new file mode 100644
index 0000000..c94a478
--- /dev/null
+++ b/game/src/cas/loader.bas
@@ -0,0 +1 @@
+10 BLOAD"cas:",R
diff --git a/game/src/cas/loader.z80 b/game/src/cas/loader.z80
new file mode 100644
index 0000000..d7b058c
--- /dev/null
+++ b/game/src/cas/loader.z80
@@ -0,0 +1,219 @@
+;
+; TAPE LOADER USING THE BIOS
+;
+
+TAPION = 0x00e1
+TAPIN = 0x00e4
+TAPIOF = 0x00e7
+DISSCR = 0x0041
+ENASCR = 0x0044
+LDIRVM = 0x005c
+CHGMOD = 0x005f
+CHGCLR = 0x0062
+FORCLR = 0xf3e9
+BAKCLR = 0xf3ea
+BDRCLR = 0xf3eb
+CHPUT = 0x00a2
+TOTEXT = 0x00d2
+ENASLT = 0x0024
+RSLREG = 0x0138
+
+ .area _CODE
+ di
+ ; init the stack
+ ld sp, #0xf380
+
+ ; sslot fix
+ ld a, (0xffff)
+ cpl
+ and #0xf0
+ ld c, a
+ rrca
+ rrca
+ rrca
+ rrca
+ or c
+ ld (0xffff),a
+
+ in a, (#0xa8)
+
+ ; map RAM on 0x8000
+ and #0xcf
+ ld c, #16
+ ld hl, #0x8000
+ call select_ram
+
+ ; map RAM on 0x4000
+ and #0xf3
+ ld c, #4
+ ld hl, #0x4000
+ call select_ram
+
+ ei
+
+ ; now we have: ROM RAM RAM RAM
+
+ ; set these to black
+ ld a, #1
+ ld (FORCLR), a
+ ld (BAKCLR), a
+ ld (BDRCLR), a
+ call CHGCLR
+
+ ; load the loading screen
+ call load_custom_block
+
+ ld hl, (block_addr)
+ ld de, #0x4000
+ call ap_uncompress
+
+ call upload_screen
+
+ ; load the code
+ call load_custom_block
+
+ ld hl, (block_addr)
+ ld de, #0x4000
+ call ap_uncompress
+
+ ; cas main
+ jp 0x4010
+
+upload_screen:
+ ld a, #2
+ call CHGMOD
+
+ call DISSCR
+
+ ld hl, #0x4000
+ ld de, #0
+ ld bc, #256 * 8
+ call LDIRVM
+
+ ld hl, #0x4000 + 256 * 8
+ ld de, #256 * 8
+ ld bc, #256 * 8
+ call LDIRVM
+
+ ld hl, #0x4000 + 256 * 8 * 2
+ ld de, #256 * 8 * 2
+ ld bc, #256 * 8
+ call LDIRVM
+
+ ld hl, #0x4000 + 256 * 8 * 3
+ ld de, #0x2000
+ ld bc, #256 * 8
+ call LDIRVM
+
+ ld hl, #0x4000 + 256 * 8 * 4
+ ld de, #0x2000 + 256 * 8
+ ld bc, #256 * 8
+ call LDIRVM
+
+ ld hl, #0x4000 + 256 * 8 * 5
+ ld de, #0x2000 + 256 * 8 * 2
+ ld bc, #256 * 8
+ call LDIRVM
+
+ jp ENASCR
+
+load_custom_block:
+ call TAPION
+ jp c, tape_error
+
+ ld bc, #4
+ ld hl, #block_addr
+ call load_block
+
+ ld bc, (block_len)
+ ld hl, (block_addr)
+ call load_block
+
+ jp TAPIOF
+
+load_block:
+ ld a, r
+ and #15
+ out (#0x99), a
+ ld a, #0x87
+ nop
+ nop
+ out (#0x99), a
+
+ push bc
+ push hl
+ call TAPIN
+ pop hl
+ pop bc
+ jr c, tape_error
+
+ ld (hl), a
+ inc hl
+
+ dec bc
+ ld a, b
+ or c
+ jr nz, load_block
+
+ ld a, #1
+ out (#0x99), a
+ ld a, #0x87
+ nop
+ nop
+ out (#0x99), a
+ ret
+
+select_ram:
+ ld b, #4
+select_ram_loop:
+ out (#0xa8), a
+ ld (hl), a
+ cp (hl)
+ ret z
+ add a, c
+ djnz select_ram_loop
+
+memory_error:
+ ld hl, #mem_err_message
+ jp display_error
+
+tape_error:
+ ld hl, #tape_err_message
+
+display_error:
+ push hl
+ call TOTEXT
+
+ ld a, #1
+ ld (BAKCLR), a
+ ld (BDRCLR), a
+ ld a, #6
+ ld (FORCLR), a
+ call CHGCLR
+
+ pop hl
+print_loop:
+ ld a, (hl)
+ or a
+ jr z, halt0
+ inc hl
+ call CHPUT
+ jr print_loop
+halt0:
+ halt
+ jr halt0
+
+tape_err_message:
+ .str "TAPE READ ERROR"
+ .db 0
+mem_err_message:
+ .str "MEMORY INIT ERROR"
+ .db 0
+
+ .area _DATA
+
+block_addr:
+ .dw 2
+block_len:
+ .dw 2
+
diff --git a/game/src/crt0.z80 b/game/src/crt0.z80
index 81763d0..c8bd167 100644
--- a/game/src/crt0.z80
+++ b/game/src/crt0.z80
@@ -1,82 +1,87 @@
.module crt0
-.globl _main
-.area _HOME
-.area _CODE
-.area _INITIALIZER
+.globl _main
+
+.area _HOME
+.area _CODE
+.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
-.area _DATA
-.area _INITIALIZED
-.area _BSEG
+.area _DATA
+.area _INITIALIZED
+.area _BSEG
.area _BSS
.area _HEAP
-.area _CODE
-
ENASLT = 0x0024
RSLREG = 0x0138
CLIKSW = 0xf3db
- ; ROM header
- .str "AB"
- .dw _main_init
- .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.area _CODE
+ ; ROM header
+ .str "AB"
+ .dw _main_init
+ .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+ ; entry point skipping the init code that is used
+ ; when starting from cassette
+ jp _cas_main
_main_init::
- ; init the stack
- di
- ld sp, #0xf380
- ei
+ ; init the stack
+ di
+ ld sp, #0xf380
+ ei
- ; setup memory
- ; ref: https://www.msx.org/forum/msx-talk/development/memory-pages-again
+ ; setup memory
+ ; ref: https://www.msx.org/forum/msx-talk/development/memory-pages-again
- call RSLREG
- rrca
- rrca
- and #3
- ld c, a
- add a, #0xc1
- ld l, a
- ld h, #0xfc
- ld a, (hl)
- and #0x80
- or c
- ld c, a
- inc l
- inc l
- inc l
- inc l
- ld a, (hl)
- and #0x0c
- or c
- ld h, #0x80
- call ENASLT
+ call RSLREG
+ rrca
+ rrca
+ and #3
+ ld c, a
+ add a, #0xc1
+ ld l, a
+ ld h, #0xfc
+ ld a, (hl)
+ and #0x80
+ or c
+ ld c, a
+ inc l
+ inc l
+ inc l
+ inc l
+ ld a, (hl)
+ and #0x0c
+ or c
+ ld h, #0x80
+ call ENASLT
- ; disable key click sound
- xor a
- ld (CLIKSW), a
+_cas_main::
+ ; disable key click sound
+ xor a
+ ld (CLIKSW), a
- call gsinit
- call _main
+ call gsinit
+ call _main
halt0:
- halt
- jr halt0
+ halt
+ jr halt0
.area _GSINIT
gsinit::
- ld bc, #l__INITIALIZER
- ld a, b
- or a, c
- jr Z, gsinit_next
- ld de, #s__INITIALIZED
- ld hl, #s__INITIALIZER
- ldir
+ ld bc, #l__INITIALIZER
+ ld a, b
+ or a, c
+ jr Z, gsinit_next
+ ld de, #s__INITIALIZED
+ ld hl, #s__INITIALIZER
+ ldir
gsinit_next:
.area _GSFINAL
- ret
+ ret