Compare commits

...

7 commits

Author SHA1 Message Date
hkz
4fd200b7b7 Squashed commit of the following:
commit ce479dacb9
Author: hkz <tabaglio@posteo.net>
Date:   Fri Oct 17 09:31:15 2025 +0200

    Update README and CHANGELOG

commit 6840e57190
Author: hkz <tabaglio@posteo.net>
Date:   Wed Oct 15 13:25:23 2025 +0200

    Rework graphics

commit 0f0fe3ecb7
Author: hkz <tabaglio@posteo.net>
Date:   Wed Oct 15 13:10:55 2025 +0200

    Rework graphics

commit f258d81f73
Author: hkz <tabaglio@posteo.net>
Date:   Wed Oct 15 12:54:29 2025 +0200

    Rework colors

commit 631097903b
Author: hkz <tabaglio@posteo.net>
Date:   Wed Oct 15 09:24:59 2025 +0200

    Centralize versioning

commit 3219687fd7
Author: hkz <tabaglio@posteo.net>
Date:   Wed Oct 15 07:38:55 2025 +0200

    move some definitions outside of utility.h

commit 07d054ea51
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 14 14:03:24 2025 +0200

    Tweak some initialization code

commit d920f68139
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 14 11:04:53 2025 +0200

    Reworked wait time before making a move in demo mode

commit a3425993b1
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 14 08:57:48 2025 +0200

    Tweak strings to indicate DEMO mode

commit 46f3662322
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 14 08:39:41 2025 +0200

    Rewritten the irq handler

commit 2999c7c218
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 21:10:54 2025 +0200

    fix saving

commit e7a5006a4a
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 21:00:29 2025 +0200

    nitial working version for the VDP

commit 735513e5c8
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 19:36:20 2025 +0200

    Fix game mode

commit 76fed16432
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 18:59:02 2025 +0200

    Re-enable partial drawing

commit f5cfc0f5da
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 18:46:08 2025 +0200

    Use signed arithmetics for game logic

commit 5348adcd72
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 17:53:49 2025 +0200

    Enable tiles redrawing

commit 31018463ad
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 17:48:52 2025 +0200

    Fix joystick code

commit 7c4385972d
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 17:24:13 2025 +0200

    Begin fixing game code

commit 78604e6f7d
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 16:24:29 2025 +0200

    Begin writing code to update the tiles

commit 26e94d2957
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 11:43:41 2025 +0200

    Begin wiring in the VDP code in the game module

commit 28a1fbfc18
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 10:09:43 2025 +0200

    Implement (untested) code to draw joystick

commit d3d2207b4f
Author: hkz <tabaglio@posteo.net>
Date:   Mon Oct 13 08:44:00 2025 +0200

    Add dummy demo and game modules for VDP

commit 5deb0d802f
Author: hkz <tabaglio@posteo.net>
Date:   Sun Oct 12 21:27:15 2025 +0200

    Update the charset

commit d2cd7356ec
Author: hkz <tabaglio@posteo.net>
Date:   Sun Oct 12 21:19:43 2025 +0200

    Tweak nametable for the dialog

commit dd0e5ce53d
Author: hkz <tabaglio@posteo.net>
Date:   Sun Oct 12 21:12:24 2025 +0200

    Integrate the new dialog module for the VDP

commit b4469d514c
Author: hkz <tabaglio@posteo.net>
Date:   Sun Oct 12 15:25:31 2025 +0200

    Add dummy module for VDP dialog

commit d1dcdd1381
Author: hkz <tabaglio@posteo.net>
Date:   Sun Oct 12 12:15:23 2025 +0200

    Add initializer module for VDP

commit fd84d3abbb
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 20:15:46 2025 +0200

    Begin defining binaries

commit bd650081fc
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 15:02:56 2025 +0200

    Add resources for two screens of the VDP version

commit 58f7436c45
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 12:52:38 2025 +0200

    Add a module list with defines

commit 969fe9deab
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 12:35:40 2025 +0200

    Additional renaming

commit 83552c2ad8
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 12:14:27 2025 +0200

    Rename other graphic files, remove unused imports

commit dbc1bebf9f
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 11:59:16 2025 +0200

    Begin renaming graphic files to mention they're for HGR
2025-10-17 09:34:26 +02:00
hkz
49232e5887 Update README and screenshot 2025-10-07 09:09:38 +02:00
hkz
c1060fb449 Squashed commit of the following:
commit b29f27ab8d852ff575840060b9af7b62c1b69f68
Author: hkz <tabaglio@posteo.net>
Date:   Tue Oct 7 09:01:06 2025 +0200

    Removed unused loading_screen.c, Updated CHANGELOG, updated loading
    screen

commit 2855ba5209
Author: hkz <tabaglio@posteo.net>
Date:   Thu Sep 11 15:42:46 2025 +0200

    Restore correct offsets for disk writing

commit e1216fa616
Author: hkz <tabaglio@posteo.net>
Date:   Sat Sep 6 10:30:43 2025 +0200

    Update the version number

commit 8a4559d4f9
Author: hkz <tabaglio@posteo.net>
Date:   Sat Sep 6 09:58:24 2025 +0200

    implement a demo mode

commit 22790bdc44
Author: hkz <tabaglio@posteo.net>
Date:   Sat Sep 6 08:31:11 2025 +0200

    Initial creation of demo module
2025-10-07 09:02:18 +02:00
hkz
510d317511 Add LICENSE 2025-09-01 22:32:34 +02:00
hkz
426a72563b Port limited retries when searching for sector start during disk write 2025-09-01 21:46:52 +02:00
hkz
0f34399cca Move the CRC8 code into utility 2025-09-01 08:42:13 +02:00
hkz
491a37b938 Fix typo 2025-08-30 15:02:50 +02:00
49 changed files with 2892 additions and 1002 deletions

View file

