diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e0919..05bab1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,44 +1,23 @@ -# 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 - -_This release removes the tape version of the game._ - -### Changed - -- Game code is now modularized so that only the current module plus a resident master is loaded into memory - -### Added - -- Simple sound effects (replacing the standard *BELL* from the monitor routines) -- Game save and load -- High score save - -### Removed - -- Tape variant of the game - -## 1.0 - 2025-08-20 - +# Changelog + +## 2.0 - 2025-08-30 + +_This release removes the tape version of the game._ + +### Changed + +- Game code is now modularized so that only the current module plus a resident master is loaded into memory + +### Added + +- Simple sound effects (replacing the standard *BELL* from the monitor routines) +- Game save and load +- High score save + +### Removed + +- Tape variant of the game + +## 1.0 - 2025-08-20 + _First release._ \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cbd8e57..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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. \ No newline at end of file diff --git a/Makefile b/Makefile index 68f225b..ec1e49e 100644 --- a/Makefile +++ b/Makefile @@ -11,52 +11,27 @@ MASTER_PRG=master INTRO_PRG=intro DLOG_PRG=dlog GAME_PRG=game -DEMO_PRG=demo -VDPIN_PRG=vdpin -VDDLG_PRG=vddlg -VDGAM_PRG=vdgam -VDDEM_PRG=vddem # Libraries LIBS=clib-6502.a MASTER_ASM_SRCS = tk2k_startup_master.s disk2.s master_func.s -MASTER_C_SRCS = master_main.c dos_floppy.c utility.c +MASTER_C_SRCS = master_main.c dos_floppy.c -INTRO_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s vdp.s vdp_utils.s -INTRO_C_SRCS = intro_main.c utility.c input.c +INTRO_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s +INTRO_C_SRCS = intro_main.c utility.c DLOG_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s sound.s -DLOG_C_SRCS = dlog_main.c input.c utility.c game_hgr_graphics.c hgr_line_data.c +DLOG_C_SRCS = dlog_main.c input.c utility.c game_graphics.c line_data.c 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_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 +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 # Object files MASTER_OBJS = $(MASTER_ASM_SRCS:%.s=%.o) $(MASTER_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) 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 @@ -78,21 +53,6 @@ $(DLOG_PRG).hex: $(DLOG_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) -$(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 (cd out ; objcopy -I ihex -O binary $(MASTER_PRG).hex $(MASTER_PRG).bin) @@ -104,33 +64,13 @@ $(DLOG_PRG).bin: $(DLOG_PRG).hex $(GAME_PRG).bin: $(GAME_PRG).hex (cd out ; objcopy -I ihex -O binary $(GAME_PRG).hex $(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 +$(SW_NAME).dsk: $(MASTER_PRG).bin $(INTRO_PRG).bin $(DLOG_PRG).bin $(GAME_PRG).bin (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 $(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 $(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/STATE.bin | $(JAVA) -jar $(ACMD) -p $(SW_NAME).dsk STATE b;) diff --git a/README.md b/README.md index 6d24f63..34a756e 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,69 @@ -# TK2048 - -## DISCLAIMER - -Any use of this project is **under your own responsibility**. -By using this project You will agree that I cannot be held responsible if it will destroy any of your devices, damage your computer, burn down your house or whatever. - -## Introduction - -![TK2048 V2.0 title screen](pics/title.png) - -This game is an excuse and a testbed for the development on the Microdigital TK2000 clone [I recently built for myself](https://github.com/hkzlab/TK2000_Build_Notes). - -My primary objective with this game is building something where I can add support for all my expansion boards (well, at least where it makes a sliver of sense) so I can test and PoC them, beside, -I want to experiment with the [Calypsi toolchain](https://www.calypsi.cc/). - -I decided for a port of 2048, the now-classic tile sliding game, as it provided several advantages as a first time/playground project: - -- Doesn't need complex graphics hardware or advanced artist skills -- It can be drawn in B/W with static graphics, but animations and colors can be added in the future -- Sound is not needed either, but can be added for simple events like a tile slide or a button press -- The game logic is pretty simple -- Not CPU or memory intensive -- Can be expanded with support for additional hardware (sound cards, video cards, timers) if so desired, but it's not necessary -- Floppy drive can be potentially used not only to load the game, but also for saving the high score - -![TK2048 V1.0 main game shown on a green phosphor CRT](pics/screenshot.jpg) - -### Support - -If you wish to support me in building new hardware and software for old machines, [throw a few euros in my direction via Ko-Fi](https://ko-fi.com/hkzlab) ☕! - -### Current state - -The game is playable, and the following features have been implemented: - -- B/W mode -- VDP board support -- Single graphical tileset -- Simple sound effects -- Control via keyboard -- 5x5 grid, with randomized start and new tiles -- Game save/load -- Highscore saving -- Demo mode - -## How to play - -- You can move the tiles using the cursor keys -- `CTRL-R` during the game will clear your score and restart -- `CTRL-S` during the game will save the game on floppy and let you continue -- `CTRL-L` during the game will load the previous save from floppy and let you continue from there - -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 - -Just put your floppy in the first drive and power on the TK2000. It will autoboot. - -## How to build - -You need the following: - -- GNU Make (I used the one provides by [MSYS2](https://www.msys2.org/)) -- [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) -- [dsk2woz](https://github.com/TomHarte/dsk2woz) - -## The future - +# TK2048 + +## DISCLAIMER + +Any use of this project is **under your own responsibility**. +By using this project You will agree that I cannot be held responsible if it will destroy any of your devices, damage your computer, burn down your house or whatever. + +## Introduction + +![TK2048 V2.0 title screen](pics/title.png) + +This game is an excuse and a testbed for the development on the Microdigital TK2000 clone [I recently built for myself](https://github.com/hkzlab/TK2000_Build_Notes). + +My primary objective with this game is building something where I can add support for all my expansion boards (well, at least where it makes a sliver of sense) so I can test and PoC them, beside, +I want to experiment with the [Calypsi toolchain](https://www.calypsi.cc/). + +I decided for a port of 2048, the now-classic tile sliding game, as it provided several advantages as a first time/playground project: + +- Doesn't need complex graphics hardware or advanced artist skills +- It can be drawn in B/W with static graphics, but animations and colors can be added in the future +- Sound is not needed either, but can be added for simple events like a tile slide or a button press +- The game logic is pretty simple +- Not CPU or memory intensive +- Can be expanded with support for additional hardware (sound cards, video cards, timers) if so desired, but it's not necessary +- Floppy drive can be potentially used not only to load the game, but also for saving the high score + +![TK2048 V1.0 main game shown on a green phosphor CRT](pics/screenshot.jpg) + +### Support + +If you wish to support me in building new hardware and software for old machines, [throw a few euros in my direction via Ko-Fi](https://ko-fi.com/hkzlab) ☕! + +### Current state + +The game is playable, and the following features have been implemented: + +- B/W mode +- Single graphical tileset +- Crude sound +- Control via keyboard +- 5x5 grid, with randomized start and new tiles +- Game save/load +- Highscore saving + +## How to play + +- You can move the tiles using the cursor keys +- `CTRL-R` during the game will clear your score and restart +- `CTRL-S` during the game will save the game on floppy and let you continue +- `CTRL-L` during the game will load the previous save from floppy and let you continue from there + +The game ends once you reach a tile with a value of 2048. + +### Floppy version + +Just put your floppy in the first drive and power on the TK2000. It will autoboot. + +## How to build + +You need the following: + +- GNU Make (I used the one provide via [MSYS2](https://www.msys2.org/)) +- [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) +- [dsk2woz](https://github.com/TomHarte/dsk2woz) + +## The future + I plan to add (optional) support for several expansion boards I'm working on, starting with a VDP board sporting a TMS9918A graphic processor. \ No newline at end of file diff --git a/data/LOADS.bin b/data/LOADS.bin index b1ff972..be529d4 100644 Binary files a/data/LOADS.bin and b/data/LOADS.bin differ diff --git a/data/vdp_charset.bin b/data/vdp_charset.bin deleted file mode 100644 index 658d813..0000000 Binary files a/data/vdp_charset.bin and /dev/null differ diff --git a/data/vdp_colortable.bin b/data/vdp_colortable.bin deleted file mode 100644 index efd4f0e..0000000 Binary files a/data/vdp_colortable.bin and /dev/null differ diff --git a/data/vdp_nt_board.bin b/data/vdp_nt_board.bin deleted file mode 100644 index 92d3faa..0000000 Binary files a/data/vdp_nt_board.bin and /dev/null differ diff --git a/data/vdp_nt_dialog.bin b/data/vdp_nt_dialog.bin deleted file mode 100644 index 937d253..0000000 Binary files a/data/vdp_nt_dialog.bin and /dev/null differ diff --git a/data/vdp_sprite_tiles.bin b/data/vdp_sprite_tiles.bin deleted file mode 100644 index 20a9083..0000000 Binary files a/data/vdp_sprite_tiles.bin and /dev/null differ diff --git a/graphics/loading_screen.aseprite b/graphics/loading_screen.aseprite index 3aa15a1..279674d 100644 Binary files a/graphics/loading_screen.aseprite and b/graphics/loading_screen.aseprite differ diff --git a/graphics/loading_screen.png b/graphics/loading_screen.png index 20ac20a..1800be7 100644 Binary files a/graphics/loading_screen.png and b/graphics/loading_screen.png differ diff --git a/linker-files/module.scm b/linker-files/module.scm index fd7c619..81c846b 100644 --- a/linker-files/module.scm +++ b/linker-files/module.scm @@ -1,19 +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 . #x935f)) (type ram) (section (programStart #x4000) startup code switch idata cdata data_init_table)) - (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 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)) +(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 . #x93ff)) (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 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)) )) \ No newline at end of file diff --git a/linker-files/vdpin_module.scm b/linker-files/vdpin_module.scm deleted file mode 100644 index 2a0f734..0000000 --- a/linker-files/vdpin_module.scm +++ /dev/null @@ -1,19 +0,0 @@ -(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)) - )) \ No newline at end of file diff --git a/pics/title.png b/pics/title.png index 8c2b99a..1156bd5 100644 Binary files a/pics/title.png and b/pics/title.png differ diff --git a/pics/vdp_mode.jpg b/pics/vdp_mode.jpg deleted file mode 100644 index 68c65d9..0000000 Binary files a/pics/vdp_mode.jpg and /dev/null differ diff --git a/src/demo_main.c b/src/demo_main.c deleted file mode 100644 index 5d9a243..0000000 --- a/src/demo_main.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include - -#include - -#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; -} diff --git a/src/disk2.s b/src/disk2.s index e27c09c..f29f44a 100644 --- a/src/disk2.s +++ b/src/disk2.s @@ -523,14 +523,13 @@ wr_err_return: lda #0x10 ; This will be the error code rts dii_write_sector: -RETRIES$: .equ 0xff +RETRIES$: .equ 0xff ; 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. __BUF6S: .equ 0x9C00 ; 256 entries. -__NIBTAB: .equ 0x9D56 +__NIBTAB: .equ 0x9D56 ; This will contain the translation table for writing nibbles. 63 entries. __OFFSETP6 .equ 0x0678 -__T_RETRYC2:.equ _Zp+10 __T_VOL: .equ _Zp+9 __T_TRK: .equ _Zp+8 __T_SEC: .equ _Zp+7 @@ -546,25 +545,20 @@ __P_TRACK: .equ _Zp+0 sta zp:__P_OFFSET sta __OFFSETP6 tax - - lda #RETRIES$ ; Set up the retry counters - sta zp:__T_RETRYC2 -InnerRetr$: lda #RETRIES$ + lda #RETRIES$ ; Set up the retry counter sta zp:__T_RETRYC - dec zp:__T_RETRYC2 - beq wr_err_return ; Out of retries ;;; Search for the address prologue (D5 AA 96) RdSect$: dec zp:__T_RETRYC - beq InnerRetr$ ; Out of retries + beq wr_err_return ; Out of retries ;;; Read the address prologue RdByte1$: lda READ_SW,x bpl RdByte1$ ; Read the first byte ChkD5$: cmp #0xD5 - bne RdSect$ ; Not the first byte, keep searching + bne RdByte1$ ; Not the first byte, keep searching nop RdByte2$: lda READ_SW,x @@ -621,8 +615,7 @@ RdByte7$: lda READ_SW,x lda WRITE_SW,x ; Combination of these two in sequence checks for write protect lda CLEAR_SW,x ; and enables the write sequence. - bpl _b2add01 ; Check if Write protected disk. - jmp wr_err_return + bmi wr_err_return ; Write protected disk. Branch on N = 1 _b2add01: lda __BUF2S ; Get the first 2-bit encode byte sta zp:__T_HOLDNIB ; and save it for future use. diff --git a/src/dlog_main.c b/src/dlog_main.c index 5c32d8f..1cbeaf0 100644 --- a/src/dlog_main.c +++ b/src/dlog_main.c @@ -3,7 +3,7 @@ #include -#include "game_hgr_graphics.h" +#include "game_graphics.h" #include "monitor_subroutines.h" #include "utility.h" #include "mem_map.h" @@ -13,7 +13,6 @@ #include "game_data.h" #include "input.h" #include "sound.h" -#include "module_list.h" // External initialization requirements #pragma require __preserve_zp @@ -22,10 +21,7 @@ static state_page_data* state_page = (state_page_data*)STATE_PAGE; static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE; -#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); @@ -55,19 +51,13 @@ void main(void) { shared_page->master_command = MASTER_COMMAND_NONE; } - shared_page->next_module_idx = MODULE_GAME; // Go to the GAME module + shared_page->next_module_idx = 4; // 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++; + while(!read_any_key()) { 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(); return; diff --git a/src/game_data.h b/src/game_data.h index a8a400b..63f2e48 100644 --- a/src/game_data.h +++ b/src/game_data.h @@ -1,19 +1,14 @@ -#ifndef _GAME_DATA_HEADER_ -#define _GAME_DATA_HEADER_ - -#include - -#define GAME_VER_CH0 '3' -#define GAME_VER_CH1 '.' -#define GAME_VER_CH2 '0' - - -#define GAME_MODE_NORMAL 0 -#define GAME_MODE_LOAD 1 - - -typedef struct { - uint8_t mode; -} game_data; - -#endif /* _GAME_DATA_HEADER_ */ +#ifndef _GAME_DATA_HEADER_ +#define _GAME_DATA_HEADER_ + +#include + +#define GAME_MODE_NORMAL 0 +#define GAME_MODE_LOAD 1 + + +typedef struct { + uint8_t mode; +} game_data; + +#endif /* _GAME_DATA_HEADER_ */ diff --git a/src/game_hgr_graphics.c b/src/game_graphics.c similarity index 92% rename from src/game_hgr_graphics.c rename to src/game_graphics.c index caac19b..9aa1818 100644 --- a/src/game_hgr_graphics.c +++ b/src/game_graphics.c @@ -1,17 +1,16 @@ -#include "game_hgr_graphics.h" +#include "game_graphics.h" #include -#include "game_data.h" #include "utility.h" #include "mem_map.h" #include "mem_registers.h" -#include "hgr_line_data.h" +#include "line_data.h" #include "game_logic.h" #include "tiles.h" #include "charset.h" #include "monitor_subroutines.h" -#include "hgr_graph_misc_data.h" +#include "graph_misc_data.h" #include "arrows_pic.h" #define SCREEN_WIDTH 280 @@ -79,7 +78,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, 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, 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, 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, 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, @@ -107,30 +106,9 @@ static const uint8_t instruction_box[INSTR_BOX_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 5, 1, 3, 8, 0, 0, 50, 48, 52, 56, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 15, 15, 4, 0, 12, 21, 3, 11, 33, 33, 33 + 79, 0, 50, 48, 50, 53, 0, 50, 46, 48, 0, 79 }; -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, // It is offset on the left side by 7 pixels and on the top by 14 @@ -157,10 +135,6 @@ void draw_game_background(uint16_t hi_score) { // Draw the borders 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_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); @@ -170,12 +144,8 @@ 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 direct_draw_number(hi_score, HIGH_TEXT_WIDTH, HIGH_TEXT_X, HIGH_TEXT_Y, front_buf); - // 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 instruction box 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 memcpy((void*)DISPLAY_PAGE_2, (void*)DISPLAY_PAGE_1, DISPLAY_PAGE_SIZE); @@ -237,10 +207,6 @@ void draw_tiles(void) { // Re-draw the borders, to restore the correct width 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 diff --git a/src/game_hgr_graphics.h b/src/game_graphics.h similarity index 87% rename from src/game_hgr_graphics.h rename to src/game_graphics.h index e4234a7..72fcf99 100644 --- a/src/game_hgr_graphics.h +++ b/src/game_graphics.h @@ -1,34 +1,34 @@ -#ifndef _GAME_HGR_GRAPHICS_HEADER_ -#define _GAME_HGR_GRAPHICS_HEADER_ - -#include - -#define BRD_DOUBLING_UP(a) (a & 0x01) -#define BRD_DOUBLING_DOWN(a) (a & 0x02) -#define BRD_DOUBLING_LEFT(a) (a & 0x04) -#define BRD_DOUBLING_RIGHT(a) (a & 0x08) - -#define BRD_SKIP_UP(a) (a & 0x10) -#define BRD_SKIP_DOWN(a) (a & 0x20) -#define BRD_SKIP_LEFT(a) (a & 0x40) -#define BRD_SKIP_RIGHT(a) (a & 0x80) - -#define GRAPH_ARROW_UP 0 -#define GRAPH_ARROW_DOWN 1 -#define GRAPH_ARROW_LEFT 2 -#define GRAPH_ARROW_RIGHT 3 - -void initialize_display_buffers(void); -void ddraw_field_borders_on_buffer(uint8_t brd); -void draw_game_background(uint16_t hi_score); -void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y); -void draw_tiles(void); -void ddraw_single_tile(uint8_t offset); -void swap_display_buffers(void); -void clear_display_buffers(void); -void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y, uint8_t *disp_buf); -void ddraw_direction_arrows(uint8_t dir); -void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score); -void sync_display1_buffer(void); - -#endif /* _GAME_HGR_GRAPHICS_HEADER_ */ +#ifndef _GAME_GRAPHICS_HEADER_ +#define _GAME_GRAPHICS_HEADER_ + +#include + +#define BRD_DOUBLING_UP(a) (a & 0x01) +#define BRD_DOUBLING_DOWN(a) (a & 0x02) +#define BRD_DOUBLING_LEFT(a) (a & 0x04) +#define BRD_DOUBLING_RIGHT(a) (a & 0x08) + +#define BRD_SKIP_UP(a) (a & 0x10) +#define BRD_SKIP_DOWN(a) (a & 0x20) +#define BRD_SKIP_LEFT(a) (a & 0x40) +#define BRD_SKIP_RIGHT(a) (a & 0x80) + +#define GRAPH_ARROW_UP 0 +#define GRAPH_ARROW_DOWN 1 +#define GRAPH_ARROW_LEFT 2 +#define GRAPH_ARROW_RIGHT 3 + +void initialize_display_buffers(void); +void ddraw_field_borders_on_buffer(uint8_t brd); +void draw_game_background(uint16_t hi_score); +void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y); +void draw_tiles(void); +void ddraw_single_tile(uint8_t offset); +void swap_display_buffers(void); +void clear_display_buffers(void); +void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y, uint8_t *disp_buf); +void ddraw_direction_arrows(uint8_t dir); +void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score); +void sync_display1_buffer(void); + +#endif /* _GAME_GRAPHICS_HEADER_ */ diff --git a/src/game_hgr_graphics_demo.c b/src/game_hgr_graphics_demo.c deleted file mode 100644 index 337c19a..0000000 --- a/src/game_hgr_graphics_demo.c +++ /dev/null @@ -1,3 +0,0 @@ -#define _DEMO_MODE_ 1 - -#include "game_hgr_graphics.c" diff --git a/src/game_logic.c b/src/game_logic.c index 22867b5..aa19674 100644 --- a/src/game_logic.c +++ b/src/game_logic.c @@ -1,149 +1,149 @@ -#include "game_logic.h" - -#include "utility.h" - -#include - -static uint8_t game_grid_alpha[GRID_SIDE * GRID_SIDE]; -static uint8_t game_grid_beta[GRID_SIDE * GRID_SIDE]; - -static uint8_t *front_grid = game_grid_alpha; -static uint8_t *back_grid = game_grid_beta; - -void swap_grids(void); - -void swap_grids(void) { - uint8_t *temp = front_grid; - - front_grid = back_grid; - back_grid = temp; -} - -uint8_t reset_game(void) { - uint8_t score = 0; - - // Clear the back and front grid - memset(back_grid, 0, GRID_SIDE * GRID_SIDE); - memset(front_grid, 0, GRID_SIDE * GRID_SIDE); - - // Then add two random tiles - score += (1 << front_grid[add_random_tile() - 1]); - score += (1 << front_grid[add_random_tile() - 1]); - - return score; -} - -uint8_t *get_front_grid(void) { - return front_grid; -} - -uint8_t add_random_tile(void) { - uint16_t rand = lfsr_update(); - uint8_t tile_val = (rand & 0x000F) > 0x0D ? 2 : 1; // ~90% chance of a tile of type 1 (a "2"), 10% of a type 2 (a "4") - - uint8_t free_tiles = 0; - uint8_t chosen_tile; - - for (int8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { - if (!front_grid[offset]) free_tiles++; - } - - if(!free_tiles) return 0; - chosen_tile = (rand >> 8) % free_tiles; - - for (int8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { - if (!front_grid[offset] && !(chosen_tile--)) { - front_grid[offset] = tile_val; - return offset + 1; - } - } - - return 0; // Return 0 if we were not able to place the tile, else we return (offset + 1) to indicate where the tile was placed -} - -int8_t step_game(uint8_t dir) { - int8_t done = 0; - int8_t start_offset; - int8_t column_step; - int8_t row_step; - - /* - * UP: scans TOP to BOTTOM, RIGHT to LEFT - * DOWN: scans BOTTOM to TOP, RIGHT to LEFT - * LEFT: scans LEFT to RIGHT, TOP to BOTTOM - * RIGHT: scans RIGHT to LEFT, TOP to BOTTOM - */ - - switch(dir) { - case GAME_STEP_UP: - start_offset = GRID_SIDE - 1; - column_step = GRID_SIDE; - row_step = -1; - break; - case GAME_STEP_DOWN: - start_offset = (GRID_SIDE * GRID_SIDE) - 1; - column_step = -GRID_SIDE; - row_step = -1; - break; - case GAME_STEP_LEFT: - start_offset = 0; - column_step = 1; - row_step = GRID_SIDE; - break; - case GAME_STEP_RIGHT: - start_offset = GRID_SIDE - 1; - column_step = -1; - row_step = GRID_SIDE; - break; - }; - - // Clear the back grid - memset(back_grid, 0, GRID_SIDE * GRID_SIDE); - - for (int8_t row = 0; row < GRID_SIDE; row++) { - for(int8_t col = 0; col < GRID_SIDE; col++) { - uint8_t current_offset = start_offset + (col * column_step) + (row * row_step); - uint8_t sub_col; - - // Search for the first non-zero value in the front grid and copy it in the current place of the back grid (zeroing it in the front) - for(sub_col = col; sub_col < GRID_SIDE; sub_col++) { - uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step); - if(front_grid[sub_col_offset]) { - back_grid[current_offset] = front_grid[sub_col_offset]; - front_grid[sub_col_offset] = 0; - - break; - } - } - - // The value is still 0, we found nothing. On to the next row! - if (!back_grid[current_offset]) break; - - // Now search if there is an identical value following this one, so we can merge them - for(; sub_col < GRID_SIDE; sub_col++) { - uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step); - if(front_grid[sub_col_offset] == back_grid[current_offset]) { - back_grid[current_offset]++; // Merge them (by increasing the value of the current square and removing the merged one) - front_grid[sub_col_offset] = 0; - - done += back_grid[current_offset] == 11 ? 1 : 0; - break; - } else if (front_grid[sub_col_offset]) break; - } - } - } - - swap_grids(); - - return done; -} - -uint16_t calculate_score(void) { - uint16_t score = 0; - - for(uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { - if(front_grid[offset]) score += ((uint16_t)1 << front_grid[offset]); - } - - return score; -} +#include "game_logic.h" + +#include "utility.h" + +#include + +static uint8_t game_grid_alpha[GRID_SIDE * GRID_SIDE]; +static uint8_t game_grid_beta[GRID_SIDE * GRID_SIDE]; + +static uint8_t *front_grid = game_grid_alpha; +static uint8_t *back_grid = game_grid_beta; + +void swap_grids(void); + +void swap_grids(void) { + uint8_t *temp = front_grid; + + front_grid = back_grid; + back_grid = temp; +} + +uint8_t reset_game(void) { + uint8_t score = 0; + + // Clear the back and front grid + memset(back_grid, 0, GRID_SIDE * GRID_SIDE); + memset(front_grid, 0, GRID_SIDE * GRID_SIDE); + + // Then add two random tiles + score += (1 << front_grid[add_random_tile() - 1]); + score += (1 << front_grid[add_random_tile() - 1]); + + return score; +} + +uint8_t *get_front_grid(void) { + return front_grid; +} + +uint8_t add_random_tile(void) { + uint16_t rand = lfsr_update(); + uint8_t tile_val = (rand & 0x000F) > 0x0D ? 2 : 1; // ~90% chance of a tile of type 1 (a "2"), 10% of a type 2 (a "4") + + uint8_t free_tiles = 0; + uint8_t chosen_tile; + + for (uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { + if (!front_grid[offset]) free_tiles++; + } + + if(!free_tiles) return 0; + chosen_tile = (rand >> 8) % free_tiles; + + for (uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { + if (!front_grid[offset] && !(chosen_tile--)) { + front_grid[offset] = tile_val; + return offset + 1; + } + } + + return 0; // Return 0 if we were not able to place the tile, else we return (offset + 1) to indicate where the tile was placed +} + +int8_t step_game(uint8_t dir) { + int8_t done = 0; + uint8_t start_offset; + int8_t column_step; + int8_t row_step; + + /* + * UP: scans TOP to BOTTOM, RIGHT to LEFT + * DOWN: scans BOTTOM to TOP, RIGHT to LEFT + * LEFT: scans LEFT to RIGHT, TOP to BOTTOM + * RIGHT: scans RIGHT to LEFT, TOP to BOTTOM + */ + + switch(dir) { + case GAME_STEP_UP: + start_offset = GRID_SIDE - 1; + column_step = GRID_SIDE; + row_step = -1; + break; + case GAME_STEP_DOWN: + start_offset = (GRID_SIDE * GRID_SIDE) - 1; + column_step = -GRID_SIDE; + row_step = -1; + break; + case GAME_STEP_LEFT: + start_offset = 0; + column_step = 1; + row_step = GRID_SIDE; + break; + case GAME_STEP_RIGHT: + start_offset = GRID_SIDE - 1; + column_step = -1; + row_step = GRID_SIDE; + break; + }; + + // Clear the back grid + memset(back_grid, 0, GRID_SIDE * GRID_SIDE); + + for (uint8_t row = 0; row < GRID_SIDE; row++) { + for(uint8_t col = 0; col < GRID_SIDE; col++) { + uint8_t current_offset = start_offset + (col * column_step) + (row * row_step); + uint8_t sub_col; + + // Search for the first non-zero value in the front grid and copy it in the current place of the back grid (zeroing it in the front) + for(sub_col = col; sub_col < GRID_SIDE; sub_col++) { + uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step); + if(front_grid[sub_col_offset]) { + back_grid[current_offset] = front_grid[sub_col_offset]; + front_grid[sub_col_offset] = 0; + + break; + } + } + + // The value is still 0, we found nothing. On to the next row! + if (!back_grid[current_offset]) break; + + // Now search if there is an identical value following this one, so we can merge them + for(; sub_col < GRID_SIDE; sub_col++) { + uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step); + if(front_grid[sub_col_offset] == back_grid[current_offset]) { + back_grid[current_offset]++; // Merge them (by increasing the value of the current square and removing the merged one) + front_grid[sub_col_offset] = 0; + + done += back_grid[current_offset] == 11 ? 1 : 0; + break; + } else if (front_grid[sub_col_offset]) break; + } + } + } + + swap_grids(); + + return done; +} + +uint16_t calculate_score(void) { + uint16_t score = 0; + + for(uint8_t offset = 0; offset < GRID_SIDE * GRID_SIDE; offset++) { + if(front_grid[offset]) score += ((uint16_t)1 << front_grid[offset]); + } + + return score; +} diff --git a/src/game_main.c b/src/game_main.c index 2ae6867..1043aff 100644 --- a/src/game_main.c +++ b/src/game_main.c @@ -1,166 +1,165 @@ -#include -#include - -#include - -#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 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; - -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(); - - // 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 - 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 - lfsr_update(); - - switch(read_kb()) { - 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; - 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(); - sync_display1_buffer(); - shared_page->next_module_idx = MODULE_GAME; - gad->mode = GAME_MODE_LOAD; - return; - 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++; - - // 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) { - score += (done > 0) ? WIN_SCORE_BONUS : 0; - 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(); - - dld->mode = (done > 0) ? DLOG_MODE_WIN : DLOG_MODE_LOSE; - dld->score = score; - - - return; -} +#include +#include + +#include + +#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_graphics.h" +#include "monitor_subroutines.h" +#include "sound.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 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; + +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 = 3; // 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(); + + // 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 + 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 + lfsr_update(); + + switch(read_kb()) { + 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; + 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(); + sync_display1_buffer(); + shared_page->next_module_idx = 4; + gad->mode = GAME_MODE_LOAD; + return; + 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++; + + // 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) { + score += (done > 0) ? WIN_SCORE_BONUS : 0; + 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(); + + dld->mode = (done > 0) ? DLOG_MODE_WIN : DLOG_MODE_LOSE; + dld->score = score; + + + return; +} diff --git a/src/game_vdp_graphics.h b/src/game_vdp_graphics.h deleted file mode 100644 index a6d4c38..0000000 --- a/src/game_vdp_graphics.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _GAME_VDP_GRAPHICS_HEADER_ -#define _GAME_VDP_GRAPHICS_HEADER_ - -#include - -#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_ */ diff --git a/src/game_vdp_graphics.s b/src/game_vdp_graphics.s deleted file mode 100644 index b09c2e9..0000000 --- a/src/game_vdp_graphics.s +++ /dev/null @@ -1,323 +0,0 @@ - .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 - \ No newline at end of file diff --git a/src/hgr_graph_misc_data.c b/src/graph_misc_data.c similarity index 98% rename from src/hgr_graph_misc_data.c rename to src/graph_misc_data.c index 447e809..0652f60 100644 --- a/src/hgr_graph_misc_data.c +++ b/src/graph_misc_data.c @@ -1,31 +1,31 @@ -#include - -const uint8_t score_pic_data[] = { - 0x00, 0x2C, 0x40, 0x40, 0x03, 0x05, 0x30, 0x00, 0x00, 0x7B, 0x70, 0x63, 0x06, 0x7B, 0x70, 0x0F, 0x00, 0x0F, - 0x78, 0x57, 0x0B, 0x47, 0x39, 0x00, 0x40, 0x03, 0x3C, 0x2E, 0x4E, 0x63, 0x39, 0x00, 0x60, 0x00, 0x3C, 0x1B, - 0x2E, 0x61, 0x39, 0x00, 0x00, 0x07, 0x5E, 0x1F, 0x6E, 0x71, 0x18, 0x00, 0x40, 0x1D, 0x4E, 0x0C, 0x66, 0x1D, - 0x7E, 0x03, 0x00, 0x3A, 0x0E, 0x4E, 0x67, 0x07, 0x7C, 0x01, 0x00, 0x30, 0x07, 0x0E, 0x77, 0x02, 0x0C, 0x00, - 0x00, 0x3C, 0x07, 0x66, 0x33, 0x06, 0x06, 0x00, 0x40, 0x1B, 0x47, 0x46, 0x3B, 0x0D, 0x06, 0x00, 0x30, 0x0F, - 0x23, 0x6E, 0x19, 0x0E, 0x7F, 0x00, 0x78, 0x01, 0x3E, 0x78, 0x18, 0x1C, 0x3F, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -const uint8_t moves_pic_data[] = { - 0x00, 0x06, 0x00, 0x1C, 0x06, 0x30, 0x00, 0x0B, 0x00, 0x3E, 0x0C, 0x36, 0x0E, 0x72, 0x6F, 0x1E, 0x00, 0x7F, - 0x0A, 0x5D, 0x06, 0x3A, 0x60, 0x03, 0x00, 0x57, 0x4D, 0x72, 0x0E, 0x3F, 0x70, 0x00, 0x40, 0x6F, 0x46, 0x71, - 0x26, 0x39, 0x18, 0x00, 0x50, 0x33, 0x67, 0x71, 0x47, 0x1B, 0x60, 0x01, 0x60, 0x19, 0x67, 0x30, 0x67, 0x7F, - 0x33, 0x07, 0x60, 0x15, 0x73, 0x3C, 0x67, 0x7C, 0x41, 0x0E, 0x70, 0x4C, 0x73, 0x38, 0x37, 0x0C, 0x00, 0x0C, - 0x68, 0x5C, 0x33, 0x1E, 0x1F, 0x06, 0x00, 0x0F, 0x30, 0x4C, 0x31, 0x1C, 0x1F, 0x06, 0x70, 0x06, 0x38, 0x26, - 0x71, 0x0E, 0x0E, 0x7F, 0x6C, 0x03, 0x38, 0x66, 0x41, 0x07, 0x07, 0x3F, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x00 -}; - -const uint8_t high_pic_data[] = { - 0x00, 0x00, 0x06, 0x60, 0x21, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x64, 0x78, 0x51, 0x20, 0x00, 0x00, 0x00, - 0x0E, 0x6E, 0x1D, 0x72, 0x70, 0x00, 0x00, 0x00, 0x06, 0x7E, 0x1E, 0x33, 0x30, 0x00, 0x00, 0x00, 0x0E, 0x33, - 0x0E, 0x71, 0x18, 0x00, 0x00, 0x00, 0x07, 0x7B, 0x05, 0x38, 0x18, 0x00, 0x00, 0x00, 0x5F, 0x1B, 0x07, 0x79, - 0x1D, 0x00, 0x00, 0x00, 0x7B, 0x59, 0x73, 0x59, 0x0F, 0x00, 0x00, 0x40, 0x27, 0x5D, 0x43, 0x3C, 0x0A, 0x00, - 0x00, 0x20, 0x51, 0x4C, 0x61, 0x0A, 0x05, 0x00, 0x00, 0x40, 0x71, 0x4C, 0x63, 0x0C, 0x07, 0x00, 0x00, 0x60, - 0x61, 0x06, 0x31, 0x0E, 0x06, 0x00, 0x00, 0x60, 0x30, 0x02, 0x3E, 0x06, 0x03, 0x00, 0x00, 0x20, 0x20, 0x00, - 0x00, 0x02, 0x02, 0x00 -}; +#include + +const uint8_t score_pic_data[] = { + 0x00, 0x2C, 0x40, 0x40, 0x03, 0x05, 0x30, 0x00, 0x00, 0x7B, 0x70, 0x63, 0x06, 0x7B, 0x70, 0x0F, 0x00, 0x0F, + 0x78, 0x57, 0x0B, 0x47, 0x39, 0x00, 0x40, 0x03, 0x3C, 0x2E, 0x4E, 0x63, 0x39, 0x00, 0x60, 0x00, 0x3C, 0x1B, + 0x2E, 0x61, 0x39, 0x00, 0x00, 0x07, 0x5E, 0x1F, 0x6E, 0x71, 0x18, 0x00, 0x40, 0x1D, 0x4E, 0x0C, 0x66, 0x1D, + 0x7E, 0x03, 0x00, 0x3A, 0x0E, 0x4E, 0x67, 0x07, 0x7C, 0x01, 0x00, 0x30, 0x07, 0x0E, 0x77, 0x02, 0x0C, 0x00, + 0x00, 0x3C, 0x07, 0x66, 0x33, 0x06, 0x06, 0x00, 0x40, 0x1B, 0x47, 0x46, 0x3B, 0x0D, 0x06, 0x00, 0x30, 0x0F, + 0x23, 0x6E, 0x19, 0x0E, 0x7F, 0x00, 0x78, 0x01, 0x3E, 0x78, 0x18, 0x1C, 0x3F, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const uint8_t moves_pic_data[] = { + 0x00, 0x06, 0x00, 0x1C, 0x06, 0x30, 0x00, 0x0B, 0x00, 0x3E, 0x0C, 0x36, 0x0E, 0x72, 0x6F, 0x1E, 0x00, 0x7F, + 0x0A, 0x5D, 0x06, 0x3A, 0x60, 0x03, 0x00, 0x57, 0x4D, 0x72, 0x0E, 0x3F, 0x70, 0x00, 0x40, 0x6F, 0x46, 0x71, + 0x26, 0x39, 0x18, 0x00, 0x50, 0x33, 0x67, 0x71, 0x47, 0x1B, 0x60, 0x01, 0x60, 0x19, 0x67, 0x30, 0x67, 0x7F, + 0x33, 0x07, 0x60, 0x15, 0x73, 0x3C, 0x67, 0x7C, 0x41, 0x0E, 0x70, 0x4C, 0x73, 0x38, 0x37, 0x0C, 0x00, 0x0C, + 0x68, 0x5C, 0x33, 0x1E, 0x1F, 0x06, 0x00, 0x0F, 0x30, 0x4C, 0x31, 0x1C, 0x1F, 0x06, 0x70, 0x06, 0x38, 0x26, + 0x71, 0x0E, 0x0E, 0x7F, 0x6C, 0x03, 0x38, 0x66, 0x41, 0x07, 0x07, 0x3F, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00 +}; + +const uint8_t high_pic_data[] = { + 0x00, 0x00, 0x06, 0x60, 0x21, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x64, 0x78, 0x51, 0x20, 0x00, 0x00, 0x00, + 0x0E, 0x6E, 0x1D, 0x72, 0x70, 0x00, 0x00, 0x00, 0x06, 0x7E, 0x1E, 0x33, 0x30, 0x00, 0x00, 0x00, 0x0E, 0x33, + 0x0E, 0x71, 0x18, 0x00, 0x00, 0x00, 0x07, 0x7B, 0x05, 0x38, 0x18, 0x00, 0x00, 0x00, 0x5F, 0x1B, 0x07, 0x79, + 0x1D, 0x00, 0x00, 0x00, 0x7B, 0x59, 0x73, 0x59, 0x0F, 0x00, 0x00, 0x40, 0x27, 0x5D, 0x43, 0x3C, 0x0A, 0x00, + 0x00, 0x20, 0x51, 0x4C, 0x61, 0x0A, 0x05, 0x00, 0x00, 0x40, 0x71, 0x4C, 0x63, 0x0C, 0x07, 0x00, 0x00, 0x60, + 0x61, 0x06, 0x31, 0x0E, 0x06, 0x00, 0x00, 0x60, 0x30, 0x02, 0x3E, 0x06, 0x03, 0x00, 0x00, 0x20, 0x20, 0x00, + 0x00, 0x02, 0x02, 0x00 +}; diff --git a/src/hgr_graph_misc_data.h b/src/graph_misc_data.h similarity index 70% rename from src/hgr_graph_misc_data.h rename to src/graph_misc_data.h index c6fd0de..e3f1724 100644 --- a/src/hgr_graph_misc_data.h +++ b/src/graph_misc_data.h @@ -1,18 +1,18 @@ -#ifndef _HGR_GRAPH_MISC_DATA_HEADER_ -#define _HGR_GRAPH_MISC_DATA_HEADER_ - -#include - -#define SCORE_PIC_WIDTH_BYTES 8 -#define SCORE_PIC_HEIGHT 14 -extern const uint8_t score_pic_data[]; - -#define MOVES_PIC_WIDTH_BYTES 8 -#define MOVES_PIC_HEIGHT 14 -extern const uint8_t moves_pic_data[]; - -#define HIGH_PIC_WIDTH_BYTES 8 -#define HIGH_PIC_HEIGHT 14 -extern const uint8_t high_pic_data[]; - -#endif /* _HGR_GRAPH_MISC_DATA_HEADER_ */ +#ifndef _GRAPH_MISC_DATA_HEADER_ +#define _GRAPH_MISC_DATA_HEADER_ + +#include + +#define SCORE_PIC_WIDTH_BYTES 8 +#define SCORE_PIC_HEIGHT 14 +extern const uint8_t score_pic_data[]; + +#define MOVES_PIC_WIDTH_BYTES 8 +#define MOVES_PIC_HEIGHT 14 +extern const uint8_t moves_pic_data[]; + +#define HIGH_PIC_WIDTH_BYTES 8 +#define HIGH_PIC_HEIGHT 14 +extern const uint8_t high_pic_data[]; + +#endif /* _GRAPH_MISC_DATA_HEADER_ */ diff --git a/src/hgr_graphics.h b/src/hgr_graphics.h deleted file mode 100644 index 4851bd9..0000000 --- a/src/hgr_graphics.h +++ /dev/null @@ -1,8 +0,0 @@ -#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_ */ diff --git a/src/hgr_line_data.h b/src/hgr_line_data.h deleted file mode 100644 index 9466fe5..0000000 --- a/src/hgr_line_data.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _HGR_LINE_DATA_HEADER_ -#define _HGR_LINE_DATA_HEADER_ - -#include - -#include "hgr_graphics.h" - -extern const uint16_t line_offset_map[SCREEN_HEIGHT]; - -#endif /* _HGR_LINE_DATA_HEADER_ */ diff --git a/src/intro_main.c b/src/intro_main.c index f40cfe5..4595ad0 100644 --- a/src/intro_main.c +++ b/src/intro_main.c @@ -1,46 +1,39 @@ -#include -#include - -#include - -#include "vdp_utils.h" - -#include "monitor_subroutines.h" -#include "utility.h" -#include "input.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) { - uint8_t wait_count = 0x40; - uint8_t vdp_detected; - - // Initialize the register for LFSR - lfsr_init(0xF00D); - - // Clear the memory used to pass parameters to the next module - memset((void*)(shared_page->module_data), 0, MODULE_DATA_SIZE); - - // Detect expansion hardware, and choose what to load according to that - vdp_detected = vdp_detect() && !read_any_key(); - - // Delay a bit - while(wait_count--) WAIT(0xFF); - - // Clear the display memory - memset((void*)DISPLAY_PAGE_2, 0, DISPLAY_PAGE_SIZE); - memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE); - - shared_page->master_command = MASTER_COMMAND_NONE; - 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; -} +#include +#include + +#include + +#include "monitor_subroutines.h" +#include "utility.h" +#include "mem_map.h" +#include "shared_page.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) { + uint8_t wait_count = 0x40; + + // Initialize the register for LFSR + lfsr_init(0xF00D); + + // Clear the memory used to pass parameters to the next module + memset((void*)(shared_page->module_data), 0, MODULE_DATA_SIZE); + + // TODO: Detect expansion hardware, and choose what to load according to that + + // Delay a bit + while(wait_count--) WAIT(0xFF); + + // Clear the display memory + memset((void*)DISPLAY_PAGE_2, 0, DISPLAY_PAGE_SIZE); + memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE); + + shared_page->master_command = MASTER_COMMAND_NONE; + shared_page->next_module_idx = 3; // DLOG module is next! + + return; +} diff --git a/src/hgr_line_data.c b/src/line_data.c similarity index 97% rename from src/hgr_line_data.c rename to src/line_data.c index 95866e3..992b832 100644 --- a/src/hgr_line_data.c +++ b/src/line_data.c @@ -1,22 +1,22 @@ -#include - -#include "hgr_graphics.h" - -const uint16_t line_offset_map[SCREEN_HEIGHT] = { - 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0080, 0x0480, 0x0880, 0x0C80, - 0x1080, 0x1480, 0x1880, 0x1C80, 0x0100, 0x0500, 0x0900, 0x0D00, 0x1100, 0x1500, 0x1900, 0x1D00, - 0x0180, 0x0580, 0x0980, 0x0D80, 0x1180, 0x1580, 0x1980, 0x1D80, 0x0200, 0x0600, 0x0A00, 0x0E00, - 0x1200, 0x1600, 0x1A00, 0x1E00, 0x0280, 0x0680, 0x0A80, 0x0E80, 0x1280, 0x1680, 0x1A80, 0x1E80, - 0x0300, 0x0700, 0x0B00, 0x0F00, 0x1300, 0x1700, 0x1B00, 0x1F00, 0x0380, 0x0780, 0x0B80, 0x0F80, - 0x1380, 0x1780, 0x1B80, 0x1F80, 0x0028, 0x0428, 0x0828, 0x0C28, 0x1028, 0x1428, 0x1828, 0x1C28, - 0x00A8, 0x04A8, 0x08A8, 0x0CA8, 0x10A8, 0x14A8, 0x18A8, 0x1CA8, 0x0128, 0x0528, 0x0928, 0x0D28, - 0x1128, 0x1528, 0x1928, 0x1D28, 0x01A8, 0x05A8, 0x09A8, 0x0DA8, 0x11A8, 0x15A8, 0x19A8, 0x1DA8, - 0x0228, 0x0628, 0x0A28, 0x0E28, 0x1228, 0x1628, 0x1A28, 0x1E28, 0x02A8, 0x06A8, 0x0AA8, 0x0EA8, - 0x12A8, 0x16A8, 0x1AA8, 0x1EA8, 0x0328, 0x0728, 0x0B28, 0x0F28, 0x1328, 0x1728, 0x1B28, 0x1F28, - 0x03A8, 0x07A8, 0x0BA8, 0x0FA8, 0x13A8, 0x17A8, 0x1BA8, 0x1FA8, 0x0050, 0x0450, 0x0850, 0x0C50, - 0x1050, 0x1450, 0x1850, 0x1C50, 0x00D0, 0x04D0, 0x08D0, 0x0CD0, 0x10D0, 0x14D0, 0x18D0, 0x1CD0, - 0x0150, 0x0550, 0x0950, 0x0D50, 0x1150, 0x1550, 0x1950, 0x1D50, 0x01D0, 0x05D0, 0x09D0, 0x0DD0, - 0x11D0, 0x15D0, 0x19D0, 0x1DD0, 0x0250, 0x0650, 0x0A50, 0x0E50, 0x1250, 0x1650, 0x1A50, 0x1E50, - 0x02D0, 0x06D0, 0x0AD0, 0x0ED0, 0x12D0, 0x16D0, 0x1AD0, 0x1ED0, 0x0350, 0x0750, 0x0B50, 0x0F50, - 0x1350, 0x1750, 0x1B50, 0x1F50, 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0 -}; +#include + +#include "utility.h" + +const uint16_t line_offset_map[SCREEN_HEIGHT] = { + 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0080, 0x0480, 0x0880, 0x0C80, + 0x1080, 0x1480, 0x1880, 0x1C80, 0x0100, 0x0500, 0x0900, 0x0D00, 0x1100, 0x1500, 0x1900, 0x1D00, + 0x0180, 0x0580, 0x0980, 0x0D80, 0x1180, 0x1580, 0x1980, 0x1D80, 0x0200, 0x0600, 0x0A00, 0x0E00, + 0x1200, 0x1600, 0x1A00, 0x1E00, 0x0280, 0x0680, 0x0A80, 0x0E80, 0x1280, 0x1680, 0x1A80, 0x1E80, + 0x0300, 0x0700, 0x0B00, 0x0F00, 0x1300, 0x1700, 0x1B00, 0x1F00, 0x0380, 0x0780, 0x0B80, 0x0F80, + 0x1380, 0x1780, 0x1B80, 0x1F80, 0x0028, 0x0428, 0x0828, 0x0C28, 0x1028, 0x1428, 0x1828, 0x1C28, + 0x00A8, 0x04A8, 0x08A8, 0x0CA8, 0x10A8, 0x14A8, 0x18A8, 0x1CA8, 0x0128, 0x0528, 0x0928, 0x0D28, + 0x1128, 0x1528, 0x1928, 0x1D28, 0x01A8, 0x05A8, 0x09A8, 0x0DA8, 0x11A8, 0x15A8, 0x19A8, 0x1DA8, + 0x0228, 0x0628, 0x0A28, 0x0E28, 0x1228, 0x1628, 0x1A28, 0x1E28, 0x02A8, 0x06A8, 0x0AA8, 0x0EA8, + 0x12A8, 0x16A8, 0x1AA8, 0x1EA8, 0x0328, 0x0728, 0x0B28, 0x0F28, 0x1328, 0x1728, 0x1B28, 0x1F28, + 0x03A8, 0x07A8, 0x0BA8, 0x0FA8, 0x13A8, 0x17A8, 0x1BA8, 0x1FA8, 0x0050, 0x0450, 0x0850, 0x0C50, + 0x1050, 0x1450, 0x1850, 0x1C50, 0x00D0, 0x04D0, 0x08D0, 0x0CD0, 0x10D0, 0x14D0, 0x18D0, 0x1CD0, + 0x0150, 0x0550, 0x0950, 0x0D50, 0x1150, 0x1550, 0x1950, 0x1D50, 0x01D0, 0x05D0, 0x09D0, 0x0DD0, + 0x11D0, 0x15D0, 0x19D0, 0x1DD0, 0x0250, 0x0650, 0x0A50, 0x0E50, 0x1250, 0x1650, 0x1A50, 0x1E50, + 0x02D0, 0x06D0, 0x0AD0, 0x0ED0, 0x12D0, 0x16D0, 0x1AD0, 0x1ED0, 0x0350, 0x0750, 0x0B50, 0x0F50, + 0x1350, 0x1750, 0x1B50, 0x1F50, 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0 +}; diff --git a/src/line_data.h b/src/line_data.h new file mode 100644 index 0000000..219744e --- /dev/null +++ b/src/line_data.h @@ -0,0 +1,9 @@ +#ifndef _LINE_DATA_HEADER_ +#define _LINE_DATA_HEADER_ + +#include +#include "utility.h" + +extern const uint16_t line_offset_map[SCREEN_HEIGHT]; + +#endif /* _LINE_DATA_HEADER */ diff --git a/src/loading_screen.c b/src/loading_screen.c new file mode 100644 index 0000000..0aceb00 --- /dev/null +++ b/src/loading_screen.c @@ -0,0 +1,210 @@ +#include + +/*__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 +}; + diff --git a/src/master_main.c b/src/master_main.c index 85e9880..9d85844 100644 --- a/src/master_main.c +++ b/src/master_main.c @@ -24,7 +24,7 @@ static uint8_t *module_page = (uint8_t*)MODULE_PAGE; static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE; -#define FILE_LIST_LEN 10 +#define FILE_LIST_LEN 5 #define FNAME_LEN 6 #define STATE_FILE_IDX 1 @@ -34,14 +34,9 @@ static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE; 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 | '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 detect hardware and load the appropriate followup module) + { 0x80 | 'I', 0x80 | 'N', 0x80 | 'T', 0x80 | 'R', 0x80 | 'O', 0x00}, // INTRO (this executable will show the initial presentation picture) { 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 | '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. @@ -51,16 +46,12 @@ 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, }; static void init(void); 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 calculate_crc8(uint8_t* data, uint8_t len); // Low level initialization static void init(void) { @@ -126,19 +117,42 @@ static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file) { 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) { uint8_t cur_trk = 0; uint8_t cur_file = 0; uint8_t keep_going = 1; - __disable_interrupts(); // Keep the interrupts disabled in the master module + __disable_interrupts(); init(); init_floppy_data(&cur_trk, &cur_file); + + __enable_interrupts(); do { 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); // Check if we need to load another module @@ -156,6 +170,7 @@ __task int main(void) { } dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET); + __enable_interrupts(); } shared_page->master_command = MASTER_COMMAND_NONE; diff --git a/src/mem_registers.h b/src/mem_registers.h index 5c11921..5ca2394 100644 --- a/src/mem_registers.h +++ b/src/mem_registers.h @@ -1,51 +1,48 @@ -#ifndef _MEM_REGISTERS_HEADER_ -#define _MEM_REGISTERS_HEADER_ - -#include - -#define NMI_HANDLER_ADDRESS 0x03FB -#define IRQ_HANDLER_ADDRESS 0x03FE - -#define ROM_MONITOR 0xFF61 - -#define ZP_WNDLFT 0x0020 // 0, left column of scroll window -#define ZP_WNDWDTH 0x0021 // 40, width of scroll window -#define ZP_WNDTOP 0x0022 // 0, top line of the scroll window -#define ZP_WNDBTM 0x0023 // 24, bottom line of the scroll window - -#define ZP_CH 0x0024 // Displacement from window left for the cursor -#define ZP_CV 0x0025 // Displacement from top of screen (not window!) for the cursor - -#define ZP_INVFLAG 0x0032 // Either 0x00 or 0x7F, set text color inversion -#define ZP_PROMPT 0x0033 // Prompt character - -#define ZP_RND 0x004E // Note that this is a 16bit register incremented by the RDKEY func - -#define P3_PWRDUP_REF 0x03F3 -#define P3_PWRDUP 0x03F4 // Already-powered-up indicator. If it is set to the content of 0x03F3 XOR'd with 0xA5, the soft reset vector is considered valid - - -#define DATAIN_KB_MASK 0x3F -#define DATAIN_PRNT_MASK 0x40 -#define DATAIN_TAPEIN_MASK 0x80 - -#define IO_DATAOUT 0xC000 // (W) To keyboard and printer port -#define IO_DATAIN 0xC010 // (R) Data input from keyboard (0:5), printer (6) and tape (7) -#define IO_TAPEOUT 0xC020 // (R) Data output for tape, read from here to output bit on tape -#define IO_SPEAKER 0xC030 // (R) Speaker toggle -#define IO_DISPLAY_COLOR 0xC050 // (R / W) Access here to enable the colorburst -#define IO_DISPLAY_BW 0xC051 // (R / W) Access here to disable the colorburst -#define IO_MTA_OFF 0xC052 // (?) -#define IO_MTA_ON 0xC053 // (?) -#define IO_DISPLAY_PAGE1 0xC054 // (R / W) Access here to select the primary display page -#define IO_DISPLAY_PAGE2 0xC055 // (R / W) Access here to select the secondary display page -#define IO_MTB_OFF 0xC056 // (?) -#define IO_MTB_ON 0xC057 // (?) -#define IO_PRNT_STRB_LO 0xC058 // (R / W) Access LO/HI/LO or HI/LO/HI consecutively depending on the type of strobe pulse to create -#define IO_PRNT_STRB_HI 0xC059 // (R / W) -#define IO_ROMSEL 0xC05A // (R / W) Access here will make region C100-FFFF a ROM area -#define IO_RAMSEL 0xC05B // (R / W) Access here will make region C100-FFFF a RAM area -#define IO_KB_CTRL_LOW 0xC05E // (R / W) Set the CTRL line to 0, access is through DATAIN -#define IO_KB_CTRL_HI 0xC05F // (R / W) Set the CTRL line to 1 - -#endif /* _MEM_REGISTERS_HEADER_ */ +#ifndef _MEM_REGISTERS_HEADER_ +#define _MEM_REGISTERS_HEADER_ + +#include + +#define ROM_MONITOR 0xFF61 + +#define ZP_WNDLFT 0x0020 // 0, left column of scroll window +#define ZP_WNDWDTH 0x0021 // 40, width of scroll window +#define ZP_WNDTOP 0x0022 // 0, top line of the scroll window +#define ZP_WNDBTM 0x0023 // 24, bottom line of the scroll window + +#define ZP_CH 0x0024 // Displacement from window left for the cursor +#define ZP_CV 0x0025 // Displacement from top of screen (not window!) for the cursor + +#define ZP_INVFLAG 0x0032 // Either 0x00 or 0x7F, set text color inversion +#define ZP_PROMPT 0x0033 // Prompt character + +#define ZP_RND 0x004E // Note that this is a 16bit register incremented by the RDKEY func + +#define P3_PWRDUP_REF 0x03F3 +#define P3_PWRDUP 0x03F4 // Already-powered-up indicator. If it is set to the content of 0x03F3 XOR'd with 0xA5, the soft reset vector is considered valid + + +#define DATAIN_KB_MASK 0x3F +#define DATAIN_PRNT_MASK 0x40 +#define DATAIN_TAPEIN_MASK 0x80 + +#define IO_DATAOUT 0xC000 // (W) To keyboard and printer port +#define IO_DATAIN 0xC010 // (R) Data input from keyboard (0:5), printer (6) and tape (7) +#define IO_TAPEOUT 0xC020 // (R) Data output for tape, read from here to output bit on tape +#define IO_SPEAKER 0xC030 // (R) Speaker toggle +#define IO_DISPLAY_COLOR 0xC050 // (R / W) Access here to enable the colorburst +#define IO_DISPLAY_BW 0xC051 // (R / W) Access here to disable the colorburst +#define IO_MTA_OFF 0xC052 // (?) +#define IO_MTA_ON 0xC053 // (?) +#define IO_DISPLAY_PAGE1 0xC054 // (R / W) Access here to select the primary display page +#define IO_DISPLAY_PAGE2 0xC055 // (R / W) Access here to select the secondary display page +#define IO_MTB_OFF 0xC056 // (?) +#define IO_MTB_ON 0xC057 // (?) +#define IO_PRNT_STRB_LO 0xC058 // (R / W) Access LO/HI/LO or HI/LO/HI consecutively depending on the type of strobe pulse to create +#define IO_PRNT_STRB_HI 0xC059 // (R / W) +#define IO_ROMSEL 0xC05A // (R / W) Access here will make region C100-FFFF a ROM area +#define IO_RAMSEL 0xC05B // (R / W) Access here will make region C100-FFFF a RAM area +#define IO_KB_CTRL_LOW 0xC05E // (R / W) Set the CTRL line to 0, access is through DATAIN +#define IO_KB_CTRL_HI 0xC05F // (R / W) Set the CTRL line to 1 + +#endif /* _MEM_REGISTERS_HEADER_ */ diff --git a/src/module_list.h b/src/module_list.h deleted file mode 100644 index fb9f821..0000000 --- a/src/module_list.h +++ /dev/null @@ -1,13 +0,0 @@ -#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_ */ diff --git a/src/utility.c b/src/utility.c index fb29948..5be83ab 100644 --- a/src/utility.c +++ b/src/utility.c @@ -1,77 +1,72 @@ -#include "utility.h" - -#include "mem_registers.h" -#include "monitor_subroutines.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) { - for(uint8_t idx = 0; idx < len; idx++) { - buf[idx] = n % 10; - n /= 10; - } -} - -// https://stackoverflow.com/questions/2602823/in-c-c-whats-the-simplest-way-to-reverse-the-order-of-bits-in-a-byte -uint8_t bit_reverse(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - - return b; -} - -// https://stackoverflow.com/questions/14009765/fastest-way-to-count-bits -uint8_t bit_count(uint8_t b) { - b = (b & 0x55) + (b >> 1 & 0x55); - b = (b & 0x33) + (b >> 2 & 0x33); - b = (b & 0x0f) + (b >> 4 & 0x0f); - - return b; -} - -void lfsr_init(uint16_t reg) { - *((uint16_t*)LFSR_REGISTER_ADDRESS) = 0xF00D; -} - -uint16_t lfsr_update(void) { - uint16_t *lfsr = ((uint16_t*)LFSR_REGISTER_ADDRESS); - - *lfsr ^= (*lfsr) >> 7; - *lfsr ^= (*lfsr) << 9; - *lfsr ^= (*lfsr) >> 13; - - return *lfsr; -} - -#define CRC8RDALLAS_POLY 0x31 -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; -} +#include "utility.h" + +#include "mem_registers.h" +#include "monitor_subroutines.h" +#include "line_data.h" + +void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf) { + + for(uint8_t idx = 0; idx < len; idx++) { + buf[idx] = n % 10; + n /= 10; + } +} + +// https://stackoverflow.com/questions/2602823/in-c-c-whats-the-simplest-way-to-reverse-the-order-of-bits-in-a-byte +uint8_t bit_reverse(uint8_t b) { + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + + return b; +} + +// https://stackoverflow.com/questions/14009765/fastest-way-to-count-bits +uint8_t bit_count(uint8_t b) { + b = (b & 0x55) + (b >> 1 & 0x55); + b = (b & 0x33) + (b >> 2 & 0x33); + b = (b & 0x0f) + (b >> 4 & 0x0f); + + return b; +} + +void lfsr_init(uint16_t reg) { + *((uint16_t*)LFSR_REGISTER_ADDRESS) = 0xF00D; +} + +uint16_t lfsr_update(void) { + uint16_t *lfsr = ((uint16_t*)LFSR_REGISTER_ADDRESS); + + *lfsr ^= (*lfsr) >> 7; + *lfsr ^= (*lfsr) << 9; + *lfsr ^= (*lfsr) >> 13; + + return *lfsr; +} + +/* +void print_line(const char* line, uint8_t off_x, uint8_t off_y) { + POKEZ(ZP_CV, off_y); + + uint8_t cur_ch; + for(cur_ch = 0; line[cur_ch]; cur_ch++) { + SETNORM(); + POKEZ(ZP_CH, cur_ch + off_x); + + COUT1(line[cur_ch]|0x80); + + SETINV(); + COUT1(' '|0x80); + + for(uint8_t snd_loop = 0x70; snd_loop; snd_loop--) PEEK(IO_SPEAKER); + + WAIT(0xBE); + } + + SETNORM(); + POKEZ(ZP_CH, cur_ch + off_x); + + COUT1(' '|0x80); + WAIT(0xFF); +} +*/ diff --git a/src/utility.h b/src/utility.h index 96fc869..365fa3d 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1,31 +1,34 @@ -#ifndef _UTILITY_HEADER_ -#define _UTILITY_HEADER_ - -#include - -#define PEEKZ(a) (*(volatile uint8_t* __attribute__((zpage)))(a)) -#define POKEZ(a, b) ((*(volatile uint8_t* __attribute__((zpage)))(a)) = b) - -#define PEEK(a) (*(volatile uint8_t*)(a)) -#define POKE(a, b) ((*(volatile uint8_t*)(a)) = b) - -#define PEEKW(a) (*(volatile uint16_t*)(a)) -#define POKEW(a, b) ((*(volatile uint16_t*)(a)) = b) - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) - -// 0x356 - 0x357 actually fall inside the -// decoding table for DISK II sector reading, -// but they're unused bytes! So we can use them -// to store the lfsr_update -#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); -uint8_t bit_reverse(uint8_t b); -uint8_t bit_count(uint8_t b); -void lfsr_init(uint16_t reg); -uint16_t lfsr_update(void); -uint8_t calculate_crc8(uint8_t* data, uint8_t len); - -#endif /* _UTILITY_HEADER_ */ +#ifndef _UTILITY_HEADER_ +#define _UTILITY_HEADER_ + +#include + +#define SCREEN_HEIGHT 192 +#define SCREEN_WIDTH_BYTES 128 +#define BYTES_PER_LINE 40 + +#define PEEKZ(a) (*(volatile uint8_t* __attribute__((zpage)))(a)) +#define POKEZ(a, b) ((*(volatile uint8_t* __attribute__((zpage)))(a)) = b) + +#define PEEK(a) (*(volatile uint8_t*)(a)) +#define POKE(a, b) ((*(volatile uint8_t*)(a)) = b) + +#define PEEKW(a) (*(volatile uint16_t*)(a)) +#define POKEW(a, b) ((*(volatile uint16_t*)(a)) = b) + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +// 0x356 - 0x357 actually fall inside the +// decoding table for DISK II sector reading, +// but they're unused bytes! So we can use them +// to store the lfsr_update +#define LFSR_REGISTER_ADDRESS 0x0356 + +void num_to_decbuf(uint16_t n, uint8_t len, uint8_t *buf); +uint8_t bit_reverse(uint8_t b); +uint8_t bit_count(uint8_t b); +void lfsr_init(uint16_t reg); +uint16_t lfsr_update(void); +//void print_line(const char* line, uint8_t off_x, uint8_t off_y); + +#endif /* _UTILITY_HEADER_ */ diff --git a/src/vddem_main.c b/src/vddem_main.c deleted file mode 100644 index de44d1c..0000000 --- a/src/vddem_main.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include - -#include - -#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; -} diff --git a/src/vddlg_main.c b/src/vddlg_main.c deleted file mode 100644 index 905f997..0000000 --- a/src/vddlg_main.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include - -#include - -#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; -} diff --git a/src/vdgam_main.c b/src/vdgam_main.c deleted file mode 100644 index 9ae1d1d..0000000 --- a/src/vdgam_main.c +++ /dev/null @@ -1,198 +0,0 @@ -#include -#include - -#include - -#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; -} diff --git a/src/vdp.s b/src/vdp.s deleted file mode 100644 index fa2a681..0000000 --- a/src/vdp.s +++ /dev/null @@ -1,10 +0,0 @@ - .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 \ No newline at end of file diff --git a/src/vdp_init.h b/src/vdp_init.h deleted file mode 100644 index 09f0e84..0000000 --- a/src/vdp_init.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _VDP_INIT_HEADER_ -#define _VDP_INIT_HEADER_ - -#include - -uint8_t vdp_init(void); - -#endif /* _VDP_INIT_HEADER_ */ diff --git a/src/vdp_init.s b/src/vdp_init.s deleted file mode 100644 index f7dc3a1..0000000 --- a/src/vdp_init.s +++ /dev/null @@ -1,161 +0,0 @@ - .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 - \ No newline at end of file diff --git a/src/vdp_utils.h b/src/vdp_utils.h deleted file mode 100644 index a033dcc..0000000 --- a/src/vdp_utils.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _VDP_UTILS_HEADER_ -#define _VDP_UTILS_HEADER_ - -#include - -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_ */ diff --git a/src/vdp_utils.s b/src/vdp_utils.s deleted file mode 100644 index 69b37c4..0000000 --- a/src/vdp_utils.s +++ /dev/null @@ -1,665 +0,0 @@ - .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 \ No newline at end of file diff --git a/src/vdpin_main.c b/src/vdpin_main.c deleted file mode 100644 index 4d58aa7..0000000 --- a/src/vdpin_main.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -#include - -#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; -}