@ -1,5 +1,26 @@
# Changelog # Changelog
## 3.0 - 2025-10-17
### Added
- Support for the TK2000 VDP board
## 2.1 - 2025-10-07
### Changed
- Show version number in dialogs and game screens
### Added
- Demo mode
### Removed
- Version from startup loading screen
## 2.0 - 2025-08-30 ## 2.0 - 2025-08-30
_This release removes the tape version of the game._ _This release removes the tape version of the game._

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Hkz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -11,27 +11,52 @@ MASTER_PRG=master
INTRO_PRG=intro INTRO_PRG=intro
DLOG_PRG=dlog DLOG_PRG=dlog
GAME_PRG=game GAME_PRG=game
DEMO_PRG=demo
VDPIN_PRG=vdpin
VDDLG_PRG=vddlg
VDGAM_PRG=vdgam
VDDEM_PRG=vddem
# Libraries # Libraries
LIBS=clib-6502.a LIBS=clib-6502.a
MASTER_ASM_SRCS = tk2k_startup_master.s disk2.s master_func.s MASTER_ASM_SRCS = tk2k_startup_master.s disk2.s master_func.s
MASTER_C_SRCS = master_main.c dos_floppy.c MASTER_C_SRCS = master_main.c dos_floppy.c utility.c
INTRO_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s INTRO_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s vdp.s vdp_utils.s
INTRO_C_SRCS = intro_main.c utility.c INTRO_C_SRCS = intro_main.c utility.c input.c
DLOG_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s sound.s DLOG_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s sound.s
DLOG_C_SRCS = dlog_main.c input.c utility.c game_graphics.c line_data.c DLOG_C_SRCS = dlog_main.c input.c utility.c game_hgr_graphics.c hgr_line_data.c
GAME_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s GAME_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s
GAME_C_SRCS = game_main.c input.c utility.c game_graphics.c line_data.c game_logic.c arrows_pic.c tiles.c graph_misc_data.c GAME_C_SRCS = game_main.c input.c utility.c game_hgr_graphics.c hgr_line_data.c game_logic.c arrows_pic.c tiles.c hgr_graph_misc_data.c
DEMO_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s
DEMO_C_SRCS = demo_main.c input.c utility.c game_hgr_graphics_demo.c hgr_line_data.c game_logic.c arrows_pic.c tiles.c hgr_graph_misc_data.c
VDPIN_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s vdp.s vdp_utils.s vdp_init.s
VDPIN_C_SRCS = vdpin_main.c utility.c
VDDLG_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s sound.s vdp.s vdp_utils.s game_vdp_graphics.s
VDDLG_C_SRCS = vddlg_main.c input.c utility.c
VDGAM_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s vdp.s vdp_utils.s game_vdp_graphics.s
VDGAM_C_SRCS = vdgam_main.c input.c utility.c game_logic.c
VDDEM_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s vdp.s vdp_utils.s game_vdp_graphics.s
VDDEM_C_SRCS = vddem_main.c input.c utility.c game_logic.c
# Object files # Object files
MASTER_OBJS = $(MASTER_ASM_SRCS:%.s=%.o) $(MASTER_C_SRCS:%.c=%.o) MASTER_OBJS = $(MASTER_ASM_SRCS:%.s=%.o) $(MASTER_C_SRCS:%.c=%.o)
INTRO_OBJS = $(INTRO_ASM_SRCS:%.s=%.o) $(INTRO_C_SRCS:%.c=%.o) INTRO_OBJS = $(INTRO_ASM_SRCS:%.s=%.o) $(INTRO_C_SRCS:%.c=%.o)
DLOG_OBJS = $(DLOG_ASM_SRCS:%.s=%.o) $(DLOG_C_SRCS:%.c=%.o) DLOG_OBJS = $(DLOG_ASM_SRCS:%.s=%.o) $(DLOG_C_SRCS:%.c=%.o)
GAME_OBJS = $(GAME_ASM_SRCS:%.s=%.o) $(GAME_C_SRCS:%.c=%.o) GAME_OBJS = $(GAME_ASM_SRCS:%.s=%.o) $(GAME_C_SRCS:%.c=%.o)
DEMO_OBJS = $(DEMO_ASM_SRCS:%.s=%.o) $(DEMO_C_SRCS:%.c=%.o)
VDPIN_OBJS = $(VDPIN_ASM_SRCS:%.s=%.o) $(VDPIN_C_SRCS:%.c=%.o)
VDDLG_OBJS = $(VDDLG_ASM_SRCS:%.s=%.o) $(VDDLG_C_SRCS:%.c=%.o)
VDGAM_OBJS = $(VDGAM_ASM_SRCS:%.s=%.o) $(VDGAM_C_SRCS:%.c=%.o)
VDDEM_OBJS = $(VDDEM_ASM_SRCS:%.s=%.o) $(VDDEM_C_SRCS:%.c=%.o)
all: $(SW_NAME).woz all: $(SW_NAME).woz
@ -53,6 +78,21 @@ $(DLOG_PRG).hex: $(DLOG_OBJS)
$(GAME_PRG).hex: $(GAME_OBJS) $(GAME_PRG).hex: $(GAME_OBJS)
(cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code) (cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(DEMO_PRG).hex: $(DEMO_OBJS)
(cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(VDPIN_PRG).hex: $(VDPIN_OBJS)
(cd obj ; ln6502 -g ../linker-files/vdpin_module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(VDDLG_PRG).hex: $(VDDLG_OBJS)
(cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(VDGAM_PRG).hex: $(VDGAM_OBJS)
(cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(VDDEM_PRG).hex: $(VDDEM_OBJS)
(cd obj ; ln6502 -g ../linker-files/module.scm $^ -o ../out/$@ $(LIBS) -l --cross-reference --cstartup=tk2k --no-automatic-placement-rules --output-format intel-hex --rom-code)
$(MASTER_PRG).bin: $(MASTER_PRG).hex $(MASTER_PRG).bin: $(MASTER_PRG).hex
(cd out ; objcopy -I ihex -O binary $(MASTER_PRG).hex $(MASTER_PRG).bin) (cd out ; objcopy -I ihex -O binary $(MASTER_PRG).hex $(MASTER_PRG).bin)
@ -65,12 +105,32 @@ $(DLOG_PRG).bin: $(DLOG_PRG).hex
$(GAME_PRG).bin: $(GAME_PRG).hex $(GAME_PRG).bin: $(GAME_PRG).hex
(cd out ; objcopy -I ihex -O binary $(GAME_PRG).hex $(GAME_PRG).bin) (cd out ; objcopy -I ihex -O binary $(GAME_PRG).hex $(GAME_PRG).bin)
$(SW_NAME).dsk: $(MASTER_PRG).bin $(INTRO_PRG).bin $(DLOG_PRG).bin $(GAME_PRG).bin $(DEMO_PRG).bin: $(DEMO_PRG).hex
(cd out ; objcopy -I ihex -O binary $(DEMO_PRG).hex $(DEMO_PRG).bin)
$(VDPIN_PRG).bin: $(VDPIN_PRG).hex
(cd out ; objcopy -I ihex -O binary $(VDPIN_PRG).hex $(VDPIN_PRG).bin)
$(VDDLG_PRG).bin: $(VDDLG_PRG).hex
(cd out ; objcopy -I ihex -O binary $(VDDLG_PRG).hex $(VDDLG_PRG).bin)
$(VDGAM_PRG).bin: $(VDGAM_PRG).hex
(cd out ; objcopy -I ihex -O binary $(VDGAM_PRG).hex $(VDGAM_PRG).bin)
$(VDDEM_PRG).bin: $(VDDEM_PRG).hex
(cd out ; objcopy -I ihex -O binary $(VDDEM_PRG).hex $(VDDEM_PRG).bin)
$(SW_NAME).dsk: $(MASTER_PRG).bin $(INTRO_PRG).bin $(DLOG_PRG).bin $(GAME_PRG).bin $(DEMO_PRG).bin $(VDPIN_PRG).bin $(VDDLG_PRG).bin $(VDGAM_PRG).bin $(VDDEM_PRG).bin
(cd out ; cp ../dsk/TK2048_AUTO_BRUN.dsk ./$(SW_NAME).dsk; \ (cd out ; cp ../dsk/TK2048_AUTO_BRUN.dsk ./$(SW_NAME).dsk; \
cat $(MASTER_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk HELLO B 0x800; \ cat $(MASTER_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk HELLO B 0x800; \
cat $(INTRO_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk INTRO b; \ cat $(INTRO_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk INTRO b; \
cat $(DLOG_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk DLOG b; \ cat $(DLOG_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk DLOG b; \
cat $(GAME_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk GAME b; \ cat $(GAME_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk GAME b; \
cat $(DEMO_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk DEMO b; \
cat $(VDPIN_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk VDPIN b; \
cat $(VDDLG_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk VDDLG b; \
cat $(VDGAM_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk VDGAM b; \
cat $(VDDEM_PRG).bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk VDDEM b; \
cat ../data/LOADS.bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk LOADS b; \ cat ../data/LOADS.bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk LOADS b; \
cat ../data/STATE.bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk STATE b;) cat ../data/STATE.bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk STATE b;)

View file

@ -35,12 +35,14 @@ If you wish to support me in building new hardware and software for old machines
The game is playable, and the following features have been implemented: The game is playable, and the following features have been implemented:
- B/W mode - B/W mode
- VDP board support
- Single graphical tileset - Single graphical tileset
- Crude sound - Simple sound effects
- Control via keyboard - Control via keyboard
- 5x5 grid, with randomized start and new tiles - 5x5 grid, with randomized start and new tiles
- Game save/load - Game save/load
- Highscore saving - Highscore saving
- Demo mode
## How to play ## How to play
@ -51,6 +53,17 @@ The game is playable, and the following features have been implemented:
The game ends once you reach a tile with a value of 2048. The game ends once you reach a tile with a value of 2048.
### VDP support
The game supports the [TK2000 VDP board](https://codeberg.org/hkzlab/TK2000_VDPboard) configured at address `C0Cx`.
![TK2048 VDP Game screen](pics/vdp_mode.jpg)
The card gets automatically detected and used: once the game completes the initial load, everything will be displayed on the screen
connected to the VDP board, and the main screen connected to the TK2000 will be left blank.
If you want to override detection and force the use of the main screen, just keep a button pressed while the title screen image loads.
### Floppy version ### Floppy version
Just put your floppy in the first drive and power on the TK2000. It will autoboot. Just put your floppy in the first drive and power on the TK2000. It will autoboot.
@ -59,7 +72,7 @@ Just put your floppy in the first drive and power on the TK2000. It will autoboo
You need the following: You need the following:
- GNU Make (I used the one provide via [MSYS2](https://www.msys2.org/)) - GNU Make (I used the one provides by [MSYS2](https://www.msys2.org/))
- [Calypsi 6502 toolchain](https://www.calypsi.cc/) (tested with 5.10) - [Calypsi 6502 toolchain](https://www.calypsi.cc/) (tested with 5.10)
- [AppleCommander](https://github.com/AppleCommander/AppleCommander), "ac" command line version (tested with 1.9.0) - [AppleCommander](https://github.com/AppleCommander/AppleCommander), "ac" command line version (tested with 1.9.0)
- [dsk2woz](https://github.com/TomHarte/dsk2woz) - [dsk2woz](https://github.com/TomHarte/dsk2woz)

Binary file not shown.

BIN
data/vdp_charset.bin Normal file

Binary file not shown.

BIN
data/vdp_colortable.bin Normal file

Binary file not shown.

BIN
data/vdp_nt_board.bin Normal file

Binary file not shown.

BIN
data/vdp_nt_dialog.bin Normal file

Binary file not shown.

BIN
data/vdp_sprite_tiles.bin Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before After
Before After

View file

@ -4,8 +4,8 @@
(memory firstPage (address (#x100 . #x1ff)) (section stack)) (memory firstPage (address (#x100 . #x1ff)) (section stack))
(memory reserved (address (#x200 . #x1fff)) (type ram)) (memory reserved (address (#x200 . #x1fff)) (type ram))
(memory displayPage1 (address (#x2000 . #x3fff)) (type ram)) (memory displayPage1 (address (#x2000 . #x3fff)) (type ram))
(memory upperProg (address (#x4000 . #x93ff)) (type ram) (section (programStart #x4000) startup code switch idata cdata data_init_table)) (memory upperProg (address (#x4000 . #x935f)) (type ram) (section (programStart #x4000) startup code switch idata cdata data_init_table))
(memory upperData (address (#x9400 . #x99ff)) (type ram) (section cstack zdata data heap)) (memory upperData (address (#x9360 . #x99ff)) (type ram) (section cstack zdata data heap intrzp))
(memory sharedMem (address (#x9a00 . #x9bff)) (type ram)) ;;; This memory page will be used to pass parameters and data between the master and the modules, and to save the game state (memory sharedMem (address (#x9a00 . #x9bff)) (type ram)) ;;; This memory page will be used to pass parameters and data between the master and the modules, and to save the game state
(memory diskBuffer (address (#x9c00 . #x9eff)) (type ram)) (memory diskBuffer (address (#x9c00 . #x9eff)) (type ram))
(memory zeroPageBackup (address (#x9f00 . #x9fff)) (type ram) (section (zpsave #x9f00))) (memory zeroPageBackup (address (#x9f00 . #x9fff)) (type ram) (section (zpsave #x9f00)))

View file

@ -0,0 +1,19 @@
(define memories
'((memory zeroPage (address (#x56 . #xff)) (type ram)
(section registers zpage zzpage))
(memory firstPage (address (#x100 . #x1ff)) (section stack))
(memory reserved (address (#x200 . #x1fff)) (type ram))
(memory displayPage1 (address (#x2000 . #x3fff)) (type ram))
(memory upperProg (address (#x4000 . #x7fff)) (type ram) (section (programStart #x4000) startup code switch idata cdata data_init_table))
(memory upperData (address (#x8000 . #x99ff)) (type ram) (section cstack zdata data heap intrzp))
(memory sharedMem (address (#x9a00 . #x9bff)) (type ram)) ;;; This memory page will be used to pass parameters and data between the master and the modules, and to save the game state
(memory diskBuffer (address (#x9c00 . #x9eff)) (type ram))
(memory zeroPageBackup (address (#x9f00 . #x9fff)) (type ram) (section (zpsave #x9f00)))
(memory displayPage2 (address (#xa000 . #xbfff)) (type ram))
(memory io (address (#xc000 . #xc0ff)) (type ram))
(memory rombank (address (#xc100 . #xffff)) (type rom))
(block cstack (size #x400))
(block heap (size #x020))
(block stack (size #x100))
))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before After
Before After

BIN
pics/vdp_mode.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

156
src/demo_main.c Normal file
View file

@ -0,0 +1,156 @@
#include <stubs.h>
#include <string.h>
#include <calypsi/intrinsics6502.h>
#include "monitor_subroutines.h"
#include "utility.h"
#include "mem_map.h"
#include "shared_page.h"
#include "state_page.h"
#include "dlog_data.h"
#include "game_data.h"
#include "input.h"
#include "game_logic.h"
#include "game_hgr_graphics.h"
#include "monitor_subroutines.h"
#include "sound.h"
#include "module_list.h"
// External initialization requirements
#pragma require __preserve_zp
#pragma require __data_initialization_needed
#define MOVES_TEXT_X 32
#define MOVES_TEXT_Y 61
#define MOVES_TEXT_WIDTH 5
#define SCORE_TEXT_X 32
#define SCORE_TEXT_Y 29
#define SCORE_TEXT_WIDTH 5
#define HIGH_TEXT_X 32
#define HIGH_TEXT_Y 107
#define KEY_LOOP_LEN 0x2FFF
#define MAX_DEMO_MOVES 30
static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
void main(void) {
uint16_t moves_count = 0;
uint16_t score = 0;
int8_t done = 0;
// By default, once we return from this, return to the DLOG module and give the master no command to execute
shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = MODULE_DLOG; // Go to the DLOG module
dlog_data *dld = (dlog_data *)(shared_page->module_data);
dlog_data *gad = (dlog_data *)(shared_page->module_data);
// Make sure the buffers are pointing to the correct memory and are clear
clear_display_buffers();
// Reset the game, calculate the initial score depending on which tiles we randomly get
score = reset_game();
// Draw the initial state of the game
draw_game_background(state_page->hi_score);
draw_number(moves_count, MOVES_TEXT_WIDTH, MOVES_TEXT_X, MOVES_TEXT_Y);
draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y);
draw_tiles();
// Swap graphical buffers
swap_display_buffers();
while(1) { // Game loop
uint16_t lfsr = lfsr_update();
// Any key will let us out of this, wait some time for a keypress
uint16_t k_loop_count = KEY_LOOP_LEN;
while(k_loop_count--) {
if(read_any_key()) {
snd_mod_button();
done = 1;
break;
}
}
if(!done) {
switch((lfsr & 0x0003) + 1) {
case K_UP:
SND_TAP();
done = step_game(GAME_STEP_UP);
ddraw_direction_arrows(GRAPH_ARROW_UP);
break;
case K_DOWN:
SND_TAP();
done = step_game(GAME_STEP_DOWN);
ddraw_direction_arrows(GRAPH_ARROW_DOWN);
break;
case K_LEFT:
SND_TAP();
done = step_game(GAME_STEP_LEFT);
ddraw_direction_arrows(GRAPH_ARROW_LEFT);
break;
case K_RIGHT:
SND_TAP();
done = step_game(GAME_STEP_RIGHT);
ddraw_direction_arrows(GRAPH_ARROW_RIGHT);
break;
default:
continue; // Do nothing, loop again
}
}
// Increase the count of moves we made (unless we lost or reset the game)
if(done >= 0) {
moves_count++;
done = done || (moves_count >= MAX_DEMO_MOVES);
}
// Draw the number of moves
draw_number(moves_count, MOVES_TEXT_WIDTH, MOVES_TEXT_X, MOVES_TEXT_Y);
// Draw the moved tiles
draw_tiles();
// If we have won, or we got a reset request, break out of this loop
if(done) {
draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y);
swap_display_buffers(); // Make sure we show the latest changes
break;
}
// Unable to add a tile: we ran out of space and lost!!!
uint8_t random_tile_off = add_random_tile();
if(!random_tile_off) {
done = -1; // Lost the game
break;
}
score = calculate_score();
// Draw the score
draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y);
swap_display_buffers();
// Draw the new tile directly on the front buffer, this way we make it appear with an "animation"
ddraw_single_tile(random_tile_off - 1);
}
// Sync the display buffers
sync_display1_buffer();
// Always go back to the start dialog
dld->mode = DLOG_MODE_START;
dld->score = 0;
clear_display_buffers();
return;
}

View file

@ -527,9 +527,10 @@ RETRIES$: .equ 0xff
; Note that the following buffers MUST be at the start of a page for write timing to be respected ; Note that the following buffers MUST be at the start of a page for write timing to be respected
__BUF2S: .equ 0x9D00 ; Default to this, it'll be overwritten when modifying this code. 86 entries. __BUF2S: .equ 0x9D00 ; Default to this, it'll be overwritten when modifying this code. 86 entries.
__BUF6S: .equ 0x9C00 ; 256 entries. __BUF6S: .equ 0x9C00 ; 256 entries.
__NIBTAB: .equ 0x9D56 ; This will contain the translation table for writing nibbles. 63 entries. __NIBTAB: .equ 0x9D56
__OFFSETP6 .equ 0x0678 __OFFSETP6 .equ 0x0678
__T_RETRYC2:.equ _Zp+10
__T_VOL: .equ _Zp+9 __T_VOL: .equ _Zp+9
__T_TRK: .equ _Zp+8 __T_TRK: .equ _Zp+8
__T_SEC: .equ _Zp+7 __T_SEC: .equ _Zp+7
@ -546,19 +547,24 @@ __P_TRACK: .equ _Zp+0
sta __OFFSETP6 sta __OFFSETP6
tax tax
lda #RETRIES$ ; Set up the retry counter lda #RETRIES$ ; Set up the retry counters
sta zp:__T_RETRYC2
InnerRetr$: lda #RETRIES$
sta zp:__T_RETRYC sta zp:__T_RETRYC
dec zp:__T_RETRYC2
beq wr_err_return ; Out of retries
;;; Search for the address prologue (D5 AA 96) ;;; Search for the address prologue (D5 AA 96)
RdSect$: RdSect$:
dec zp:__T_RETRYC dec zp:__T_RETRYC
beq wr_err_return ; Out of retries beq InnerRetr$ ; Out of retries
;;; Read the address prologue ;;; Read the address prologue
RdByte1$: lda READ_SW,x RdByte1$: lda READ_SW,x
bpl RdByte1$ ; Read the first byte bpl RdByte1$ ; Read the first byte
ChkD5$: cmp #0xD5 ChkD5$: cmp #0xD5
bne RdByte1$ ; Not the first byte, keep searching bne RdSect$ ; Not the first byte, keep searching
nop nop
RdByte2$: lda READ_SW,x RdByte2$: lda READ_SW,x
@ -615,7 +621,8 @@ RdByte7$: lda READ_SW,x
lda WRITE_SW,x ; Combination of these two in sequence checks for write protect lda WRITE_SW,x ; Combination of these two in sequence checks for write protect
lda CLEAR_SW,x ; and enables the write sequence. lda CLEAR_SW,x ; and enables the write sequence.
bmi wr_err_return ; Write protected disk. Branch on N = 1 bpl _b2add01 ; Check if Write protected disk.
jmp wr_err_return
_b2add01: _b2add01:
lda __BUF2S ; Get the first 2-bit encode byte lda __BUF2S ; Get the first 2-bit encode byte
sta zp:__T_HOLDNIB ; and save it for future use. sta zp:__T_HOLDNIB ; and save it for future use.

View file

@ -3,7 +3,7 @@
#include <calypsi/intrinsics6502.h> #include <calypsi/intrinsics6502.h>
#include "game_graphics.h" #include "game_hgr_graphics.h"
#include "monitor_subroutines.h" #include "monitor_subroutines.h"
#include "utility.h" #include "utility.h"
#include "mem_map.h" #include "mem_map.h"
@ -13,6 +13,7 @@
#include "game_data.h" #include "game_data.h"
#include "input.h" #include "input.h"
#include "sound.h" #include "sound.h"
#include "module_list.h"
// External initialization requirements // External initialization requirements
#pragma require __preserve_zp #pragma require __preserve_zp
@ -21,7 +22,10 @@
static state_page_data* state_page = (state_page_data*)STATE_PAGE; static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE; static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
#define WAIT_COUNTER_END 0xFFFF
void main(void) { void main(void) {
uint16_t wait_counter = 0;
dlog_data *dld = (dlog_data *)(shared_page->module_data); dlog_data *dld = (dlog_data *)(shared_page->module_data);
game_data *gad = (game_data *)(shared_page->module_data); game_data *gad = (game_data *)(shared_page->module_data);
@ -51,13 +55,19 @@ void main(void) {
shared_page->master_command = MASTER_COMMAND_NONE; shared_page->master_command = MASTER_COMMAND_NONE;
} }
shared_page->next_module_idx = 4; // Go to the GAME module shared_page->next_module_idx = MODULE_GAME; // Go to the GAME module
gad->mode = GAME_MODE_NORMAL; // Set the proper start mode for the game gad->mode = GAME_MODE_NORMAL; // Set the proper start mode for the game
while(!read_any_key()) { while(!read_any_key() && (wait_counter != WAIT_COUNTER_END)) {
wait_counter++;
lfsr_update(); lfsr_update();
} }
if (wait_counter == WAIT_COUNTER_END) {
shared_page->next_module_idx = MODULE_DEMO; // Actually go to the DEMO module
return;
}
snd_mod_button(); snd_mod_button();
return; return;

View file

@ -3,6 +3,11 @@
#include <stdint.h> #include <stdint.h>
#define GAME_VER_CH0 '3'
#define GAME_VER_CH1 '.'
#define GAME_VER_CH2 '0'
#define GAME_MODE_NORMAL 0 #define GAME_MODE_NORMAL 0
#define GAME_MODE_LOAD 1 #define GAME_MODE_LOAD 1

View file

@ -1,16 +1,17 @@
#include "game_graphics.h" #include "game_hgr_graphics.h"
#include <string.h> #include <string.h>
#include "game_data.h"
#include "utility.h" #include "utility.h"
#include "mem_map.h" #include "mem_map.h"
#include "mem_registers.h" #include "mem_registers.h"
#include "line_data.h" #include "hgr_line_data.h"
#include "game_logic.h" #include "game_logic.h"
#include "tiles.h" #include "tiles.h"
#include "charset.h" #include "charset.h"
#include "monitor_subroutines.h" #include "monitor_subroutines.h"
#include "graph_misc_data.h" #include "hgr_graph_misc_data.h"
#include "arrows_pic.h" #include "arrows_pic.h"
#define SCREEN_WIDTH 280 #define SCREEN_WIDTH 280
@ -78,7 +79,7 @@ static const uint8_t box_content_start[BOX_CONTENT_SIZE] = {
0, 0, 0, 0, 0, 0, 0,203, 77, 0, 0, 77, 0, 0, 77,192, 77, 0, 77, 77,211, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,203, 77, 0, 0, 77, 0, 0, 77,192, 77, 0, 77, 77,211, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 77, 77,211, 0, 0, 77, 0, 0, 77, 0, 77, 0, 77,198, 84, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 77,211, 0, 0, 77, 0, 0, 77, 0, 77, 0, 77,198, 84, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 20, 11, 50, 48, 52, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 50, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 11, 50, 48, 52, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, GAME_VER_CH0, GAME_VER_CH1, GAME_VER_CH2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -106,9 +107,30 @@ static const uint8_t instruction_box[INSTR_BOX_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18, 5, 1, 3, 8, 0, 0, 50, 48, 52, 56, 33, 18, 5, 1, 3, 8, 0, 0, 50, 48, 52, 56, 33,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79, 0, 50, 48, 50, 53, 0, 50, 46, 48, 0, 79 7, 15, 15, 4, 0, 12, 21, 3, 11, 33, 33, 33
}; };
static const uint8_t demo_box[INSTR_BOX_SIZE] = {
4, 5, 13, 15, 0, 0, 13, 15, 4, 5, 0, 0,
0, 4, 5, 13, 15, 0, 0, 13, 15, 4, 5, 0,
0, 0, 4, 5, 13, 15, 0, 0, 13, 15, 4, 5,
5, 0, 0, 4, 5, 13, 15, 0, 0, 13, 15, 4,
4, 5, 0, 0, 4, 5, 13, 15, 0, 0, 13, 15,
15, 4, 5, 0, 0, 4, 5, 13, 15, 0, 0, 13,
13, 15, 4, 5, 0, 0, 4, 5, 13, 15, 0, 0,
0, 13, 15, 4, 5, 0, 0, 4, 5, 13, 15, 0
};
#ifdef _DEMO_MODE_
#define DEMO_TOP_TEXT_WIDTH 14
#define DEMO_TOP_TEXT_HEIGHT 1
#define DEMO_TOP_TEXT_X 7
#define DEMO_TOP_TEXT_Y 0
static const uint8_t demo_top_text[DEMO_TOP_TEXT_WIDTH * DEMO_TOP_TEXT_HEIGHT] = {
32, 16, 21, 19, 8, 32, 1, 14, 25, 32, 11, 5, 25, 32
};
#endif /* _DEMO_MODE_ */
// The grid is 5x5 squares, // The grid is 5x5 squares,
// It is offset on the left side by 7 pixels and on the top by 14 // It is offset on the left side by 7 pixels and on the top by 14
@ -135,6 +157,10 @@ void draw_game_background(uint16_t hi_score) {
// Draw the borders // Draw the borders
draw_field_borders_on_buffer(0x0F, buf); draw_field_borders_on_buffer(0x0F, buf);
#ifdef _DEMO_MODE_
draw_graph_char_box(DEMO_TOP_TEXT_X, DEMO_TOP_TEXT_Y, DEMO_TOP_TEXT_WIDTH, DEMO_TOP_TEXT_HEIGHT, demo_top_text, front_buf);
#endif
// Draw required pics // Draw required pics
draw_picture(SCORE_PIC_WIDTH_BYTES, SCORE_PIC_HEIGHT, 31, 14, score_pic_data, buf); draw_picture(SCORE_PIC_WIDTH_BYTES, SCORE_PIC_HEIGHT, 31, 14, score_pic_data, buf);
draw_picture(MOVES_PIC_WIDTH_BYTES, MOVES_PIC_HEIGHT, 31, 45, moves_pic_data, buf); draw_picture(MOVES_PIC_WIDTH_BYTES, MOVES_PIC_HEIGHT, 31, 45, moves_pic_data, buf);
@ -144,8 +170,12 @@ void draw_game_background(uint16_t hi_score) {
// Draw the high-score. This won't change at every turn, so makes sense to just draw once // Draw the high-score. This won't change at every turn, so makes sense to just draw once
direct_draw_number(hi_score, HIGH_TEXT_WIDTH, HIGH_TEXT_X, HIGH_TEXT_Y, front_buf); direct_draw_number(hi_score, HIGH_TEXT_WIDTH, HIGH_TEXT_X, HIGH_TEXT_Y, front_buf);
// Draw instruction box // Draw demo or instruction box
#ifdef _DEMO_MODE_
draw_graph_char_box(INSTR_BOX_X, INSTR_BOX_Y, INSTR_BOX_WIDTH, INSTR_BOX_HEIGHT, demo_box, front_buf);
#else
draw_graph_char_box(INSTR_BOX_X, INSTR_BOX_Y, INSTR_BOX_WIDTH, INSTR_BOX_HEIGHT, instruction_box, front_buf); draw_graph_char_box(INSTR_BOX_X, INSTR_BOX_Y, INSTR_BOX_WIDTH, INSTR_BOX_HEIGHT, instruction_box, front_buf);
#endif
// Copy the data from display page 1 to 2 // Copy the data from display page 1 to 2
memcpy((void*)DISPLAY_PAGE_2, (void*)DISPLAY_PAGE_1, DISPLAY_PAGE_SIZE); memcpy((void*)DISPLAY_PAGE_2, (void*)DISPLAY_PAGE_1, DISPLAY_PAGE_SIZE);
@ -207,6 +237,10 @@ void draw_tiles(void) {
// Re-draw the borders, to restore the correct width // Re-draw the borders, to restore the correct width
draw_field_borders_on_buffer(0x0F, back_buf); draw_field_borders_on_buffer(0x0F, back_buf);
#ifdef _DEMO_MODE_
draw_graph_char_box(DEMO_TOP_TEXT_X, DEMO_TOP_TEXT_Y, DEMO_TOP_TEXT_WIDTH, DEMO_TOP_TEXT_HEIGHT, demo_top_text, back_buf);
#endif
} }
#define ENDGAME_BOX_X_OFFSET 2 #define ENDGAME_BOX_X_OFFSET 2

View file

@ -1,5 +1,5 @@
#ifndef _GAME_GRAPHICS_HEADER_ #ifndef _GAME_HGR_GRAPHICS_HEADER_
#define _GAME_GRAPHICS_HEADER_ #define _GAME_HGR_GRAPHICS_HEADER_
#include <stdint.h> #include <stdint.h>
@ -31,4 +31,4 @@ void ddraw_direction_arrows(uint8_t dir);
void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score); void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score);
void sync_display1_buffer(void); void sync_display1_buffer(void);
#endif /* _GAME_GRAPHICS_HEADER_ */ #endif /* _GAME_HGR_GRAPHICS_HEADER_ */

View file

@ -0,0 +1,3 @@
#define _DEMO_MODE_ 1
#include "game_hgr_graphics.c"

View file

@ -44,14 +44,14 @@ uint8_t add_random_tile(void) {
uint8_t free_tiles = 0; uint8_t free_tiles = 0;
uint8_t chosen_tile; uint8_t chosen_tile;
for (uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { for (int8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) {
if (!front_grid[offset]) free_tiles++; if (!front_grid[offset]) free_tiles++;
} }
if(!free_tiles) return 0; if(!free_tiles) return 0;
chosen_tile = (rand >> 8) % free_tiles; chosen_tile = (rand >> 8) % free_tiles;
for (uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { for (int8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) {
if (!front_grid[offset] && !(chosen_tile--)) { if (!front_grid[offset] && !(chosen_tile--)) {
front_grid[offset] = tile_val; front_grid[offset] = tile_val;
return offset + 1; return offset + 1;
@ -63,7 +63,7 @@ uint8_t add_random_tile(void) {
int8_t step_game(uint8_t dir) { int8_t step_game(uint8_t dir) {
int8_t done = 0; int8_t done = 0;
uint8_t start_offset; int8_t start_offset;
int8_t column_step; int8_t column_step;
int8_t row_step; int8_t row_step;
@ -100,8 +100,8 @@ int8_t step_game(uint8_t dir) {
// Clear the back grid // Clear the back grid
memset(back_grid, 0, GRID_SIDE * GRID_SIDE); memset(back_grid, 0, GRID_SIDE * GRID_SIDE);
for (uint8_t row = 0; row < GRID_SIDE; row++) { for (int8_t row = 0; row < GRID_SIDE; row++) {
for(uint8_t col = 0; col < GRID_SIDE; col++) { for(int8_t col = 0; col < GRID_SIDE; col++) {
uint8_t current_offset = start_offset + (col * column_step) + (row * row_step); uint8_t current_offset = start_offset + (col * column_step) + (row * row_step);
uint8_t sub_col; uint8_t sub_col;

View file

@ -12,9 +12,10 @@
#include "game_data.h" #include "game_data.h"
#include "input.h" #include "input.h"
#include "game_logic.h" #include "game_logic.h"
#include "game_graphics.h" #include "game_hgr_graphics.h"
#include "monitor_subroutines.h" #include "monitor_subroutines.h"
#include "sound.h" #include "sound.h"
#include "module_list.h"
// External initialization requirements // External initialization requirements
#pragma require __preserve_zp #pragma require __preserve_zp
@ -43,7 +44,7 @@ void main(void) {
// By default, once we return from this, return to the DLOG module and give the master no command to execute // By default, once we return from this, return to the DLOG module and give the master no command to execute
shared_page->master_command = MASTER_COMMAND_NONE; shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = 3; // Go to the DLOG module shared_page->next_module_idx = MODULE_DLOG; // Go to the DLOG module
dlog_data *dld = (dlog_data *)(shared_page->module_data); dlog_data *dld = (dlog_data *)(shared_page->module_data);
dlog_data *gad = (dlog_data *)(shared_page->module_data); dlog_data *gad = (dlog_data *)(shared_page->module_data);
@ -112,7 +113,7 @@ void main(void) {
case K_CTRL_L: case K_CTRL_L:
snd_mod_button(); snd_mod_button();
sync_display1_buffer(); sync_display1_buffer();
shared_page->next_module_idx = 4; shared_page->next_module_idx = MODULE_GAME;
gad->mode = GAME_MODE_LOAD; gad->mode = GAME_MODE_LOAD;
return; return;
default: default:

19
src/game_vdp_graphics.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef _GAME_VDP_GRAPHICS_HEADER_
#define _GAME_VDP_GRAPHICS_HEADER_
#include <stdint.h>
#define JS_POS_CENTER 0
#define JS_POS_UP 1
#define JS_POS_DOWN 2
#define JS_POS_LEFT 3
#define JS_POS_RIGHT 4
void vdp_clear_gamegrid(void);
void vdp_clear_dialog(void);
uint8_t vdp_draw_numtile(uint8_t type, uint8_t x, uint8_t y);
void vdp_redraw_tiles(uint8_t *grid);
void vdp_draw_joystick(uint8_t position);
#endif /* _GAME_VDP_GRAPHICS_HEADER_ */

323
src/game_vdp_graphics.s Normal file
View file

@ -0,0 +1,323 @@
.rtmodel version,"1"
.rtmodel core,"6502"
.extern _Zp
.extern VDP_MEM, VDP_REG
.extern vdp_point_to_vram_xy, vdp_hide_sprite, vdp_show_sprite, vdp_set_sprite_tile
NUM_TILE_OFFSET: .equ 0x14
.section code,text
vdp_redraw_tiles:
P_GRID_H$: .equ _Zp+9
P_GRID_L$: .equ _Zp+8
lda zp:_Zp+0
sta zp:P_GRID_L$
lda zp:_Zp+1
sta zp:P_GRID_H$
ldy #24
SetSprtLoop$:
lda (zp:P_GRID_L$),y
bne SkipHide$
pha
tya
pha
jsr vdp_hide_sprite
pla
tay
pla
jmp SkipSprite$
SkipHide$:
sta zp:_Zp+0
dec zp:_Zp+0
tya
pha
jsr vdp_set_sprite_tile
pla
tay
pha
jsr vdp_show_sprite
pla
tay
SkipSprite$:
dey
bpl SetSprtLoop$
ldy #24
SetTileLoop$:
tya
pha
lda TileNum_To_X_Map,y
sta zp:_Zp+0
lda TileNum_To_Y_Map,y
sta zp:_Zp+1
lda (zp:P_GRID_L$),y
jsr vdp_draw_numtile
pla
tay
dey
bpl SetTileLoop$
rts
vdp_draw_joystick:
T_NT_IDX$: .equ _Zp+4
P_POS$: .equ _Zp+2
T_Y$: .equ _Zp+1
T_X$: .equ _Zp+0
pha
ldx #0
stx zp:T_NT_IDX$
; Clear the table
lda #29
sta zp:T_X$
lda #16
sta zp:T_Y$
jsr vdp_point_to_vram_xy
lda #0
sta VDP_MEM
nop
lda #29
sta zp:T_X$
lda #18
sta zp:T_Y$
jsr vdp_point_to_vram_xy
lda #0
sta VDP_MEM
nop
lda #28
sta zp:T_X$
lda #17
sta zp:T_Y$
jsr vdp_point_to_vram_xy
lda #0
sta VDP_MEM
nop ; Slow down, we're using this while the IC is rendering
nop
sta VDP_MEM
nop
nop
sta VDP_MEM
nop
nop
; Jump to the correct code to handle joystick drawing
pla
asl a
tax
lda _draw_joystick_jumptable$,x
sta zp:_Zp+0
lda _draw_joystick_jumptable$+1,x
sta zp:_Zp+1
sec
jmp (_Zp+0)
J_Center$:
ldx #29
ldy #17
bcs J_Done$
J_Up$:
ldx #29
ldy #16
bcs J_Done$
J_Down$:
ldx #29
ldy #18
bcs J_Done$
J_Left$:
ldx #28
ldy #17
bcs J_Done$
J_Right$:
ldx #30
ldy #17
J_Done$:
stx zp:T_X$
sty zp:T_Y$
jsr vdp_point_to_vram_xy
lda #120
sta VDP_MEM
nop
nop
rts
_draw_joystick_jumptable$:
.word J_Center$
.word J_Up$
.word J_Down$
.word J_Left$
.word J_Right$
vdp_clear_gamegrid:
T_NT_IDX$: .equ _Zp+4
T_Y$: .equ _Zp+1
T_X$: .equ _Zp+0
lda #0x00
sta zp:T_NT_IDX$
lda #0x01
sta zp:T_X$
lda #19
sta zp:T_Y$
ClearLine$:
jsr vdp_point_to_vram_xy
lda #0x00
ldx #24
ClearTile$:
sta VDP_MEM
dex
bne ClearTile$
dec zp:T_Y$
bne ClearLine$
rts
vdp_clear_dialog:
T_NT_IDX$: .equ _Zp+4
T_Y$: .equ _Zp+1
T_X$: .equ _Zp+0
lda #0x01
sta zp:T_NT_IDX$
lda #0x04
sta zp:T_X$
lda #15
sta zp:T_Y$
ldy #9
ClearLine$:
jsr vdp_point_to_vram_xy
lda #0x00
ldx #24
ClearTile$:
sta VDP_MEM
dex
bne ClearTile$
dec zp:T_Y$
dey
bne ClearLine$
rts
;;; vdp_draw_numtile:
;;; Draws the 2048 tile at specified coordinates
;;; Parameters:
;;; - Type of tile [A]
;;; - X in game grid [Zp[0]]
;;; - Y in game grid [Zp[1]]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 0, 1, 2, 3, 4, 5, 6, 7
;;;
vdp_draw_numtile:
T_LINE_COUNT$:.equ _Zp+7
T_NT_IDX$: .equ _Zp+4
T_COUNTER$: .equ _Zp+3
P_TYPE$: .equ _Zp+2
P_Y$: .equ _Zp+1
P_X$: .equ _Zp+0
sta zp:P_TYPE$
lda #0
sta zp:T_NT_IDX$ ; the tiles here will be drawn only on game table
sta zp:T_COUNTER$
lda #3
sta zp:T_LINE_COUNT$
; Convert the coordinates
ldx zp:P_X$
lda X_To_TileNum_Map,x
sta zp:P_X$
ldx zp:P_Y$
lda Y_To_TileNum_Map,x
sta zp:P_Y$
; Calculate the beginning of the tile section we're interested in
clc
lda #NUM_TILE_OFFSET
adc zp:P_TYPE$
asl a
asl a
asl a
sta zp:P_TYPE$
; Draw the tile
DrawNextLine$:
jsr vdp_point_to_vram_xy
ldx zp:T_COUNTER$
ldy #4
SetTile$:
clc
lda TileNum_Offset_Map,x
adc zp:P_TYPE$
sta VDP_MEM
nop
inx
dey
bne SetTile$
stx zp:T_COUNTER$
inc zp:P_Y$
dec zp:T_LINE_COUNT$
bne DrawNextLine$
rts
;;;;;;;;;;;;;;;;;;
.section data,data
TileNum_Offset_Map: ; Offset from the beginning of the selected tilemap section, of the tiles composing the numeric-2048 tile
.byte 0x00, 0x04, 0x04, 0x02 ; First line
.byte 0x04, 0x04, 0x04, 0x04 ; Second
.byte 0x01, 0x04, 0x04, 0x03 ; Third and last
; The following maps convert between X and Y in the game grid into the tile map grid
X_To_TileNum_Map:
.byte 0x01, 0x06, 0x0B, 0x10, 0x15
Y_To_TileNum_Map:
.byte 0x01, 0x05, 0x09, 0x0D, 0x11
; The following maps convert between the tile number and the corresponding X and Y coordinates
TileNum_To_X_Map:
.byte 0x00, 0x01, 0x02, 0x03, 0x04
.byte 0x00, 0x01, 0x02, 0x03, 0x04
.byte 0x00, 0x01, 0x02, 0x03, 0x04
.byte 0x00, 0x01, 0x02, 0x03, 0x04
.byte 0x00, 0x01, 0x02, 0x03, 0x04
TileNum_To_Y_Map:
.byte 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x01, 0x01, 0x01, 0x01, 0x01
.byte 0x02, 0x02, 0x02, 0x02, 0x02
.byte 0x03, 0x03, 0x03, 0x03, 0x03
.byte 0x04, 0x04, 0x04, 0x04, 0x04
;;;;;;;;;;;;;;;;;;
.public vdp_draw_numtile
.public vdp_clear_gamegrid
.public vdp_clear_dialog
.public vdp_redraw_tiles
.public vdp_draw_joystick

View file

@ -1,5 +1,5 @@
#ifndef _GRAPH_MISC_DATA_HEADER_ #ifndef _HGR_GRAPH_MISC_DATA_HEADER_
#define _GRAPH_MISC_DATA_HEADER_ #define _HGR_GRAPH_MISC_DATA_HEADER_
#include <stdint.h> #include <stdint.h>
@ -15,4 +15,4 @@ extern const uint8_t moves_pic_data[];
#define HIGH_PIC_HEIGHT 14 #define HIGH_PIC_HEIGHT 14
extern const uint8_t high_pic_data[]; extern const uint8_t high_pic_data[];
#endif /* _GRAPH_MISC_DATA_HEADER_ */ #endif /* _HGR_GRAPH_MISC_DATA_HEADER_ */

8
src/hgr_graphics.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef _HGR_GRAPHICS_HEADER_
#define _HGR_GRAPHICS_HEADER_
#define SCREEN_HEIGHT 192
#define SCREEN_WIDTH_BYTES 128
#define BYTES_PER_LINE 40
#endif /* _HGR_GRAPHICS_HEADER_ */

View file

@ -1,6 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include "utility.h" #include "hgr_graphics.h"
const uint16_t line_offset_map[SCREEN_HEIGHT] = { const uint16_t line_offset_map[SCREEN_HEIGHT] = {
0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0080, 0x0480, 0x0880, 0x0C80, 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0080, 0x0480, 0x0880, 0x0C80,

10
src/hgr_line_data.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef _HGR_LINE_DATA_HEADER_
#define _HGR_LINE_DATA_HEADER_
#include <stdint.h>
#include "hgr_graphics.h"
extern const uint16_t line_offset_map[SCREEN_HEIGHT];
#endif /* _HGR_LINE_DATA_HEADER_ */

View file

@ -3,11 +3,16 @@
#include <calypsi/intrinsics6502.h> #include <calypsi/intrinsics6502.h>
#include "vdp_utils.h"
#include "monitor_subroutines.h" #include "monitor_subroutines.h"
#include "utility.h" #include "utility.h"
#include "input.h"
#include "mem_map.h" #include "mem_map.h"
#include "shared_page.h" #include "shared_page.h"
#include "module_list.h"
// External initialization requirements // External initialization requirements
#pragma require __preserve_zp #pragma require __preserve_zp
#pragma require __data_initialization_needed #pragma require __data_initialization_needed
@ -16,6 +21,7 @@ static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
void main(void) { void main(void) {
uint8_t wait_count = 0x40; uint8_t wait_count = 0x40;
uint8_t vdp_detected;
// Initialize the register for LFSR // Initialize the register for LFSR
lfsr_init(0xF00D); lfsr_init(0xF00D);
@ -23,7 +29,8 @@ void main(void) {
// Clear the memory used to pass parameters to the next module // Clear the memory used to pass parameters to the next module
memset((void*)(shared_page->module_data), 0, MODULE_DATA_SIZE); memset((void*)(shared_page->module_data), 0, MODULE_DATA_SIZE);
// TODO: Detect expansion hardware, and choose what to load according to that // Detect expansion hardware, and choose what to load according to that
vdp_detected = vdp_detect() && !read_any_key();
// Delay a bit // Delay a bit
while(wait_count--) WAIT(0xFF); while(wait_count--) WAIT(0xFF);
@ -33,7 +40,7 @@ void main(void) {
memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE); memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE);
shared_page->master_command = MASTER_COMMAND_NONE; shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = 3; // DLOG module is next! shared_page->next_module_idx = vdp_detected ? MODULE_INIT_VDP : MODULE_DLOG; // If VDP is detected, load the module to initialize it, otherwise DLOG module is next!
return; return;
} }

View file

@ -1,9 +0,0 @@
#ifndef _LINE_DATA_HEADER_
#define _LINE_DATA_HEADER_
#include <stdint.h>
#include "utility.h"
extern const uint16_t line_offset_map[SCREEN_HEIGHT];
#endif /* _LINE_DATA_HEADER */

View file

@ -1,210 +0,0 @@
#include <stdint.h>
/*__attribute__((section("loadscreen")))*/ const uint8_t __loading_screen[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x30, 0x40, 0x2D, 0x36, 0x18, 0x18, 0x4C, 0x01, 0x0C, 0x06, 0x18, 0x43, 0x19, 0x6C, 0x30, 0x43, 0x0D, 0x06, 0x60, 0x00, 0x06, 0x07, 0x00, 0x33, 0x18, 0x6C, 0x30, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x66, 0x30, 0x18, 0x43, 0x01, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7F, 0x7F, 0x1F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x48, 0x00, 0x10, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78,
0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x58, 0x61, 0x06, 0x03, 0x63, 0x30, 0x43,
0x6D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x1F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F,
0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x01, 0x7E, 0x7F, 0x01, 0x0C, 0x54, 0x28, 0x57, 0x0A, 0x04, 0x06, 0x6A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00,
0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x1F,
0x40, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x39, 0x4C, 0x3F, 0x04, 0x00, 0x00,
0x00, 0x20, 0x7E, 0x39, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x1F, 0x78, 0x01, 0x02, 0x00, 0x11, 0x6E, 0x45, 0x2B, 0x55, 0x2A, 0x07, 0x00, 0x2A, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x7F, 0x7F, 0x43, 0x7F, 0x7F, 0x7F, 0x19, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x00,
0x00, 0x10, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x02, 0x7E, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00, 0x40, 0x07, 0x20, 0x00, 0x00, 0x00, 0x70,
0x01, 0x0F, 0x18, 0x7C, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x14, 0x21, 0x07, 0x00, 0x78, 0x0A, 0x02, 0x00, 0x1C, 0x05, 0x49, 0x29, 0x24, 0x21, 0x28, 0x04, 0x27, 0x29, 0x04, 0x25, 0x24, 0x13,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x1A, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x60, 0x30, 0x7E, 0x2D, 0x76, 0x1F, 0x18, 0x4C, 0x01, 0x0C,
0x66, 0x1F, 0x43, 0x79, 0x6F, 0x30, 0x03, 0x7C, 0x07, 0x40, 0x1F, 0x06, 0x03, 0x7C, 0x33, 0x78, 0x6F, 0x30, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00, 0x70, 0x01, 0x0F, 0x18, 0x7C, 0x01, 0x02, 0x00, 0x00, 0x10, 0x70, 0x01, 0x60, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x20, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x60, 0x5F, 0x61, 0x06, 0x03, 0x63, 0x30, 0x03, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00,
0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3E, 0x7C, 0x03, 0x04, 0x5C, 0x38, 0x51, 0x3A, 0x07, 0x00, 0x2A, 0x1D, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07,
0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x40, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x43, 0x4F, 0x63, 0x04, 0x00, 0x00, 0x00, 0x20, 0x7E, 0x33, 0x58, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0F, 0x70, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00,
0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x79, 0x7F, 0x7F, 0x40, 0x7F, 0x7F, 0x7F, 0x19, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x03, 0x00, 0x00,
0x20, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F,
0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x02, 0x7E, 0x1F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x60, 0x03, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x66, 0x30, 0x1E, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x12, 0x13, 0x19, 0x08, 0x00, 0x48, 0x06, 0x01, 0x0E, 0x24, 0x43, 0x28, 0x4A, 0x24, 0x21, 0x2E, 0x04, 0x29, 0x29, 0x65, 0x25, 0x24, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x12, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, 0x60, 0x30, 0x43, 0x2D, 0x36, 0x00, 0x18, 0x4C, 0x01, 0x0C, 0x36, 0x18, 0x43, 0x19, 0x60, 0x30, 0x43, 0x0D, 0x30, 0x00, 0x30, 0x06, 0x03, 0x06, 0x33, 0x18,
0x60, 0x30, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x00, 0x70, 0x01, 0x0F, 0x18, 0x7C, 0x01, 0x00, 0x00, 0x00,
0x08, 0x08, 0x7F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F,
0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x60, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00,
0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x19,
0x33, 0x58, 0x61, 0x06, 0x03, 0x63, 0x30, 0x43, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x40, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01,
0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1E, 0x40, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x40, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x67, 0x43, 0x3D, 0x04, 0x00, 0x00, 0x00, 0x20, 0x04, 0x73, 0x3F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7F, 0x78, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01,
0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x1F, 0x40, 0x7F, 0x7F, 0x7F, 0x19, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00, 0x20, 0x20, 0x01, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x09, 0x78, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x17, 0x00, 0x01, 0x00, 0x17, 0x20, 0x01, 0x74, 0x5E,
0x74, 0x02, 0x00, 0x22, 0x01, 0x00, 0x1A, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F,
0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x79, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x02, 0x7E, 0x1F, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20,
0x05, 0x60, 0x03, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x66, 0x30, 0x1E, 0x03, 0x00, 0x00, 0x03, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x56, 0x10, 0x05, 0x08, 0x00, 0x48, 0x4A, 0x00, 0x00, 0x24, 0x25, 0x28, 0x0A, 0x25, 0x21,
0x29, 0x04, 0x29, 0x29, 0x15, 0x39, 0x24, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x3F,
0x7E, 0x2D, 0x66, 0x0F, 0x70, 0x47, 0x01, 0x7C, 0x63, 0x1F, 0x5E, 0x71, 0x67, 0x30, 0x7E, 0x78, 0x33, 0x60, 0x1F, 0x3C, 0x03, 0x7C, 0x63, 0x73, 0x47, 0x3F, 0x7E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x02, 0x3F, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x0C, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00,
0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x40, 0x19, 0x63, 0x5F, 0x61, 0x7C, 0x03, 0x46, 0x1F, 0x7E, 0x4C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07,
0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x78, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3E, 0x40, 0x03, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60,
0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00,
0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x63, 0x19, 0x30, 0x41, 0x01, 0x27, 0x19, 0x3F, 0x4E, 0x01, 0x73, 0x1C, 0x46, 0x29, 0x06, 0x00, 0x00, 0x08, 0x76, 0x40, 0x1F, 0x04, 0x00, 0x00, 0x00, 0x40, 0x7C, 0x63, 0x1F, 0x00, 0x00, 0x00,
0x60, 0x00, 0x7F, 0x7F, 0x01, 0x42, 0x0B, 0x40, 0x60, 0x15, 0x70, 0x08, 0x00, 0x00, 0x00, 0x01, 0x5D, 0x17, 0x5D, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00,
0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x1F,
0x40, 0x7F, 0x7F, 0x7F, 0x19, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x4B, 0x0E, 0x03, 0x16, 0x18, 0x10, 0x26, 0x19, 0x11, 0x0E, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x15, 0x6E, 0x55, 0x03, 0x11, 0x2E, 0x01, 0x12, 0x52, 0x25, 0x04, 0x00, 0x2E, 0x5C, 0x3A, 0x0B, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x79, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x7C, 0x3F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x70, 0x61, 0x30, 0x18, 0x73, 0x01, 0x00, 0x03, 0x00,
0x60, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x67, 0x3C, 0x07, 0x00, 0x48, 0x52, 0x07, 0x00, 0x24, 0x69, 0x4B, 0x6B, 0x18, 0x2E, 0x2E, 0x39, 0x29, 0x49, 0x62, 0x21, 0x19, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x06, 0x40, 0x0F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F,
0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01,
0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66,
0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x41, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x40, 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x78, 0x3F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7E, 0x7F, 0x03, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01,
0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x14, 0x24, 0x10, 0x27, 0x02, 0x69, 0x24, 0x49,
0x52, 0x00, 0x14, 0x25, 0x09, 0x1A, 0x01, 0x00, 0x00, 0x08, 0x36, 0x18, 0x07, 0x08, 0x00, 0x00, 0x00, 0x40, 0x7E, 0x01, 0x00, 0x01, 0x00, 0x00, 0x60, 0x00, 0x7E, 0x7F, 0x01, 0x42, 0x22, 0x5D, 0x20, 0x31, 0x50, 0x2E, 0x3C, 0x77, 0x6E, 0x41,
0x44, 0x34, 0x09, 0x01, 0x40, 0x38, 0x57, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F,
0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x00, 0x40, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x20, 0x05, 0x00, 0x00, 0x49,
0x52, 0x04, 0x72, 0x24, 0x30, 0x29, 0x25, 0x51, 0x52, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3F, 0x00, 0x20, 0x01, 0x00, 0x75,
0x2A, 0x5D, 0x02, 0x71, 0x28, 0x05, 0x72, 0x52, 0x26, 0x04, 0x00, 0x2A, 0x45, 0x2A, 0x1A, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F,
0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00,
0x01, 0x60, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66,
0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x61, 0x30, 0x18, 0x73, 0x01, 0x02, 0x03, 0x00, 0x60, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x04, 0x00, 0x09, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x0F, 0x00, 0x00, 0x00,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07,
0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x7C, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x03, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x3F, 0x00, 0x08, 0x1C, 0x00,
0x10, 0x02, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00,
0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x3B, 0x02, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x01, 0x5C, 0x00, 0x00, 0x00,
0x40, 0x00, 0x7E, 0x7F, 0x03, 0x04, 0x00, 0x75, 0x6E, 0x5D, 0x7B, 0x7D, 0x38, 0x07, 0x00, 0x2A, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00,
0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x7F, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x78,
0x43, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x20, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x51, 0x14, 0x3C, 0x10, 0x69, 0x03, 0x29, 0x24, 0x49, 0x52, 0x00, 0x17, 0x25, 0x4F, 0x0B, 0x02, 0x00, 0x00, 0x08, 0x6E, 0x1F, 0x00, 0x08, 0x00, 0x00,
0x00, 0x40, 0x1E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x7C, 0x7F, 0x00, 0x42, 0x2A, 0x55, 0x60, 0x14, 0x50, 0x2A, 0x24, 0x15, 0x2A, 0x41, 0x5C, 0x54, 0x09, 0x01, 0x40, 0x2B, 0x75, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x00, 0x40, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x40, 0x1F, 0x00, 0x04, 0x00, 0x00, 0x49, 0x52, 0x07, 0x12, 0x3D, 0x10, 0x29, 0x25, 0x55, 0x52, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x0A, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x01, 0x01, 0x00, 0x53, 0x2A, 0x51, 0x02, 0x51, 0x2A, 0x03, 0x12, 0x52, 0x24, 0x04, 0x06, 0x2A, 0x45, 0x2A, 0x22, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, 0x7F, 0x7F, 0x43, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x40, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C,
0x66, 0x30, 0x18, 0x43, 0x01, 0x03, 0x03, 0x00, 0x60, 0x7F, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x04, 0x60, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01,
0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x7C, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x78, 0x7F, 0x00, 0x08, 0x44, 0x3B, 0x17, 0x38, 0x07, 0x00, 0x2A, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01,
0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x67, 0x10, 0x02, 0x00, 0x00, 0x00, 0x20, 0x43, 0x61, 0x4F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7F, 0x7F, 0x01, 0x04, 0x00, 0x55, 0x2A, 0x15, 0x2A, 0x55, 0x2A, 0x05, 0x00, 0x2E,
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78,
0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x78, 0x43, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x51,
0x14, 0x04, 0x10, 0x29, 0x00, 0x27, 0x24, 0x49, 0x4E, 0x40, 0x74, 0x1C, 0x21, 0x0A, 0x24, 0x00, 0x00, 0x10, 0x6C, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x20, 0x00, 0x78, 0x3F, 0x00, 0x42, 0x4B, 0x44,
0x20, 0x15, 0x70, 0x4A, 0x2A, 0x15, 0x22, 0x41, 0x44, 0x14, 0x09, 0x41, 0x41, 0x28, 0x45, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F,
0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x00, 0x40, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00,
0x04, 0x60, 0x1F, 0x00, 0x02, 0x00, 0x00, 0x71, 0x4E, 0x00, 0x12, 0x05, 0x10, 0x29, 0x25, 0x55, 0x12, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x7F, 0x01, 0x00, 0x55, 0x6E, 0x5D, 0x02, 0x57, 0x2E, 0x05, 0x14, 0x5E, 0x24, 0x02, 0x00, 0x2E, 0x5D, 0x2B, 0x1A, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00, 0x00, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x63, 0x1C, 0x07, 0x00, 0x48, 0x02,
0x00, 0x00, 0x04, 0x01, 0x60, 0x03, 0x00, 0x20, 0x20, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x7C, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x66, 0x30, 0x18, 0x43, 0x41, 0x7F, 0x03, 0x00, 0x30, 0x78, 0x7F, 0x7F, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x04, 0x03, 0x10, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78,
0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x60, 0x4F, 0x3F, 0x7C, 0x03, 0x63, 0x30, 0x7E,
0x4C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x78, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x7F, 0x7F,
0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x33, 0x66, 0x7C, 0x33, 0x66, 0x4C, 0x19, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x01, 0x7E, 0x7F, 0x01, 0x0C, 0x44, 0x22, 0x75, 0x0A, 0x01, 0x00, 0x2E, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x0F, 0x78, 0x7F, 0x01,
0x3F, 0x00, 0x70, 0x7F, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x60, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x7F, 0x1F,
0x40, 0x0F, 0x00, 0x7C, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x6F, 0x1C, 0x02, 0x00, 0x00,
0x00, 0x20, 0x40, 0x71, 0x47, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7F, 0x7F, 0x01, 0x04, 0x00, 0x17, 0x0A, 0x45, 0x2A, 0x55, 0x2A, 0x04, 0x06, 0x6A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x0F, 0x78, 0x03, 0x00, 0x3F, 0x60, 0x7F, 0x07, 0x7C, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x7F, 0x1F, 0x00, 0x78, 0x7F, 0x01, 0x7F, 0x7F, 0x0F, 0x78, 0x7F, 0x01, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x7F, 0x7F, 0x43, 0x7F, 0x7F, 0x7F, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x64, 0x19, 0x20, 0x49, 0x01, 0x21, 0x18, 0x49, 0x02, 0x01, 0x17, 0x04, 0x46, 0x0B, 0x23, 0x00,
0x00, 0x10, 0x0C, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x42, 0x28, 0x5D, 0x60, 0x35, 0x50, 0x0E, 0x39, 0x75, 0x6E, 0x01, 0x45, 0x17, 0x49, 0x00, 0x40, 0x38, 0x75, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01,
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x00, 0x40, 0x0F, 0x00, 0x70, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x7C, 0x1F, 0x00, 0x02, 0x00, 0x00, 0x42, 0x02, 0x03, 0x14, 0x19, 0x10, 0x26, 0x19, 0x4A,
0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x40, 0x7F, 0x7F, 0x7F,
0x03, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x03, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00, 0x40, 0x07, 0x20, 0x00, 0x00, 0x00, 0x70,
0x01, 0x0F, 0x18, 0x7C, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x14, 0x21, 0x01, 0x00, 0x48, 0x52, 0x07, 0x00, 0x04, 0x69, 0x13, 0x44, 0x19, 0x0E, 0x26, 0x38, 0x01, 0x27, 0x64, 0x18, 0x18, 0x65,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x3F, 0x7E, 0x7C, 0x63, 0x0F, 0x70, 0x67, 0x0F, 0x7C,
0x63, 0x4F, 0x5F, 0x71, 0x67, 0x1F, 0x7E, 0x78, 0x03, 0x40, 0x1F, 0x3F, 0x7B, 0x7C, 0x79, 0x73, 0x47, 0x3F, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x7C, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x66, 0x30, 0x18, 0x43, 0x41, 0x7F, 0x01, 0x00, 0x10, 0x00, 0x7E, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View file

@ -24,7 +24,7 @@
static uint8_t *module_page = (uint8_t*)MODULE_PAGE; static uint8_t *module_page = (uint8_t*)MODULE_PAGE;
static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE; static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE;
#define FILE_LIST_LEN 5 #define FILE_LIST_LEN 10
#define FNAME_LEN 6 #define FNAME_LEN 6
#define STATE_FILE_IDX 1 #define STATE_FILE_IDX 1
@ -34,9 +34,14 @@ static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE;
static const uint8_t file_table[FILE_LIST_LEN][FNAME_LEN] = { static const uint8_t file_table[FILE_LIST_LEN][FNAME_LEN] = {
{ 0x80 | 'L', 0x80 | 'O', 0x80 | 'A', 0x80 | 'D', 0x80 | 'S', 0x00}, // LOADS (this is not an executable, but will be used to show the loading screen). { 0x80 | 'L', 0x80 | 'O', 0x80 | 'A', 0x80 | 'D', 0x80 | 'S', 0x00}, // LOADS (this is not an executable, but will be used to show the loading screen).
{ 0x80 | 'S', 0x80 | 'T', 0x80 | 'A', 0x80 | 'T', 0x80 | 'E', 0x00}, // STATE (this is not an executable, but will be used to save/load the game and scores). { 0x80 | 'S', 0x80 | 'T', 0x80 | 'A', 0x80 | 'T', 0x80 | 'E', 0x00}, // STATE (this is not an executable, but will be used to save/load the game and scores).
{ 0x80 | 'I', 0x80 | 'N', 0x80 | 'T', 0x80 | 'R', 0x80 | 'O', 0x00}, // INTRO (this executable will show the initial presentation picture) { 0x80 | 'I', 0x80 | 'N', 0x80 | 'T', 0x80 | 'R', 0x80 | 'O', 0x00}, // INTRO (this executable will detect hardware and load the appropriate followup module)
{ 0x80 | 'D', 0x80 | 'L', 0x80 | 'O', 0x80 | 'G', 0xA0, 0x00}, // DLOG (startup, win, lose dialogs) { 0x80 | 'D', 0x80 | 'L', 0x80 | 'O', 0x80 | 'G', 0xA0, 0x00}, // DLOG (startup, win, lose dialogs)
{ 0x80 | 'G', 0x80 | 'A', 0x80 | 'M', 0x80 | 'E', 0xA0, 0x00}, // GAME (the actual game) { 0x80 | 'G', 0x80 | 'A', 0x80 | 'M', 0x80 | 'E', 0xA0, 0x00}, // GAME (the actual game)
{ 0x80 | 'D', 0x80 | 'E', 0x80 | 'M', 0x80 | 'O', 0xA0, 0x00}, // DEMO (automatic demo),
{ 0x80 | 'V', 0x80 | 'D', 0x80 | 'P', 0x80 | 'I', 0x80 | 'N', 0x00}, // VDPIN (Loads VDP resources),
{ 0x80 | 'V', 0x80 | 'D', 0x80 | 'D', 0x80 | 'L', 0x80 | 'G', 0x00}, // VDDLG (VDP startup, win, lose dialogs),
{ 0x80 | 'V', 0x80 | 'D', 0x80 | 'G', 0x80 | 'A', 0x80 | 'M', 0x00}, // VDGAM (Game, VDP version),
{ 0x80 | 'V', 0x80 | 'D', 0x80 | 'D', 0x80 | 'E', 0x80 | 'M', 0x00}, // VDDEM (Demo, VDP version),
}; };
static uint8_t file_trksec[FILE_LIST_LEN][2]; // This will hold track/sector for initial ts list sector for every one of the listed files. Populated at startup. static uint8_t file_trksec[FILE_LIST_LEN][2]; // This will hold track/sector for initial ts list sector for every one of the listed files. Populated at startup.
@ -46,12 +51,16 @@ static uint16_t file_load_address[FILE_LIST_LEN] = { // This will hold the load
MODULE_PAGE, MODULE_PAGE,
MODULE_PAGE, MODULE_PAGE,
MODULE_PAGE, MODULE_PAGE,
MODULE_PAGE,
MODULE_PAGE,
MODULE_PAGE,
MODULE_PAGE,
MODULE_PAGE,
}; };
static void init(void); static void init(void);
static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file); static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file);
static uint8_t fill_trksec_list(uint8_t* cur_trk); static uint8_t fill_trksec_list(uint8_t* cur_trk);
static uint8_t calculate_crc8(uint8_t* data, uint8_t len);
// Low level initialization // Low level initialization
static void init(void) { static void init(void) {
@ -117,42 +126,19 @@ static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file) {
if (!initialized_correctly) __asm volatile(" brk\n":::); if (!initialized_correctly) __asm volatile(" brk\n":::);
} }
#define CRC8RDALLAS_POLY 0x31
static uint8_t calculate_crc8(uint8_t* data, uint8_t len) {
uint8_t crc = 0;
for(uint8_t data_idx = 0; data_idx < len; data_idx++) {
uint8_t carry;
uint8_t d = data[data_idx];
for (uint8_t i = 8; i > 0; i--) {
carry = (crc & 0x80);
crc <<= 1;
if (d & 1) crc |= 1;
d >>= 1;
if (carry) crc ^= CRC8RDALLAS_POLY;
}
}
return crc;
}
__task int main(void) { __task int main(void) {
uint8_t cur_trk = 0; uint8_t cur_trk = 0;
uint8_t cur_file = 0; uint8_t cur_file = 0;
uint8_t keep_going = 1; uint8_t keep_going = 1;
__disable_interrupts(); __disable_interrupts(); // Keep the interrupts disabled in the master module
init(); init();
init_floppy_data(&cur_trk, &cur_file); init_floppy_data(&cur_trk, &cur_file);
__enable_interrupts();
do { do {
if((cur_file != shared_page->next_module_idx) || (shared_page->master_command == MASTER_COMMAND_SAVE)) { if((cur_file != shared_page->next_module_idx) || (shared_page->master_command == MASTER_COMMAND_SAVE)) {
__disable_interrupts();
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0); dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0);
// Check if we need to load another module // Check if we need to load another module
@ -170,7 +156,6 @@ __task int main(void) {
} }
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET); dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
__enable_interrupts();
} }
shared_page->master_command = MASTER_COMMAND_NONE; shared_page->master_command = MASTER_COMMAND_NONE;

View file

@ -3,6 +3,9 @@
#include <stdint.h> #include <stdint.h>
#define NMI_HANDLER_ADDRESS 0x03FB
#define IRQ_HANDLER_ADDRESS 0x03FE
#define ROM_MONITOR 0xFF61 #define ROM_MONITOR 0xFF61
#define ZP_WNDLFT 0x0020 // 0, left column of scroll window #define ZP_WNDLFT 0x0020 // 0, left column of scroll window

13
src/module_list.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef _MODULE_LIST_HEADER_
#define _MODULE_LIST_HEADER_
#define MODULE_DLOG 3
#define MODULE_GAME 4
#define MODULE_DEMO 5
#define MODULE_INIT_VDP 6
#define MODULE_DLOG_VDP 7
#define MODULE_GAME_VDP 8
#define MODULE_DEMO_VDP 9
#endif /* _MODULE_LIST_HEADER_ */

View file

@ -2,10 +2,22 @@
#include "mem_registers.h" #include "mem_registers.h"
#include "monitor_subroutines.h" #include "monitor_subroutines.h"
#include "line_data.h"
void decbuf_to_ascii(uint8_t len, uint8_t *buf) {
for(uint8_t idx = 0; idx < len; idx++) {
buf[idx] += 0x30;
}
// Swap the order in the array
uint8_t tmp;
for(uint8_t idx = 0; idx < len/2; idx++) {
tmp = buf[idx];
buf[idx] = buf[(len - 1) - idx];
buf[(len - 1) - idx] = tmp;
}
}
void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf) { void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf) {
for(uint8_t idx = 0; idx < len; idx++) { for(uint8_t idx = 0; idx < len; idx++) {
buf[idx] = n % 10; buf[idx] = n % 10;
n /= 10; n /= 10;
@ -44,29 +56,22 @@ uint16_t lfsr_update(void) {
return *lfsr; return *lfsr;
} }
/* #define CRC8RDALLAS_POLY 0x31
void print_line(const char* line, uint8_t off_x, uint8_t off_y) { uint8_t calculate_crc8(uint8_t* data, uint8_t len) {
POKEZ(ZP_CV, off_y); uint8_t crc = 0;
uint8_t cur_ch; for(uint8_t data_idx = 0; data_idx < len; data_idx++) {
for(cur_ch = 0; line[cur_ch]; cur_ch++) { uint8_t carry;
SETNORM(); uint8_t d = data[data_idx];
POKEZ(ZP_CH, cur_ch + off_x);
COUT1(line[cur_ch]|0x80); for (uint8_t i = 8; i > 0; i--) {
carry = (crc & 0x80);
SETINV(); crc <<= 1;
COUT1(' '|0x80); if (d & 1) crc |= 1;
d >>= 1;
for(uint8_t snd_loop = 0x70; snd_loop; snd_loop--) PEEK(IO_SPEAKER); if (carry) crc ^= CRC8RDALLAS_POLY;
}
WAIT(0xBE);
} }
SETNORM(); return crc;
POKEZ(ZP_CH, cur_ch + off_x);
COUT1(' '|0x80);
WAIT(0xFF);
} }
*/

View file

@ -3,10 +3,6 @@
#include <stdint.h> #include <stdint.h>
#define SCREEN_HEIGHT 192
#define SCREEN_WIDTH_BYTES 128
#define BYTES_PER_LINE 40
#define PEEKZ(a) (*(volatile uint8_t* __attribute__((zpage)))(a)) #define PEEKZ(a) (*(volatile uint8_t* __attribute__((zpage)))(a))
#define POKEZ(a, b) ((*(volatile uint8_t* __attribute__((zpage)))(a)) = b) #define POKEZ(a, b) ((*(volatile uint8_t* __attribute__((zpage)))(a)) = b)
@ -24,11 +20,12 @@
// to store the lfsr_update // to store the lfsr_update
#define LFSR_REGISTER_ADDRESS 0x0356 #define LFSR_REGISTER_ADDRESS 0x0356
void decbuf_to_ascii(uint8_t len, uint8_t *buf);
void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf); void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf);
uint8_t bit_reverse(uint8_t b); uint8_t bit_reverse(uint8_t b);
uint8_t bit_count(uint8_t b); uint8_t bit_count(uint8_t b);
void lfsr_init(uint16_t reg); void lfsr_init(uint16_t reg);
uint16_t lfsr_update(void); uint16_t lfsr_update(void);
//void print_line(const char* line, uint8_t off_x, uint8_t off_y); uint8_t calculate_crc8(uint8_t* data, uint8_t len);
#endif /* _UTILITY_HEADER_ */ #endif /* _UTILITY_HEADER_ */

197
src/vddem_main.c Normal file
View file

@ -0,0 +1,197 @@
#include <stubs.h>
#include <string.h>
#include <calypsi/intrinsics6502.h>
#include "vdp_utils.h"
#include "game_vdp_graphics.h"
#include "monitor_subroutines.h"
#include "utility.h"
#include "mem_map.h"
#include "mem_registers.h"
#include "shared_page.h"
#include "state_page.h"
#include "dlog_data.h"
#include "game_data.h"
#include "input.h"
#include "game_logic.h"
#include "monitor_subroutines.h"
#include "sound.h"
#include "module_list.h"
// External initialization requirements
#pragma require __preserve_zp
#pragma require __data_initialization_needed
#define HSCORE_TEXT_X 27
#define HSCORE_TEXT_Y 13
#define SCORE_TEXT_X 27
#define SCORE_TEXT_Y 4
#define MOVES_TEXT_X 27
#define MOVES_TEXT_Y 8
#define BOTTOM_TEXT_X 1
#define BOTTOM_TEXT_Y 23
#define MAX_DEMO_MOVES 30
#define RUNS_TO_SKIP 4000
static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
static uint8_t text_buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static volatile uint8_t key_pressed = 0;
void main(void) {
uint16_t moves_count = 0;
uint16_t score = 0;
int8_t done = 0;
__disable_interrupts(); // Make sure the interrupts are disabled
// By default, once we return from this, return to the DLOG module and give the master no command to execute
shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = MODULE_DLOG_VDP; // Go to the DLOG module
dlog_data *dld = (dlog_data *)(shared_page->module_data);
dlog_data *gad = (dlog_data *)(shared_page->module_data);
// Make sure the buffers are pointing to the correct memory and are clear
vdp_hide_sprites();
vdp_clear_gamegrid();
vdp_switch_nt(0); // Make sure VDP shows the gamegrid
// Setup the IRQ handler
POKEW(IRQ_HANDLER_ADDRESS, (uint16_t)vdp_irq_handler);
// Reset the game, calculate the initial score depending on which tiles we randomly get
score = reset_game();
// Draw the initial state of the game
vdp_print_string(0, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, "DEMO MODE Press any key to exit");
num_to_decbuf(state_page->hi_score, 5, text_buf); // High score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, HSCORE_TEXT_X, HSCORE_TEXT_Y, (char*)text_buf);
num_to_decbuf(moves_count, 5, text_buf); // Moves count
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf);
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
vdp_draw_joystick(JS_POS_CENTER); // Center the joystick
vdp_redraw_tiles(get_front_grid());
uint16_t lfsr;
uint16_t current_run = 0;
__enable_interrupts();
while(1) { // Game loop
lfsr = lfsr_update();
// Any key will let us out of this, wait some time for a keypress
__disable_interrupts();
if(read_any_key()) {
snd_mod_button();
done = 1;
}
if(!done && current_run <= RUNS_TO_SKIP) {
current_run++;
__enable_interrupts();
continue;
}
__disable_interrupts();
current_run = 0;
if(!done) {
switch((lfsr & 0x0003) + 1) {
case K_UP:
SND_TAP();
vdp_draw_joystick(JS_POS_UP);
done = step_game(GAME_STEP_UP);
break;
case K_DOWN:
SND_TAP();
vdp_draw_joystick(JS_POS_DOWN);
done = step_game(GAME_STEP_DOWN);
break;
case K_LEFT:
SND_TAP();
vdp_draw_joystick(JS_POS_LEFT);
done = step_game(GAME_STEP_LEFT);
break;
case K_RIGHT:
SND_TAP();
vdp_draw_joystick(JS_POS_RIGHT);
done = step_game(GAME_STEP_RIGHT);
break;
default:
__enable_interrupts();
continue; // Do nothing, loop again
}
}
// Increase the count of moves we made (unless we lost or reset the game)
if(done >= 0) {
moves_count++;
done = done || (moves_count >= MAX_DEMO_MOVES);
}
// Draw the number of moves
num_to_decbuf(moves_count, 5, text_buf);
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf);
// Draw the moved tiles
vdp_redraw_tiles(get_front_grid());
// If we have won, or we got a reset request, break out of this loop
if(done) {
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
break;
}
// Unable to add a tile: we ran out of space and lost!!!
uint8_t random_tile_off = add_random_tile();
if(!random_tile_off) {
done = -1; // Lost the game
break;
}
score = calculate_score();
// Draw the score
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
vdp_redraw_tiles(get_front_grid());
vdp_draw_joystick(JS_POS_CENTER);
__enable_interrupts();
}
__disable_interrupts();
// Always go back to the start dialog
dld->mode = DLOG_MODE_START;
dld->score = 0;
vdp_redraw_tiles(get_front_grid());
return;
}

96
src/vddlg_main.c Normal file
View file

@ -0,0 +1,96 @@
#include <stubs.h>
#include <string.h>
#include <calypsi/intrinsics6502.h>
#include "vdp_utils.h"
#include "game_vdp_graphics.h"
#include "monitor_subroutines.h"
#include "utility.h"
#include "mem_map.h"
#include "shared_page.h"
#include "state_page.h"
#include "dlog_data.h"
#include "game_data.h"
#include "input.h"
#include "sound.h"
#include "module_list.h"
// External initialization requirements
#pragma require __preserve_zp
#pragma require __data_initialization_needed
static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
static uint8_t score_buf[7] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static char game_ver[5] = {'V', GAME_VER_CH0, GAME_VER_CH1, GAME_VER_CH2, '\0'};
#define WAIT_COUNTER_END 0xFFFF
void main(void) {
uint16_t wait_counter = 0;
dlog_data *dld = (dlog_data *)(shared_page->module_data);
game_data *gad = (game_data *)(shared_page->module_data);
__disable_interrupts(); // Make sure the interrupts are disabled
num_to_decbuf(state_page->hi_score, 6, score_buf);
decbuf_to_ascii(6, score_buf);
vdp_hide_sprites();
vdp_clear_dialog();
vdp_switch_nt(1); // Make sure VDP shows the correct dialog nametable
vdp_print_string(1, 6, 10, "Current High-Score :");
vdp_print_string(1, 13, 12, (char*)score_buf);
vdp_print_string(1, 5, 15, "Press any key to START");
vdp_print_string(1, 1, 23, "hkz@social.chinwag.org");
vdp_print_string(1, 28, 23, game_ver);
switch(dld->mode) {
case DLOG_MODE_WIN:
snd_festive();
vdp_print_string(1, 11, 8, "YOU WIN!!!");
break;
case DLOG_MODE_LOSE:
snd_sad_scale();
vdp_print_string(1, 11, 8, "GAME OVER!");
break;
default:
case DLOG_MODE_START:
vdp_print_string(1, 7, 8, "WELCOME TO TK2048!");
snd_start();
break;
};
if(dld->score > state_page->hi_score) { // New high-score. We need to save it.
state_page->hi_score = dld->score;
// Update the score!
num_to_decbuf(state_page->hi_score, 6, score_buf);
decbuf_to_ascii(6, score_buf);
vdp_print_string(1, 13, 12, (char*)score_buf);
vdp_print_string(1, 8, 13, "!NEW HIGH SCORE!");
shared_page->master_command = MASTER_COMMAND_SAVE;
} else {
shared_page->master_command = MASTER_COMMAND_NONE;
}
shared_page->next_module_idx = MODULE_GAME_VDP; // Go to the GAME module
gad->mode = GAME_MODE_NORMAL; // Set the proper start mode for the game
while(!read_any_key() && (wait_counter != WAIT_COUNTER_END)) {
wait_counter++;
lfsr_update();
}
if (wait_counter == WAIT_COUNTER_END) {
shared_page->next_module_idx = MODULE_DEMO_VDP; // Actually go to the DEMO module
return;
}
snd_mod_button();
return;
}

198
src/vdgam_main.c Normal file
View file

@ -0,0 +1,198 @@
#include <stubs.h>
#include <string.h>
#include <calypsi/intrinsics6502.h>
#include "vdp_utils.h"
#include "game_vdp_graphics.h"
#include "monitor_subroutines.h"
#include "utility.h"
#include "mem_map.h"
#include "mem_registers.h"
#include "shared_page.h"
#include "state_page.h"
#include "dlog_data.h"
#include "game_data.h"
#include "input.h"
#include "game_logic.h"
#include "monitor_subroutines.h"
#include "sound.h"
#include "module_list.h"
// External initialization requirements
#pragma require __preserve_zp
#pragma require __data_initialization_needed
#define HSCORE_TEXT_X 27
#define HSCORE_TEXT_Y 13
#define SCORE_TEXT_X 27
#define SCORE_TEXT_Y 4
#define MOVES_TEXT_X 27
#define MOVES_TEXT_Y 8
#define BOTTOM_TEXT_X 1
#define BOTTOM_TEXT_Y 23
#define WIN_SCORE_BONUS 10000
static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
static uint8_t text_buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void main(void) {
uint16_t moves_count = 0;
uint16_t score = 0;
int8_t done = 0;
__disable_interrupts(); // Make sure the interrupts are disabled
// By default, once we return from this, return to the DLOG module and give the master no command to execute
shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = MODULE_DLOG_VDP; // Go to the dialog module
dlog_data *dld = (dlog_data *)(shared_page->module_data);
dlog_data *gad = (dlog_data *)(shared_page->module_data);
// Make sure the buffers are pointing to the correct memory and are clear
vdp_hide_sprites();
vdp_clear_gamegrid();
vdp_switch_nt(0); // Make sure VDP shows the gamegrid
// Setup the IRQ handler
POKEW(IRQ_HANDLER_ADDRESS, (uint16_t)vdp_irq_handler);
// Reset the game, calculate the initial score depending on which tiles we randomly get
score = reset_game();
// Load the game
if(gad->mode == GAME_MODE_LOAD) {
gad->mode = GAME_MODE_NORMAL;
memcpy(get_front_grid(), (void*)(state_page->save_grid), GRID_SIDE * GRID_SIDE);
moves_count = state_page->saved_moves_count;
score = calculate_score();
// We loaded an empty save, just restart the game
if (!score) score = reset_game();
}
// Draw the initial state of the game
vdp_print_string(0, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, "hkz@social.chinwag.org 2025");
num_to_decbuf(state_page->hi_score, 5, text_buf); // High score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, HSCORE_TEXT_X, HSCORE_TEXT_Y, (char*)text_buf);
num_to_decbuf(moves_count, 5, text_buf); // Moves count
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf);
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
vdp_draw_joystick(JS_POS_CENTER); // Center the joystick
vdp_redraw_tiles(get_front_grid());
__enable_interrupts();
while(1) { // Game loop
lfsr_update();
__disable_interrupts();
switch(read_kb()) {
case K_UP:
SND_TAP();
vdp_draw_joystick(JS_POS_UP);
done = step_game(GAME_STEP_UP);
break;
case K_DOWN:
SND_TAP();
vdp_draw_joystick(JS_POS_DOWN);
done = step_game(GAME_STEP_DOWN);
break;
case K_LEFT:
SND_TAP();
vdp_draw_joystick(JS_POS_LEFT);
done = step_game(GAME_STEP_LEFT);
break;
case K_RIGHT:
SND_TAP();
vdp_draw_joystick(JS_POS_RIGHT);
done = step_game(GAME_STEP_RIGHT);
break;
case K_CTRL_R:
snd_mod_button();
score = 0; // We'll reset the score
done = -1;
break;
case K_CTRL_S: // The following two will return early
snd_mod_button();
memcpy((void*)(state_page->save_grid), get_front_grid(), GRID_SIDE * GRID_SIDE);
state_page->saved_moves_count = moves_count;
shared_page->master_command = MASTER_COMMAND_SAVE;
case K_CTRL_L:
snd_mod_button();
shared_page->next_module_idx = MODULE_GAME_VDP;
gad->mode = GAME_MODE_LOAD;
return;
default:
__enable_interrupts();
continue; // Do nothing, loop again
}
// Increase the count of moves we made (unless we lost or reset the game)
if(done >= 0) moves_count++;
num_to_decbuf(moves_count, 5, text_buf); // Moves count
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf);
// If we have won, or we got a reset request, break out of this loop
if(done) {
score += (done > 0) ? WIN_SCORE_BONUS : 0;
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
break;
}
// Unable to add a tile: we ran out of space and lost!!!
uint8_t random_tile_off = add_random_tile();
if(!random_tile_off) {
done = -1; // Lost the game
break;
}
score = calculate_score();
// Draw the score
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
vdp_redraw_tiles(get_front_grid());
vdp_draw_joystick(JS_POS_CENTER);
__enable_interrupts();
}
dld->mode = (done > 0) ? DLOG_MODE_WIN : DLOG_MODE_LOSE;
dld->score = score;
vdp_redraw_tiles(get_front_grid());
WAIT(0xFF);
__disable_interrupts();
return;
}

10
src/vdp.s Normal file
View file

@ -0,0 +1,10 @@
.rtmodel version,"1"
.rtmodel core,"6502"
;;; IO Ports
SLOT_OFFSET:.equ 0x40
VDP_BASE: .equ 0xC080 + SLOT_OFFSET
VDP_MEM: .equ VDP_BASE + 0x00
VDP_REG: .equ VDP_BASE + 0x01
.public VDP_MEM, VDP_REG

8
src/vdp_init.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef _VDP_INIT_HEADER_
#define _VDP_INIT_HEADER_
#include <stdint.h>
uint8_t vdp_init(void);
#endif /* _VDP_INIT_HEADER_ */

161
src/vdp_init.s Normal file
View file

@ -0,0 +1,161 @@
.rtmodel version,"1"
.rtmodel core,"6502"
.extern _Zp
.extern vdp_write_vram, vdp_write_registers
.extern SpriteAttributeTable, NT_P0, NT_P1
.extern VDP_MEM, VDP_REG
.section code,text
;;; vdp_init:
;;; Initialize the VDP processor
;;; Parameters: none
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 1, 2, 3, 4, 5
;;;
vdp_init:
T_SCRATCH_L$:.equ _Zp+0
T_SCRATCH_H$:.equ _Zp+1
; Get the board ready to accept the rest of the commands
lda #0x80 ; Disable interrupts and video, set 16K mode
sta VDP_REG
lda #0x81
sta VDP_REG
; Load the pattern table int 0x0800
lda #.byte0 PatternTable_Charset
sta zp:_Zp+0
lda #.byte1 PatternTable_Charset
sta zp:_Zp+1
lda #0x00
sta zp:_Zp+2
lda #0x08
sta zp:_Zp+3
lda #0x00
sta zp:_Zp+4
lda #0x08
sta zp:_Zp+5
jsr vdp_write_vram
; Load the Color Table into 0x0380
lda #.byte0 ColorTable
sta zp:_Zp+0
lda #.byte1 ColorTable
sta zp:_Zp+1
lda #0x20
sta zp:_Zp+2
lda #0x00
sta zp:_Zp+3
lda #0x80
sta zp:_Zp+4
lda #0x03
sta zp:_Zp+5
jsr vdp_write_vram
; Load the Sprite attribute table at 0x0300
lda #.byte0 SpriteAttributeTable
sta zp:_Zp+0
lda #.byte1 SpriteAttributeTable
sta zp:_Zp+1
lda #0x80
sta zp:_Zp+2
lda #0x00
sta zp:_Zp+3
lda #0x00
sta zp:_Zp+4
lda #0x03
sta zp:_Zp+5
jsr vdp_write_vram
; Load the Name Table for the Game Board at 0x0000
lda #.byte0 NameTable_GameBoard
sta zp:_Zp+0
lda #.byte1 NameTable_GameBoard
sta zp:_Zp+1
lda #0x00
sta zp:_Zp+2
lda #0x03
sta zp:_Zp+3
lda #0x00
sta zp:_Zp+4
lda NT_P0
sta zp:_Zp+5
jsr vdp_write_vram
; Load the Name Table for the Dialog Screens at 0x1400
lda #.byte0 NameTable_Dialog
sta zp:_Zp+0
lda #.byte1 NameTable_Dialog
sta zp:_Zp+1
lda #0x00
sta zp:_Zp+2
lda #0x03
sta zp:_Zp+3
lda #0x00
sta zp:_Zp+4
lda NT_P1
sta zp:_Zp+5
jsr vdp_write_vram
; Load the Sprite Pattern table at 0x1000
lda #.byte0 SpritePatternTable
sta zp:_Zp+0
lda #.byte1 SpritePatternTable
sta zp:_Zp+1
lda #0x80
sta zp:_Zp+2
lda #0x01
sta zp:_Zp+3
lda #0x00
sta zp:_Zp+4
lda #0x10
sta zp:_Zp+5
jsr vdp_write_vram
; Write the register sequence
lda #.byte0 VDPRegs_M0
sta zp:_Zp+0
lda #.byte1 VDPRegs_M0
sta zp:_Zp+1
jsr vdp_write_registers
rts
.section data,data
PatternTable_Charset:
.incbin "..\\data\\vdp_charset.bin"
NameTable_GameBoard:
.incbin "..\\data\\vdp_nt_board.bin"
NameTable_Dialog:
.incbin "..\\data\\vdp_nt_dialog.bin"
SpritePatternTable:
.incbin "..\\data\\vdp_sprite_tiles.bin"
ColorTable:
.incbin "..\\data\\vdp_colortable.bin"
VDPRegs_M0:
.byte 0x00, 0x80 ; Reg. 0, Disable external video, set M3 to 0 (we'll use mode 0/Graphics I)
.byte 0xE3, 0x81 ; Reg. 1, Enable display and interrupts, 16x16 sprites and magnification
.byte 0x05, 0x82 ; Reg. 2, Place Name Table at 0x1400 (Load the Dialog)
.byte 0x0E, 0x83 ; Reg. 3, Place Color Table at 0x0380
.byte 0x01, 0x84 ; Reg. 4, Place Pattern Table at 0x0800
.byte 0x06, 0x85 ; Reg. 5, Place Sprite Attribute Table at 0x0300, the secondary will live at 0x1200
.byte 0x02, 0x86 ; Reg. 6, Place Sprite Pattern Table at 0x1000
.byte 0xF1, 0x87 ; Reg. 7, Set foreground and background color (white on black)
;;;
;;;
;;; Exported symbols
.public vdp_init

20
src/vdp_utils.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef _VDP_UTILS_HEADER_
#define _VDP_UTILS_HEADER_
#include <stdint.h>
void vdp_write_vram(uint8_t *src, uint16_t len, uint16_t vram_dest);
void vdp_fill_vram(uint8_t val, uint16_t len, uint16_t vram_dest);
uint8_t vdp_detect(void);
void vdp_init_registers(uint8_t *reg_array);
void vdp_hide_sprites(void);
void vdp_hide_sprite(uint8_t sprite_number);
void vdp_show_sprite(uint8_t sprite_number);
void vdp_set_sprite_tile(uint8_t sprite_number, uint8_t tile_idx);
void vdp_switch_nt(uint8_t nt_idx);
void vdp_print_string(uint8_t nt_idx, uint8_t x, uint8_t y, char *str);
void vdp_set_tile(uint8_t nt_idx, uint8_t x, uint8_t y, uint8_t tile_idx);
void vdp_write_interleaved_sat(void);
void vdp_irq_handler(void);
#endif /* _VDP_UTILS_HEADER_ */

665
src/vdp_utils.s Normal file
View file

@ -0,0 +1,665 @@
.rtmodel version,"1"
.rtmodel core,"6502"
.extern _Zp
.extern VDP_MEM, VDP_REG
;;; Define a space
.section intrzp, noinit, root ; root, as we always require it
.space 0xA9
.section code,text
;;; vdp_point_to_vram_xy:
;;; Readies the VDP registers to write on a tile at XY
;;; Parameters:
;;; - nametable index in vram [_Zp[4]]
;;; - X coordinate [_Zp[0]]
;;; - Y coordinate [_Zp[1]]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 5, 6
;;;
vdp_point_to_vram_xy:
T_VADD_H$: .equ _Zp+6
T_VADD_L$: .equ _Zp+5
P_NT_IDX$: .equ _Zp+4
P_Y$: .equ _Zp+1
P_X$: .equ _Zp+0
lda #0x00
sta zp:T_VADD_H$
lda zp:P_Y$
sta zp:T_VADD_L$
;; Shift Y five times to the left to get the offset for the ROW in VRAM
ldx #5
ShiftOffset$:
asl zp:T_VADD_L$
rol zp:T_VADD_H$
dex
bne ShiftOffset$
clc
; Calculate the VRAM address
lda zp:P_X$
adc zp:T_VADD_L$
sta zp:T_VADD_L$
ldx zp:P_NT_IDX$
lda NameTablesList,x
adc zp:T_VADD_H$
sta zp:T_VADD_H$
; Setup the VDP to write into VRAM
lda zp:T_VADD_L$
sta VDP_REG
nop
lda zp:T_VADD_H$
ora #0x40
sta VDP_REG
nop
rts
;;; vdp_set_tile:
;;; Prints the provided ASCII string at the specified coordinates
;;; Parameters:
;;; - nametable index in vram [A]
;;; - X coordinate [_Zp[0]]
;;; - Y coordinate [_Zp[1]]
;;; - tile index [_Zp[2]]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 5, 6
;;;
vdp_set_tile:
T_VADD_H$: .equ _Zp+6
T_VADD_L$: .equ _Zp+5
P_NT_IDX$: .equ _Zp+4
P_TILE$: .equ _Zp+2
P_Y$: .equ _Zp+1
P_X$: .equ _Zp+0
sta zp:P_NT_IDX$
jsr vdp_point_to_vram_xy
lda zp:P_TILE$
sta VDP_MEM
nop
EOS$:
rts
;;; vdp_print_string:
;;; Prints the provided ASCII string at the specified coordinates (newlines and control chars are not supported)
;;; Parameters:
;;; - nametable index in vram [A]
;;; - X coordinate [_Zp[0]]
;;; - Y coordinate [_Zp[1]]
;;; - string address [_Zp[2], _Zp[3]]: Address of the beginning of data to write
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 5, 6
;;;
vdp_print_string:
T_VADD_H$: .equ _Zp+6
T_VADD_L$: .equ _Zp+5
P_NT_IDX$: .equ _Zp+4
P_DATA_H$: .equ _Zp+3
P_DATA_L$: .equ _Zp+2
P_Y$: .equ _Zp+1
P_X$: .equ _Zp+0
sta zp:P_NT_IDX$
jsr vdp_point_to_vram_xy
ldy #0x00
NextChar$:
lda (zp:P_DATA_L$),y
beq EOS$
sec
sbc #0x20
sta VDP_MEM
nop
nop
iny
bne NextChar$
EOS$:
rts
;;; vdp_write_vram:
;;; Write the provided data into VRAM at specified address
;;; Parameters:
;;; - data address [_Zp[0], _Zp[1]]: Address of the beginning of data to write
;;; - data length [_Zp[2], _Zp[3]]: Length of data to write
;;; - VRAM address [_Zp[4], _Zp[5]]: Start address of data in VRAM
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 1, 2, 3
;;;
vdp_write_vram:
P_VADD_H$: .equ _Zp+5
P_VADD_L$: .equ _Zp+4
P_DLEN_H$: .equ _Zp+3
P_DLEN_L$: .equ _Zp+2
P_DATA_H$: .equ _Zp+1
P_DATA_L$: .equ _Zp+0
; Decrement length by one, so or the loop would do an off-by-one write
sec
lda zp:P_DLEN_L$
sbc #1
sta zp:P_DLEN_L$
lda zp:P_DLEN_H$
sbc #0
sta zp:P_DLEN_H$
; Setup the VDP to write into VRAM
lda zp:P_VADD_L$
sta VDP_REG
lda zp:P_VADD_H$
ora #0x40
sta VDP_REG
; Actually write data into VRAM
ldx zp:P_DLEN_H$
ldy #0x00
CopyLoop$:
lda (zp:P_DATA_L$),y
sta VDP_MEM
nop
iny
bne SkipHIncr$ ; Check if we did overflow. In case, increment the high byte of the address
inc zp:P_DATA_H$
SkipHIncr$:
dec zp:P_DLEN_L$
lda zp:P_DLEN_L$
cmp #0xFF
bne CopyLoop$
dex
bpl CopyLoop$
rts
;;; vdp_fill_vram:
;;; Fill VRAM with a specific byte
;;; Parameters:
;;; - fill value [A]
;;; - data length [_Zp[0], _Zp[1]]: Length of data to write
;;; - VRAM address [_Zp[2], _Zp[3]]: Start address of data in VRAM
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 0, 1, 2, 4
;;;
vdp_fill_vram:
T_FILLVAL$: .equ _Zp+4
P_VADD_H$: .equ _Zp+3
P_VADD_L$: .equ _Zp+2
P_DLEN_H$: .equ _Zp+1
P_DLEN_L$: .equ _Zp+0
sta zp:T_FILLVAL$
; Decrement length by one, so or the loop would do an off-by-one write
sec
lda zp:P_DLEN_L$
sbc #1
sta zp:P_DLEN_L$
lda zp:P_DLEN_H$
sbc #0
sta zp:P_DLEN_H$
; Setup the VDP to write into VRAM
lda zp:P_VADD_L$
sta VDP_REG
lda zp:P_VADD_H$
ora #0x40
sta VDP_REG
; Fill the VRAM
ldx zp:P_DLEN_H$
CopyLoop$:
lda zp:T_FILLVAL$
sta VDP_MEM
nop
dec zp:P_DLEN_L$
lda zp:P_DLEN_L$
cmp #0xFF
bne CopyLoop$
dex
bpl CopyLoop$
rts
;;; vdp_detect:
;;; Check if a VDP is present
;;; Parameters: none
;;;
;;; Returns: 0xFF in A if VDP is present, 0 otherwise
;;;
;;; Clobbers:
;;; - A
;;;
vdp_detect:
lda #0x00
sta VDP_REG
nop
lda #0x40
sta VDP_REG
nop
lda #0x55
sta VDP_MEM
nop
lda #0xAA
sta VDP_MEM
nop
lda #0x00
sta VDP_REG
nop
sta VDP_REG
nop
eor VDP_MEM
nop
eor VDP_MEM
nop
cmp #0xFF
beq VdpFound$
lda #0x00
VdpFound$:
rts
;;; vdp_hide_sprites:
;;; Marks all sprites as hidden
;;; Parameters: none
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 1, 2, 3, 4, 5, 6, 7
;;;
vdp_hide_sprites:
ldy #0
HideLoop$:
tya
jsr vdp_hide_sprite
iny
cpy #25
bne HideLoop$
; Make sure the table gets updated in memory
jsr vdp_write_interleaved_sat
rts
;;; vdp_hide_sprite:
;;; Mark a single sprite as hidden
;;; Parameters:
;;; - sprite number [A]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;;
vdp_hide_sprite:
tay
ldx SAT_RowCol_Trans_Table,y
lda #0xC0
sta SpriteAttributeTable,x
rts
;;; vdp_show_sprite:
;;; Enable a single sprite in the game grid
;;; Parameters:
;;; - sprite number [A]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;;
vdp_show_sprite:
tay
ldx SAT_RowCol_Trans_Table,y
lda SAT_Y_Map,y
sta SpriteAttributeTable,x
rts
;;; vdp_set_sprite_tile:
;;; Set the current tile index for a specific sprite
;;; Parameters:
;;; - sprite number [A]
;;; - tile index [_Zp [0]]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;;
vdp_set_sprite_tile:
P_TILE_IDX$:.equ _Zp+0
asl zp:P_TILE_IDX$ ; We're using 2x2 tile sprites
asl zp:P_TILE_IDX$
tay
ldx SAT_RowCol_Trans_Table,y
lda zp:P_TILE_IDX$
sta SpriteAttributeTable+2,x
rts
;;; vdp_switch_nt:
;;; Switch shown nametable
;;; Parameters:
;;; - name table index [A]
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, X
;;;
vdp_switch_nt:
tax
lda NameTablesList,x
lsr a
lsr a
sta VDP_REG
nop
lda #0x82
sta VDP_REG
nop
rts
;;; vdp_write_registers:
;;; Initialize the registers of the VDP, using the provided byte array
;;; Parameters:
;;; - data address [_Zp[0], _Zp[1]]: Address of the beginning of initialization data, a 16 byte array
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y
;;;
vdp_write_registers:
P_REG_H$: .equ _Zp+1
P_REG_L$: .equ _Zp+0
; Write the register sequence
ldy #0x00
RegLoop$:
lda (zp:P_REG_L$),y
sta VDP_REG
nop
iny
cpy #16
bne RegLoop$
rts
;;; vdp_write_interleaved_sat:
;;; Updates SAT at 0x300 with sprite multiplexing
;;; Parameters: none
;;;
;;; Returns: nothing
;;;
;;; Clobbers:
;;; - A, Y, X
;;; - Zp 1, 2, 3, 4, 5, 6, 7
;;;
vdp_write_interleaved_sat:
T_COUNT$: .equ _Zp+7
T_SATB_IDX$: .equ _Zp+6
T_DEST_H$: .equ _Zp+5
T_DEST_L$: .equ _Zp+4
T_DLEN_H$: .equ _Zp+3
T_DLEN_L$: .equ _Zp+2
T_DATA_H$: .equ _Zp+1
T_DATA_L$: .equ _Zp+0
lda #0x00
sta zp:T_DEST_L$
lda #0x03
sta zp:T_DEST_H$
lda CurrentByteTableOffset
cmp #5
bne NoOverflow$
lda #0
sta CurrentByteTableOffset
NoOverflow$:
asl a
sta zp:T_SATB_IDX$
lda #4
sta zp:T_COUNT$
WriteLoop$:
lda #20
sta zp:T_DLEN_L$
lda #00
sta zp:T_DLEN_H$
lda zp:T_SATB_IDX$
tax
lda SAT_Block_Table,x
sta zp:T_DATA_L$
lda SAT_Block_Table+1,x
sta zp:T_DATA_H$
jsr vdp_write_vram
clc
lda zp:T_DEST_L$
adc #20
sta zp:T_DEST_L$
lda zp:T_SATB_IDX$
adc #0x02
sta zp:T_SATB_IDX$
dec zp:T_COUNT$
bpl WriteLoop$
inc CurrentByteTableOffset
rts
_irq_save_zp:
ldx #0
SaveZp$:
lda zp:_Zp,x
sta .sectionStart intrzp,x
inx
;cpx #.sectionSize intrzp
cpx #10 ; Save only part of the ZP, we're not using more
bne SaveZp$
rts
_irq_restore_zp:
ldx #0
RestoreZp$:
lda .sectionStart intrzp,x
sta zp:_Zp,x
inx
;cpx #.sectionSize intrzp
cpx #10 ; Restpre only part of the ZP, we're not using more
bne RestoreZp$
rts
vdp_irq_handler:
; Save the registers
pha
txa
pha
tya
pha
;;; Save ZP
jsr _irq_save_zp
jsr vdp_write_interleaved_sat
;;; Restore ZP
jsr _irq_restore_zp
;;; Clear the IRQ
lda VDP_REG
; Restore the registers
pla
tay
pla
tax
pla
rti
;;;;;;;;;;;;;;;;;;
.section data,data
SpriteAttributeTable:
; Organized in columns
SAT_Col1:
.byte 0xC0, 0x08, 0x30, 0x01 ; Col 1
.byte 0xC0, 0x08, 0x30, 0x01
.byte 0xC0, 0x08, 0x30, 0x01
.byte 0xC0, 0x08, 0x30, 0x01
.byte 0xC0, 0x08, 0x30, 0x01
SAT_Col2:
.byte 0xC0, 0x30, 0x30, 0x01 ; Col 2
.byte 0xC0, 0x30, 0x30, 0x01
.byte 0xC0, 0x30, 0x30, 0x01
.byte 0xC0, 0x30, 0x30, 0x01
.byte 0xC0, 0x30, 0x30, 0x01
SAT_Col3:
.byte 0xC0, 0x58, 0x30, 0x01 ; Col 3
.byte 0xC0, 0x58, 0x30, 0x01
.byte 0xC0, 0x58, 0x30, 0x01
.byte 0xC0, 0x58, 0x30, 0x01
.byte 0xC0, 0x58, 0x30, 0x01
SAT_Col4:
.byte 0xC0, 0x80, 0x30, 0x01 ; Col 4
.byte 0xC0, 0x80, 0x30, 0x01
.byte 0xC0, 0x80, 0x30, 0x01
.byte 0xC0, 0x80, 0x30, 0x01
.byte 0xC0, 0x80, 0x30, 0x01
SAT_Col5:
.byte 0xC0, 0xA8, 0x30, 0x01 ; Col 5
.byte 0xC0, 0xA8, 0x30, 0x01
.byte 0xC0, 0xA8, 0x30, 0x01
.byte 0xC0, 0xA8, 0x30, 0x01
.byte 0xC0, 0xA8, 0x30, 0x01
; Unused
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
.byte 0xD0, 0x00, 0x30, 0x00
SAT_RowCol_Trans_Table:
.byte 0, 20, 40, 60, 80
.byte 4, 24, 44, 64, 84
.byte 8, 28, 48, 68, 88
.byte 12, 32, 52, 72, 92
.byte 16, 36, 56, 76, 96
SAT_Y_Map:
.byte 0x07
.byte 0x07
.byte 0x07
.byte 0x07
.byte 0x07
.byte 0x27
.byte 0x27
.byte 0x27
.byte 0x27
.byte 0x27
.byte 0x47
.byte 0x47
.byte 0x47
.byte 0x47
.byte 0x47
.byte 0x67
.byte 0x67
.byte 0x67
.byte 0x67
.byte 0x67
.byte 0x87
.byte 0x87
.byte 0x87
.byte 0x87
.byte 0x87
SAT_Block_Table:
.word SAT_Col1
.word SAT_Col2
.word SAT_Col3
.word SAT_Col4
.word SAT_Col5
.word SAT_Col1
.word SAT_Col2
.word SAT_Col3
.word SAT_Col4
.word SAT_Col5
; Contains a list of VRAM addresses corresponding to every page
NameTablesList:
NT_P0: .byte 0x00
NT_P1: .byte 0x14
CurrentByteTableOffset:
.byte 0x00
;;;
;;;
;;; Exported symbols
.public vdp_write_vram
.public vdp_detect
.public vdp_write_registers
.public vdp_hide_sprites
.public vdp_hide_sprite
.public vdp_show_sprite
.public vdp_switch_nt
.public vdp_set_sprite_tile
.public vdp_print_string
.public vdp_set_tile
.public vdp_point_to_vram_xy
.public vdp_write_interleaved_sat
.public vdp_irq_handler
.public SpriteAttributeTable ; We'll need to set change visibility and values
.public NT_P0, NT_P1

34
src/vdpin_main.c Normal file
View file

@ -0,0 +1,34 @@
#include <stubs.h>
#include <string.h>
#include <calypsi/intrinsics6502.h>
#include "vdp_init.h"
#include "vdp_utils.h"
#include "monitor_subroutines.h"
#include "utility.h"
#include "mem_map.h"
#include "shared_page.h"
#include "module_list.h"
// External initialization requirements
#pragma require __preserve_zp
#pragma require __data_initialization_needed
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
void main(void) {
__disable_interrupts(); // Make sure the interrupts are disabled
vdp_init();
vdp_print_string(1, 6, 10, "Loading...");
shared_page->master_command = MASTER_COMMAND_NONE;
shared_page->next_module_idx = MODULE_DLOG_VDP;
return;
}