Repository: andreasjhkarlsson/gbdk-n Branch: master Commit: 2592ba475a06 Files: 87 Total size: 333.4 KB Directory structure: gitextract_01138mzq/ ├── .gitignore ├── Make.bat ├── Makefile ├── README.md ├── bin/ │ ├── gbdk-n-assemble.bat │ ├── gbdk-n-assemble.sh │ ├── gbdk-n-compile.bat │ ├── gbdk-n-compile.sh │ ├── gbdk-n-link.bat │ ├── gbdk-n-link.sh │ ├── gbdk-n-make-rom.bat │ └── gbdk-n-make-rom.sh ├── examples/ │ ├── galaxy/ │ │ ├── Make.bat │ │ ├── Makefile │ │ └── galaxy.c │ ├── paint/ │ │ ├── Make.bat │ │ ├── Makefile │ │ └── paint.c │ ├── space/ │ │ ├── Make.bat │ │ ├── Makefile │ │ └── space.s │ └── thumby/ │ ├── Make.bat │ ├── Makefile │ └── thumby.c ├── include/ │ ├── asm/ │ │ ├── gbz80/ │ │ │ ├── provides.h │ │ │ ├── stdarg.h │ │ │ └── types.h │ │ ├── types.h │ │ └── z80/ │ │ ├── provides.h │ │ ├── stdarg.h │ │ └── types.h │ └── gb/ │ ├── cgb.h │ ├── console.h │ ├── drawing.h │ ├── font.h │ ├── gb.h │ ├── hardware.h │ ├── malloc.h │ ├── rand.h │ ├── sample.h │ └── sgb.h └── libc/ ├── arand.s ├── cgb.s ├── cpy_data.s ├── crt0.s ├── delay.s ├── digits.c ├── drawing.s ├── f_ibm_sh.s ├── f_italic.s ├── f_min.s ├── f_spect.s ├── font.s ├── get_bk_t.s ├── get_data.s ├── get_prop.s ├── get_spr.s ├── get_wi_t.s ├── get_xy_t.s ├── global.s ├── gprint.c ├── gprintf.c ├── gprintln.c ├── gprintn.c ├── hiramcpy.s ├── ibmfixed.s ├── init_tt.s ├── input.s ├── mv_bkg.s ├── mv_spr.s ├── mv_win.s ├── pad.s ├── rand.s ├── sample.s ├── scroll_b.s ├── scroll_s.s ├── scroll_w.s ├── serial.s ├── set_bk_t.s ├── set_data.s ├── set_prop.s ├── set_spr.s ├── set_wi_t.s ├── set_xy_t.s ├── sfr.s ├── sgb.s └── stubs.rasm ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ lib/* obj/* ================================================ FILE: Make.bat ================================================ echo off set SRCDIR=libc set OBJDIR=obj set LIBDIR=lib set CC=bin\gbdk-n-compile.bat set CA=bin\gbdk-n-assemble.bat :: Build examples if "%1"=="examples" ( cd examples echo Building: galaxy && cd galaxy && call Make.bat echo. && echo Building: paint && cd ../paint && call Make.bat echo. && echo Building: space && cd ../space && call Make.bat echo. && echo Building: thumby && cd ../thumby && call Make.bat cd ..\.. goto end ) :: Clean libc + examples if "%1"=="clean" ( echo Cleaning: libc if exist %OBJDIR% rd /s/q %OBJDIR% if exist %LIBDIR% rd /s/q %LIBDIR% cd examples echo Cleaning: galaxy && cd galaxy && call Make.bat clean echo Cleaning: paint && cd ..\paint && call Make.bat clean echo Cleaning: space && cd ..\space && call Make.bat clean echo Cleaning: thumby && cd ..\thumby && call Make.bat clean cd ..\.. echo. goto end ) :: Build libc sources if not exist %OBJDIR% md %OBJDIR% echo Building gb.lib && echo. for %%A in (%SRCDIR%\*.c) do ( if exist %OBJDIR%\%%~nA.rel del %OBJDIR%\%%~nA.rel echo Compiling: %%~nxA && call %CC% %SRCDIR%\%%~nA.c -o %OBJDIR%\%%~nA.rel if not exist %OBJDIR%\%%~nA.rel echo. && echo Build failed! && echo. && pause && goto end ) for %%A in (%SRCDIR%\*.s) do ( if exist %OBJDIR%\%%~nA.rel del %OBJDIR%\%%~nA.rel echo Assembling: %%~nxA && call %CA% %OBJDIR%\%%~nA.rel %SRCDIR%\%%~nA.s if not exist %OBJDIR%\%%~nA.rel echo. && echo Build failed! && echo. && pause && goto end ) if not exist %LIBDIR% md %LIBDIR% if exist %LIBDIR%\crt0.rel del %LIBDIR%\crt0.rel copy /b/v/y %OBJDIR%\crt0.rel %LIBDIR%\crt0.rel :: Write list of inputs for the library if exist %LIBDIR%\gb.lib del %LIBDIR%\gb.lib for %%A in (%OBJDIR%\*.rel) do ( sdar -qv %LIBDIR%\gb.lib %%A ) echo. if not exist %LIBDIR%\gb.lib ( echo Build failed! ) else ( echo Build succeeded! ) echo. :end ================================================ FILE: Makefile ================================================ SRCDIR=./libc OBJDIR=./obj LIBDIR=./lib CC=bin/gbdk-n-compile.sh CA=bin/gbdk-n-assemble.sh .PHONY: lib lib: $(LIBDIR)/gb.lib $(LIBDIR)/crt0.rel $(LIBDIR)/gb.lib: $(LIBDIR)/crt0.rel sdar -qv $(LIBDIR)/gb.lib $(OBJDIR)/*.rel $(LIBDIR)/crt0.rel: chmod u+x bin/* mkdir -p $(OBJDIR) $(CC) $(SRCDIR)/digits.c -o $(OBJDIR)/digits.rel $(CC) $(SRCDIR)/gprint.c -o $(OBJDIR)/gprint.rel $(CC) $(SRCDIR)/gprintf.c -o $(OBJDIR)/gprintf.rel $(CC) $(SRCDIR)/gprintln.c -o $(OBJDIR)/gprintln.rel $(CC) $(SRCDIR)/gprintn.c -o $(OBJDIR)/gprintn.rel $(CA) $(OBJDIR)/arand.rel $(SRCDIR)/arand.s $(CA) $(OBJDIR)/cgb.rel $(SRCDIR)/cgb.s $(CA) $(OBJDIR)/cpy_data.rel $(SRCDIR)/cpy_data.s $(CA) $(OBJDIR)/delay.rel $(SRCDIR)/delay.s $(CA) $(OBJDIR)/drawing.rel $(SRCDIR)/drawing.s $(CA) $(OBJDIR)/f_ibm_sh.rel $(SRCDIR)/f_ibm_sh.s $(CA) $(OBJDIR)/f_italic.rel $(SRCDIR)/f_italic.s $(CA) $(OBJDIR)/f_min.rel $(SRCDIR)/f_min.s $(CA) $(OBJDIR)/font.rel $(SRCDIR)/font.s $(CA) $(OBJDIR)/f_spect.rel $(SRCDIR)/f_spect.s $(CA) $(OBJDIR)/get_bk_t.rel $(SRCDIR)/get_bk_t.s $(CA) $(OBJDIR)/get_data.rel $(SRCDIR)/get_data.s $(CA) $(OBJDIR)/get_prop.rel $(SRCDIR)/get_prop.s $(CA) $(OBJDIR)/get_spr.rel $(SRCDIR)/get_spr.s $(CA) $(OBJDIR)/get_wi_t.rel $(SRCDIR)/get_wi_t.s $(CA) $(OBJDIR)/get_xy_t.rel $(SRCDIR)/get_xy_t.s $(CA) $(OBJDIR)/global.rel $(SRCDIR)/global.s $(CA) $(OBJDIR)/hiramcpy.rel $(SRCDIR)/hiramcpy.s $(CA) $(OBJDIR)/ibmfixed.rel $(SRCDIR)/ibmfixed.s $(CA) $(OBJDIR)/init_tt.rel $(SRCDIR)/init_tt.s $(CA) $(OBJDIR)/input.rel $(SRCDIR)/input.s $(CA) $(OBJDIR)/mv_bkg.rel $(SRCDIR)/mv_bkg.s $(CA) $(OBJDIR)/mv_spr.rel $(SRCDIR)/mv_spr.s $(CA) $(OBJDIR)/mv_win.rel $(SRCDIR)/mv_win.s $(CA) $(OBJDIR)/pad.rel $(SRCDIR)/pad.s $(CA) $(OBJDIR)/rand.rel $(SRCDIR)/rand.s $(CA) $(OBJDIR)/sample.rel $(SRCDIR)/sample.s $(CA) $(OBJDIR)/scroll_b.rel $(SRCDIR)/scroll_b.s $(CA) $(OBJDIR)/scroll_s.rel $(SRCDIR)/scroll_s.s $(CA) $(OBJDIR)/scroll_w.rel $(SRCDIR)/scroll_w.s $(CA) $(OBJDIR)/serial.rel $(SRCDIR)/serial.s $(CA) $(OBJDIR)/set_bk_t.rel $(SRCDIR)/set_bk_t.s $(CA) $(OBJDIR)/set_data.rel $(SRCDIR)/set_data.s $(CA) $(OBJDIR)/set_prop.rel $(SRCDIR)/set_prop.s $(CA) $(OBJDIR)/set_spr.rel $(SRCDIR)/set_spr.s $(CA) $(OBJDIR)/set_wi_t.rel $(SRCDIR)/set_wi_t.s $(CA) $(OBJDIR)/set_xy_t.rel $(SRCDIR)/set_xy_t.s $(CA) $(OBJDIR)/sfr.rel $(SRCDIR)/sfr.s $(CA) $(OBJDIR)/sgb.rel $(SRCDIR)/sgb.s $(CA) $(OBJDIR)/crt0.rel $(SRCDIR)/crt0.s mkdir -p $(LIBDIR) cp $(OBJDIR)/crt0.rel $(LIBDIR)/ .PHONY: examples examples: lib $(MAKE) -C examples/galaxy $(MAKE) -C examples/space $(MAKE) -C examples/thumby $(MAKE) -C examples/paint .PHONY: clean clean: rm -rf $(OBJDIR)/* rm -rf $(LIBDIR)/* $(MAKE) -C examples/galaxy clean $(MAKE) -C examples/space clean $(MAKE) -C examples/thumby clean $(MAKE) -C examples/paint clean ================================================ FILE: README.md ================================================ # gbdk-n #### Background The Gameboy Development Kit (GBDK) is an SDK for developing applications/games for the gameboy platform. The library bundles a custom version of the Small Device C Compiler (SDCC), libraries & examples. The latest update of GBDK was a long time ago (mid 2002). Since then the SDCC compiler has gotten native support for compiling and linking fully functional gameboy roms. However GBDK is still useful since it contains libraries for developing applications for the gameboy family. This project aims to update the libraries to be compatible with new versions of SDCC and provide helpers for building roms. The GBDK libraries are copied from the latest source release on sourceforge: http://sourceforge.net/projects/gbdk/files/gbdk/2.96/ #### Usage ##### Building the library: `$ make` ##### Building the examples: `$ make examples` ##### Building custom ROMs: NOTE: All commands listed below are simply wrappers to SDCC, see the SDCC documentation for flags and general usage. * Compile / assemble .c files and .asm files into .rel files using the gbdk-n-compile.sh and gbdk-n-assemble.sh commands respectively. * Link together one or more .rel files into an .ihx file using the gbdk-n-link.sh command. * Create a ready to use .gb rom file from the .ihx file with the gbdk-n-make-rom.sh command. For exact commands, please see the Makefiles for the example programs. ================================================ FILE: bin/gbdk-n-assemble.bat ================================================ set GBDK_DIR=%~dp0.. sdasgb -plosgff -I"libc" %* ================================================ FILE: bin/gbdk-n-assemble.sh ================================================ #!/bin/sh GBDK_DIR="$( cd "$( dirname "$0" )" && pwd )/.." set -x sdasgb -plosgff -I"libc" "$@" ================================================ FILE: bin/gbdk-n-compile.bat ================================================ set GBDK_DIR=%~dp0.. sdcc -mgbz80 --no-std-crt0 -I "%GBDK_DIR%\include" -I "%GBDK_DIR%\include\asm" -c %* ================================================ FILE: bin/gbdk-n-compile.sh ================================================ #!/bin/sh GBDK_DIR="$( cd "$( dirname "$0" )" && pwd )/.." set -x sdcc -mgbz80 --no-std-crt0 -I "$GBDK_DIR/include" -I "$GBDK_DIR/include/asm" -c "$@" ================================================ FILE: bin/gbdk-n-link.bat ================================================ set GBDK_DIR=%~dp0.. sdcc -mgbz80 --no-std-crt0 --data-loc 0xc0a0 -L "%GBDK_DIR%\lib" "%GBDK_DIR%\lib\crt0.rel" gb.lib -o a.ihx %* ================================================ FILE: bin/gbdk-n-link.sh ================================================ #!/bin/sh GBDK_DIR="$( cd "$( dirname "$0" )" && pwd )/.." set -x sdcc -mgbz80 --no-std-crt0 --data-loc 0xc0a0 -L "$GBDK_DIR/lib" "$GBDK_DIR/lib/crt0.rel" gb.lib -o a.ihx "$@" ================================================ FILE: bin/gbdk-n-make-rom.bat ================================================ makebin -Z %* ================================================ FILE: bin/gbdk-n-make-rom.sh ================================================ #!/bin/sh set -x makebin -Z "$@" ================================================ FILE: examples/galaxy/Make.bat ================================================ echo off set BIN=..\..\bin set OBJ=obj if "%1"=="clean" ( if exist %OBJ% rd /s/q %OBJ% if exist galaxy.gb del galaxy.gb goto end ) if not exist %OBJ% mkdir %OBJ% call %BIN%\gbdk-n-compile.bat galaxy.c -o %OBJ%\galaxy.rel call %BIN%\gbdk-n-link.bat %OBJ%\galaxy.rel -o %OBJ%\galaxy.ihx call %BIN%\gbdk-n-make-rom.bat %OBJ%\galaxy.ihx galaxy.gb :end ================================================ FILE: examples/galaxy/Makefile ================================================ BIN=../../bin OBJ=./obj build: mkdir -p $(OBJ) $(BIN)/gbdk-n-compile.sh galaxy.c -o $(OBJ)/galaxy.rel $(BIN)/gbdk-n-link.sh $(OBJ)/galaxy.rel -o $(OBJ)/galaxy.ihx $(BIN)/gbdk-n-make-rom.sh $(OBJ)/galaxy.ihx galaxy.gb clean: rm -rf $(OBJ) rm -f galaxy.gb ================================================ FILE: examples/galaxy/galaxy.c ================================================ /* * C version of the 'space' assembly demo. * * Little demo illustrating how to use the graphical possibilities * of the GB (background, window and animated sprite) * I have used fixed-point values for both the position and * speed of objects to get smooth movements * * OBJ data : 0x8000 -> 0x8FFF (unsigned) * Window data : 0x8800 -> 0x97FF (unsigned) * Background data : 0x8800 -> 0x97FF (signed) * * Tiled 0xFC -> 0xFF are standard tiles (all black -> all white) * * Keys: * Arrow keys : Change the speed (and direction) of the sprite * Arrow keys + A : Change the speed (and direction) of the window * Arrow keys + B : Change the speed (and direction) of the background * START : Open/close the door * SELECT : Basic fading effect * * Note that the window is kept in the lower right part of the screen * since it can't be made transparent */ #include const unsigned char std_data[] = { /* Basic tiles (0xFC to 0xFF) */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; const unsigned char earth_data[] = { /* Tile 0x00 */ 0x07,0x07,0x18,0x1F,0x32,0x2D,0x71,0x4E,0x70,0x4F,0xF8,0x87,0xF8,0x87,0xF8,0x87, 0xFC,0x83,0xFE,0x81,0x7F,0x40,0x7F,0x40,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0xF0,0x30,0x78,0x88,0x3C,0xC4,0x5C,0xA4,0x9E,0x62,0x3E,0xC2,0x3E,0xC2, 0x5E,0xA2,0x7E,0x82,0x0C,0xF4,0x0C,0xF4,0x98,0x68,0xB0,0x70,0xC0,0xC0,0x00,0x00, 0x07,0x07,0x1F,0x18,0x2F,0x30,0x4F,0x70,0x6F,0x50,0x9F,0xE0,0x9F,0xE0,0xBF,0xC0, 0xFF,0x80,0xB7,0xC8,0x63,0x5C,0x43,0x7C,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0xB0,0x70,0x18,0xE8,0x0C,0xF4,0x0C,0xF4,0x82,0x7E,0x82,0x7E,0x86,0x7A, 0xC6,0x3A,0xE6,0x1A,0xF4,0x0C,0xFC,0x04,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00, /* Tile 0x08 */ 0x07,0x07,0x1E,0x19,0x20,0x3F,0x40,0x7F,0x42,0x7D,0x81,0xFE,0x81,0xFE,0x83,0xFC, 0xD7,0xA8,0xBB,0xC4,0x6E,0x51,0x7C,0x43,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0x70,0xB0,0xE8,0x18,0xF4,0x0C,0xF4,0x0C,0xFE,0x02,0xFE,0x02,0xFE,0x02, 0xFE,0x02,0x7E,0x82,0x3C,0xC4,0x3C,0xC4,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00, 0x07,0x07,0x1B,0x1C,0x20,0x3F,0x40,0x7F,0x40,0x7F,0xE0,0x9F,0x90,0xEF,0x89,0xF6, 0x8D,0xF2,0x9F,0xE0,0x5E,0x61,0x6F,0x50,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0xB0,0x70,0x28,0xD8,0x04,0xFC,0x2C,0xD4,0x1E,0xE2,0x1E,0xE2,0x3E,0xC2, 0x7E,0x82,0xB6,0x4A,0xE4,0x1C,0xC4,0x3C,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00, /* Tile 0x10 */ 0x07,0x07,0x18,0x1F,0x20,0x3F,0x40,0x7F,0x40,0x7F,0xEE,0x91,0xF1,0x8E,0xE0,0x9F, 0xE0,0x9F,0xF1,0x8E,0x71,0x4E,0x72,0x4D,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0xF0,0x30,0x08,0xF8,0x04,0xFC,0x04,0xFC,0x02,0xFE,0x02,0xFE,0x92,0x6E, 0xD6,0x2A,0xFE,0x02,0xEC,0x14,0xFC,0x04,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00, 0x07,0x07,0x1D,0x1A,0x36,0x29,0x5C,0x63,0x6C,0x53,0xCE,0xB1,0x9F,0xE0,0x9E,0xE1, 0xAE,0xD1,0xBF,0xC0,0x47,0x78,0x47,0x78,0x2F,0x30,0x1F,0x18,0x07,0x07,0x00,0x00, 0xC0,0xC0,0x70,0xB0,0x08,0xF8,0x04,0xFC,0x04,0xFC,0xE2,0x1E,0x32,0xCE,0x0E,0xF2, 0x0E,0xF2,0x1E,0xE2,0x1C,0xE4,0x2C,0xD4,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00, /* Tile 0x18 */ 0x07,0x07,0x1E,0x19,0x33,0x2C,0x49,0x76,0x42,0x7D,0xC4,0xBB,0xC1,0xBE,0xC1,0xBE, 0xE2,0x9D,0xF3,0x8C,0x78,0x47,0x78,0x47,0x3C,0x23,0x1C,0x1B,0x07,0x07,0x00,0x00, 0xC0,0xC0,0x70,0xB0,0x68,0x98,0xC4,0x3C,0xC4,0x3C,0xEE,0x12,0xF2,0x0E,0xE2,0x1E, 0xE2,0x1E,0xF2,0x0E,0x7C,0x84,0x7C,0x84,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 }; const unsigned char frame_data[] = { /* Tile 0x00 */ 0xFF,0x00,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F, 0xFF,0x00,0x01,0xFE,0x03,0xFC,0x07,0xF8,0x0F,0xF0,0x1F,0xE0,0x3F,0xC0,0x7F,0x80, 0xFF,0x00,0xFE,0x01,0xFC,0x03,0xF8,0x07,0xF0,0x0F,0xE0,0x1F,0xC0,0x3F,0x80,0x7F, 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0xFF,0x00,0xFF,0x01,0xFD,0x03,0xF9,0x07,0xF1,0x0F,0xE1,0x1F,0xC1,0x3F,0x81,0x7F, 0x80,0x7F,0x81,0x7E,0x83,0x7C,0x87,0x78,0x8F,0x70,0x9F,0x60,0xBF,0x40,0xFF,0x00, 0xFF,0x70,0xFF,0x98,0xEF,0xB8,0xCF,0xF8,0xFF,0x70,0xFF,0x00,0xFF,0x00,0xFF,0x01, 0xFF,0x00,0xFE,0x01,0xFC,0x03,0xF8,0x07,0xF0,0x0F,0xE0,0x1F,0xC0,0x3F,0xFF,0xFF, /* Tile 0x08 */ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF, 0x00,0xFF,0x01,0xFE,0x03,0xFC,0x07,0xF8,0x0F,0xF0,0x1F,0xE0,0x3F,0xC0,0xFF,0xFF, 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF, 0xFF,0x0E,0xFF,0x13,0xFD,0x17,0xF9,0x1F,0xFE,0x0F,0xE0,0x1F,0xC0,0x3F,0x80,0xFF, 0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF, 0xFF,0x01,0xFF,0x01,0xFD,0x03,0xF9,0x07,0xF1,0x0F,0xE1,0x1F,0xC1,0x3F,0x81,0x7F, 0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F, 0x01,0xFF,0x01,0xFF,0x03,0xFD,0x07,0xF9,0x0F,0xF1,0x1F,0xE1,0x3F,0xC1,0x7F,0x81, /* Tile 0x10 */ 0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01, 0x01,0xFF,0x01,0xFE,0x03,0xFC,0x77,0xF8,0xFF,0x98,0xEF,0xB8,0xCF,0xF8,0x7F,0xF0, 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x0E,0xFF,0x13,0xFD,0x17,0xF9,0x1F,0xFF,0x0E, 0x80,0x7F,0x81,0x7E,0x83,0x7C,0x87,0x78,0x8F,0x70,0x9F,0x60,0xBF,0x40,0xFF,0x7F, 0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0xFF,0xFF, /* Door1 */ /* Tile 0x15 */ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF, /* Door2 */ /* Tile 0x18 */ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF, 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF, 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* Door3 */ /* Tile 0x1C */ 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF, 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* Door4 */ /* Tile 0x20 */ 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF }; const unsigned char bkg_data[] = { /* Tile 0x00 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xEF,0xFF,0xFF,0xF7,0xFF,0xFB,0xFF,0xFD,0xFF,0xFE,0xFE,0xFF, /* Tile 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7D,0xFE,0x7C,0x39, 0xFF,0xFF,0xF7,0xFF,0xEF,0xFF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFD, 0xBB,0x01,0xC7,0x83,0xC7,0x83,0xC7,0x83,0xBB,0x01,0x7C,0x39,0x7D,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,0xAF,0x77,0x27,0x8F,0xDF,0x8F,0x27,0x8F, /* Tile 0x10 */ 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xF7,0xEF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xFF,0xDF,0xEF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xAF,0x77,0xFF,0xFB,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, /* Tile 0x18 */ 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x7D,0xFE,0x7C,0x39, 0xFF,0xFF,0xF7,0xFF,0xEF,0xFF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFD, /* Tile 0x20 */ 0xFF,0xFF,0xDF,0xFF,0xEF,0xFF,0xFF,0xF7,0xFF,0xFB,0xFE,0xFD,0xFD,0xFE,0xFE,0xFF, 0xAB,0x11,0xC7,0x83,0x83,0xC7,0xC7,0x83,0xAB,0x11,0x7C,0x39,0x7D,0xFE,0xFE,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0x7F, 0xFB,0xFF,0xFF,0xFD,0xFE,0xFE,0xFE,0xFF,0xFE,0xFE,0xFF,0xFD,0xFB,0xFF,0xFF,0xFF, 0xEF,0xFF,0xFF,0xDF,0x3F,0xBF,0x3F,0x7F,0x3F,0xBF,0xFF,0xDF,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFD,0xFE,0xFE,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF, /* Tile 0x28 */ 0xF7,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF }; /* * Image size: 0x40 x 0x40 * Number of tiles (total - unique): 0x40 - 0x2D */ const unsigned char bkg_tiles[] = { 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC, 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A, 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC, 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14, 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC, 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20, 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26, 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 }; /* * Image size: 0x10 x 0x70 * Number of tiles (total - unique): 0x1C - 0x1C */ const unsigned char earth_tiles[] = { 0x00,0x02, 0x04,0x06, 0x08,0x0A, 0x0C,0x0E, 0x10,0x12, 0x14,0x16, 0x18,0x1A }; /* * Image size: 0x80 x 0x50 * Number of tiles (total - unique): 0xA0 - 0x15 */ const unsigned char frame_tiles[] = { 0x80,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x84, 0x85,0x86,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x8B,0x8C, 0xFD,0x8D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E,0x8F, 0x82,0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85,0x90, 0x8E,0x8F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x8D, 0x85,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x82,0x8C, 0xFD,0x8D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E,0x8F, 0x82,0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85,0x90, 0x8E,0x91,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0x92,0x8D, 0x93,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x94 }; /* * Image size: 0x60 x 0x30 * Number of tiles (total - unique): 0x48 - 0x03 */ const unsigned char door1_tiles[] = { 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95, 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96, 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97, 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95, 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96, 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC }; /* * Image size: 0x60 x 0x30 * Number of tiles (total - unique): 0x48 - 0x04 */ const unsigned char door2_tiles[] = { 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98, 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A, 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98, 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, }; /* * Image size: 0x60 x 0x30 * Number of tiles (total - unique): 0x48 - 0x04 */ const unsigned char door3_tiles[] = { 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C, 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D, 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E, 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C, 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D, 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC }; /* * Image size: 0x60 x 0x30 * Number of tiles (total - unique): 0x48 - 0x01 */ const unsigned char door4_tiles[] = { 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95, 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96, 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97, 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95, 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96, 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC }; /* Should really be const, but sdcc doesnt yet support it. */ const unsigned char * const film[] = { &door1_tiles[0x0C*0], &door2_tiles[0x0C*0], &door3_tiles[0x0C*0], &door4_tiles[0x0C*0], &door1_tiles[0x0C*1], &door2_tiles[0x0C*1], &door3_tiles[0x0C*1], &door4_tiles[0x0C*1], &door1_tiles[0x0C*2], &door2_tiles[0x0C*2], &door3_tiles[0x0C*2], &door4_tiles[0x0C*2], &door1_tiles[0x0C*3], &door2_tiles[0x0C*3], &door3_tiles[0x0C*3], &door4_tiles[0x0C*3], &door1_tiles[0x0C*4], &door2_tiles[0x0C*4], &door3_tiles[0x0C*4], &door4_tiles[0x0C*4], &door1_tiles[0x0C*5], &door2_tiles[0x0C*5], &door3_tiles[0x0C*5], &door4_tiles[0x0C*5], &door1_tiles[0x0C*6] }; #define NBDFRAMES 0x18 /* Nb frames for the door */ #define NBSFRAMES 0x07 /* Nb frames for the sprite */ #define WINSZX 0x80 /* Size of the picture in the window */ #define WINSZY 0x50 #define MINWINX (MAXWNDPOSX-WINSZX+1) /* Bounds of the window origin */ #define MINWINY (MAXWNDPOSY-WINSZY+1) #define MAXWINX MAXWNDPOSX #define MAXWINY MAXWNDPOSY #define FADESTEP 0x10 /* Nb steps for the fading effect */ #define STARTFADE (0x06*FADESTEP) /* Initial value for the fading effect */ #define CLOSED 0x00 #define OPENING 0x01 #define OPENED 0x02 #define CLOSING 0x03 static UBYTE time; /* Global "time" value (counter) */ UBYTE doorstate; /* State of the door (OPENED, CLOSED...) */ UBYTE doorpos; /* Current position in the door animation */ static UBYTE color; /* Current color for fading effect */ UBYTE sframe; /* Current frame of the sprite */ fixed bposx, bposy; /* Background position (fixed point) */ fixed bspx, bspy; /* Background speed (fixed point) */ fixed wposx, wposy; /* Window position (fixed point) */ fixed wspx, wspy; /* Window speed (fixed point) */ fixed sposx, sposy; /* Sprite position (fixed point) */ fixed sspx, sspy; /* Sprite speed (fixed point) */ void fade(); void scroll(); void door(); void animate_sprite(); void tile_sprite(); void place_sprite(); /* Fade the screen (off and on) */ void fade() { if(color == 0) return; switch(color) { case STARTFADE: case STARTFADE-4*FADESTEP: BGP_REG = 0xF9U; break; case STARTFADE-FADESTEP: case STARTFADE-3*FADESTEP: BGP_REG = 0xFEU; break; case STARTFADE-2*FADESTEP: BGP_REG = 0xFFU; break; case STARTFADE-5*FADESTEP: BGP_REG = 0xE4U; break; } color--; } /* Scroll the background, the window and the sprite */ void scroll() { /* Update background */ bposx.w += bspx.w; bposy.w += bspy.w; SCX_REG = bposx.b.h; SCY_REG = bposy.b.h; /* Update window */ wposx.w += wspx.w ; wposy.w += wspy.w ; /* X position */ if(wposx.b.h >= MAXWINX) { wposx.b.h = MAXWINX; /* Invert speed */ wspx.w = -(WORD)wspx.w; } else if(wposx.b.h <= MINWINX) { wposx.b.h = MINWINX; /* Invert speed */ wspx.w = -(WORD)wspx.w; } WX_REG = wposx.b.h; /* Y position */ if(wposy.b.h >= MAXWINY) { wposy.b.h = MAXWINY; /* Invert speed */ wspy.w = -(WORD)wspy.w; } else if(wposy.b.h <= MINWINY) { wposy.b.h = MINWINY; /* Invert speed */ wspy.w = -(WORD)wspy.w; } WY_REG = wposy.b.h; /* Update sprite */ sposx.w += sspx.w; sposy.w += sspy.w; place_sprite(); } /* Open and close the door */ void door() { if(doorstate == OPENING) { doorpos++; /* Draw the door in the window */ set_win_tiles(2, 2, 12, 6, film[doorpos]); if(doorpos == NBDFRAMES) doorstate = OPENED; } else if(doorstate == CLOSING) { doorpos--; /* Draw the door in the window */ set_win_tiles(2, 2, 12, 6, film[doorpos]); if(doorpos == 0) doorstate = CLOSED; } } /* Animate sprite */ void animate_sprite() { if((time&0x07) == 0) { sframe++; if(sframe == NBSFRAMES) sframe = 0; tile_sprite(); } } /* Set sprite tiles */ void tile_sprite() { UBYTE s; s = sframe<<1; set_sprite_tile(0, earth_tiles[s]); set_sprite_tile(1, earth_tiles[s+1]); } /* Place sprite */ void place_sprite() { move_sprite(0, sposx.b.h, sposy.b.h); move_sprite(1, sposx.b.h+8, sposy.b.h); } void main() { UBYTE i, j; disable_interrupts(); DISPLAY_OFF; LCDC_REG = 0x67; /* * LCD = Off * WindowBank = 0x9C00 * Window = On * BG Chr = 0x8800 * BG Bank = 0x9800 * OBJ = 8x16 * OBJ = On * BG = On */ doorstate = CLOSED; /* Set palettes */ BGP_REG = OBP0_REG = OBP1_REG = 0xE4U; /* Initialize the background */ set_bkg_data(0xFC, 0x04, std_data); set_bkg_data(0x00, 0x2D, bkg_data); /* * Draw the background * * Width = 0x100 = 0x20 * 8 * Height = 0x100 = 0x20 * 8 */ for(i = 0; i < 32; i+=8) for(j = 0; j < 32; j+=8) set_bkg_tiles(i, j, 8, 8, bkg_tiles); bposx.w = 0; SCX_REG = 0; bposy.w = 0; SCY_REG = 0; bspx.w = 0xFF00; bspy.w = 0x0080; /* Initialize the window */ set_win_data(0x80, 0x21, frame_data); /* * Draw the frame in the window * * Width = 0x80 = 0x10 * 8 * Height = 0x50 = 0x0A * 8 */ set_win_tiles(0, 0, 16, 10, frame_tiles); /* * Draw the door in the window * * Width = 0x60 = 0x20 * 12 * Height = 0x30 = 0x20 * 6 */ set_win_tiles(2, 2, 12, 6, door1_tiles); wposx.b.h = MAXWNDPOSX; wposx.b.l = 0; WX_REG = MAXWNDPOSX; wposy.b.h = MAXWNDPOSY; wposy.b.l = 0; WY_REG = MAXWNDPOSY; wspx.w = 0xFF80; wspy.w = 0xFFC0; /* Initialize the sprite */ set_sprite_data(0x00, 0x1C, earth_data); set_sprite_prop(0, 0x00); set_sprite_prop(1, 0x00); sframe = 0; sposx.w = 0x1000; sposy.w = 0x1000; sspx.w = 0x0040; sspy.w = 0x0040; tile_sprite(); place_sprite(); DISPLAY_ON; enable_interrupts(); while(1) { /* Skip four VBLs (slow down animation) */ for(i = 0; i < 4; i++) wait_vbl_done(); time++; fade(); door(); scroll(); animate_sprite(); i = joypad(); if(i & J_B) { if(i & J_UP) bspy.w -= 0x0010; if(i & J_DOWN) bspy.w += 0x0010; if(i & J_LEFT) bspx.w -= 0x0010; if(i & J_RIGHT) bspx.w += 0x0010; } else if(i & J_A) { if(i & J_UP) wspy.w -= 0x0010; if(i & J_DOWN) wspy.w += 0x0010; if(i & J_LEFT) wspx.w -= 0x0010; if(i & J_RIGHT) wspx.w += 0x0010; } else { if(i & J_SELECT) color = STARTFADE; if(i & J_START) if(doorstate == CLOSED) { doorstate = OPENING; doorpos = 0; } else if(doorstate == OPENED) { doorstate = CLOSING; doorpos = NBDFRAMES; } if(i & J_UP) sspy.w -= 0x0010; if(i & J_DOWN) sspy.w += 0x0010; if(i & J_LEFT) sspx.w -= 0x0010; if(i & J_RIGHT) sspx.w += 0x0010; } } } ================================================ FILE: examples/paint/Make.bat ================================================ echo off set BIN=..\..\bin set OBJ=obj if "%1"=="clean" ( if exist %OBJ% rd /s/q %OBJ% if exist paint.gb del paint.gb goto end ) if not exist %OBJ% mkdir %OBJ% call %BIN%\gbdk-n-compile.bat paint.c -o %OBJ%\paint.rel call %BIN%\gbdk-n-link.bat %OBJ%\paint.rel -o %OBJ%\paint.ihx call %BIN%\gbdk-n-make-rom.bat %OBJ%\paint.ihx paint.gb :end ================================================ FILE: examples/paint/Makefile ================================================ BIN=../../bin OBJ=./obj build: mkdir -p $(OBJ) $(BIN)/gbdk-n-compile.sh paint.c -o $(OBJ)/paint.rel $(BIN)/gbdk-n-link.sh $(OBJ)/paint.rel -o $(OBJ)/paint.ihx $(BIN)/gbdk-n-make-rom.sh $(OBJ)/paint.ihx paint.gb clean: rm -rf $(OBJ) rm -f paint.gb ================================================ FILE: examples/paint/paint.c ================================================ #include #include #define NB_TOOLS 18 #define NB_DATA_TILES 48 #define ARROW 0 #define PEN 1 #define BRUSH 2 #define FILL 3 #define ERASER 4 #define CROSS 5 #define UNSELECTED 0 #define SELECTED 1 #define FIRST_TOOL 0 #define LAST_TOOL 9 #define FIRST_COLOR 10 #define LAST_COLOR 13 #define FIRST_MODE 14 #define LAST_MODE 17 #define NULL 0 typedef struct icon_info_ { UBYTE data_idx; /* Index of data in the data array */ UBYTE x, y, w, h; /* Position and size (in tiles) */ UBYTE up, down, left, right; /* Index of next icons (for cursor movements) */ UBYTE cursor; /* Cursor associated with icon */ } icon_info; typedef struct cursor_info_ { UBYTE data_idx; /* Index of data in the data array */ UBYTE w, h; /* Size (in tiles) */ UBYTE hot_x, hot_y; /* Position of hot point, relatice to top-left of sprite (in pixels) */ } cursor_info; const icon_info icons[] = { /* Pen */ { 0, 0, 0, 2, 2, 10, 2, 1, 1, 1 }, /* 0 */ /* Brush */ { 4, 2, 0, 2, 2, 14, 3, 0, 0, 2 }, /* 1 */ /* Fill */ { 8, 0, 2, 2, 2, 0, 4, 3, 3, 3 }, /* 2 */ /* Eraser */ { 12, 2, 2, 2, 2, 1, 5, 2, 2, 4 }, /* 3 */ /* Line */ { 16, 0, 4, 2, 2, 2, 6, 5, 5, 5 }, /* 4 */ /* Line */ { 20, 2, 4, 2, 2, 3, 7, 4, 4, 5 }, /* 5 */ /* Rectangle */ { 24, 0, 6, 2, 2, 4, 8, 7, 7, 5 }, /* 6 */ /* Oval */ { 28, 2, 6, 2, 2, 5, 9, 6, 6, 5 }, /* 7 */ /* Filled rectangle */ { 32, 0, 8, 2, 2, 6, 10, 9, 9, 5 }, /* 8 */ /* Filled oval */ { 36, 2, 8, 2, 2, 7, 14, 8, 8, 5 }, /* 9 */ /* Color */ { 40, 0, 10, 1, 1, 8, 11, 16, 12, 0 }, /* 10 */ { 41, 0, 11, 1, 1, 10, 0, 17, 13, 0 }, /* 11 */ { 42, 1, 10, 1, 1, 8, 13, 10, 14, 0 }, /* 12 */ { 43, 1, 11, 1, 1, 12, 0, 11, 15, 0 }, /* 13 */ /* Mode */ { 44, 2, 10, 1, 1, 9, 15, 12, 16, 0 }, /* 14 */ { 45, 2, 11, 1, 1, 14, 1, 13, 17, 0 }, /* 15 */ { 46, 3, 10, 1, 1, 9, 17, 14, 10, 0 }, /* 16 */ { 47, 3, 11, 1, 1, 16, 1, 15, 11, 0 } /* 17 */ }; const unsigned char data[NB_DATA_TILES][0x10] = { /* Pen */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 }, { 0x7E,0x02,0x7D,0x05,0x7B,0x0A,0x77,0x14,0x7F,0x18,0x7F,0x27,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 }, { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x01,0x00,0xFF }, /* Brush */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 }, { 0x7E,0x02,0x7D,0x0D,0x7F,0x1E,0x7F,0x1E,0x7F,0x1D,0x7F,0x11,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 }, { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0xFD,0xFE,0x01,0x00,0xFF }, /* Fill */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7F,0x02,0x7E,0x0C,0x7D,0x18,0x7E,0x1D }, { 0x7F,0x1B,0x7F,0x19,0x7F,0x18,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x81,0xFE,0x41,0x7E,0x21,0xBE,0x71,0x5E,0xE9,0xAE,0xC5 }, { 0x5E,0x89,0xBE,0x11,0xFE,0xA1,0xFE,0x41,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Eraser */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7E,0x02,0x7C,0x04 }, { 0x78,0x08,0x7F,0x1F,0x71,0x11,0x7F,0x1F,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xF9,0x1E,0x19,0x2E,0x29,0x5E,0x51 }, { 0xBE,0xA1,0x7E,0x41,0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Line */ { 0x00,0x00,0x7F,0x00,0x7F,0x20,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x02,0x7F,0x01 }, { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01 }, { 0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11,0xFE,0x09,0xFE,0x05,0xFE,0x01,0x00,0xFF }, /* Arc */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x1E,0x7F,0x01,0x7F,0x00,0x7F,0x00,0x7F,0x00 }, { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11 }, { 0xFE,0x11,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Rectangle */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20 }, { 0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05 }, { 0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Oval */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7F,0x0C,0x7F,0x10,0x7F,0x20,0x7F,0x20 }, { 0x7F,0x20,0x7F,0x20,0x7F,0x10,0x7F,0x0C,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xFE,0x31,0xFE,0x09,0xFE,0x05,0xFE,0x05 }, { 0xFE,0x05,0xFE,0x05,0xFE,0x09,0xFE,0x31,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Filled rectangle */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F }, { 0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD }, { 0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Filled oval */ { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7E,0x0F,0x75,0x1F,0x6A,0x3F,0x75,0x3F }, { 0x6A,0x3F,0x75,0x3F,0x7A,0x1F,0x7D,0x0F,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F }, { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xBE,0xF1,0x5E,0xF9,0xAE,0xFD,0x56,0xFD }, { 0xAE,0xFD,0x56,0xFD,0xAE,0xF9,0x7E,0xF1,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF }, /* Color */ { 0x00,0x00,0x7F,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, { 0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x7F,0x7F,0x00,0x7F }, { 0x00,0x00,0xFE,0xFF,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03 }, { 0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0x00,0xFF }, /* Mode */ { 0x00,0x00,0x7F,0x00,0x7F,0x0C,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x18,0x7F,0x00 }, { 0x7F,0x00,0x7F,0x08,0x7F,0x14,0x7F,0x14,0x7F,0x14,0x7F,0x08,0x7F,0x00,0x00,0x7F }, { 0x00,0x01,0xFE,0x01,0xFE,0x29,0xFE,0x29,0xFE,0x11,0xFE,0x29,0xFE,0x29,0xFE,0x01 }, { 0xFE,0x01,0xFE,0x11,0xFE,0x29,0xFE,0x39,0xFE,0x29,0xFE,0x29,0xFE,0x01,0x00,0xFF } }; const unsigned char selected_data[NB_DATA_TILES][0x10] = { /* Pen */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE }, { 0x81,0xFD,0x82,0xFA,0x84,0xF5,0x88,0xEB,0x80,0xE7,0x80,0xD8,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE }, { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFE,0xFF,0x00 }, /* Brush */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE }, { 0x81,0xFD,0x82,0xF2,0x80,0xE1,0x80,0xE1,0x80,0xE2,0x80,0xEE,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE }, { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0x02,0x01,0xFE,0xFF,0x00 }, /* Fill */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x80,0xFD,0x81,0xF3,0x82,0xE7,0x81,0xE2 }, { 0x80,0xE4,0x80,0xE7,0x80,0xE7,0x80,0xF7,0x80,0xF7,0x80,0xF7,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x81,0xDE,0x41,0x8E,0xA1,0x16,0x51,0x3A }, { 0xA1,0x76,0x41,0xEE,0x01,0x5E,0x01,0xBE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Eraser */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x81,0xFD,0x83,0xFB }, { 0x87,0xF7,0x80,0xE0,0x8E,0xEE,0x80,0xE0,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x06,0xE1,0xE6,0xD1,0xD6,0xA1,0xAE }, { 0x41,0x5E,0x81,0xBE,0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Line */ { 0xFF,0xFF,0x80,0xFF,0x80,0xDF,0x80,0xEF,0x80,0xF7,0x80,0xFB,0x80,0xFD,0x80,0xFE }, { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE }, { 0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE,0x01,0xF6,0x01,0xFA,0x01,0xFE,0xFF,0x00 }, /* Arc */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xE1,0x80,0xFE,0x80,0xFF,0x80,0xFF,0x80,0xFF }, { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE }, { 0x01,0xEE,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Rectangle */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF }, { 0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA }, { 0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Oval */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x80,0xF3,0x80,0xEF,0x80,0xDF,0x80,0xDF }, { 0x80,0xDF,0x80,0xDF,0x80,0xEF,0x80,0xF3,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0x01,0xCE,0x01,0xF6,0x01,0xFA,0x01,0xFA }, { 0x01,0xFA,0x01,0xFA,0x01,0xF6,0x01,0xCE,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Filled rectangle */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0 }, { 0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02 }, { 0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Filled oval */ { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x83,0xF0,0x8F,0xE0,0x9F,0xC0,0x9F,0xC0 }, { 0x9F,0xC0,0x9F,0xC0,0x8F,0xE0,0x83,0xF0,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0xC1,0x0E,0xF1,0x06,0xF9,0x02,0xF9,0x02 }, { 0xF9,0x02,0xF9,0x02,0xF1,0x06,0xC1,0x0E,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, /* Color */ { 0x00,0x00,0x7F,0x7F,0x61,0x61,0x52,0x52,0x4C,0x4C,0x4C,0x4C,0x52,0x52,0x61,0x61 }, { 0x40,0x5E,0x40,0x6D,0x40,0x73,0x40,0x73,0x40,0x6D,0x40,0x5E,0x7F,0x7F,0x00,0x7F }, { 0x00,0x00,0xFE,0xFF,0xFE,0x87,0xFE,0x4B,0xFE,0x33,0xFE,0x33,0xFE,0x4B,0xFE,0x87 }, { 0x7A,0x7B,0xB6,0xB7,0xCE,0xCF,0xCE,0xCF,0xB6,0xB7,0x7A,0x7B,0xFE,0xFF,0x00,0xFF }, /* Mode */ { 0x00,0x00,0x7F,0x7F,0x73,0x73,0x6F,0x6F,0x77,0x77,0x7B,0x7B,0x67,0x67,0x7F,0x7F }, { 0x7F,0x7F,0x77,0x77,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x77,0x77,0x7F,0x7F,0x00,0x7F }, { 0x00,0x01,0xFE,0xFF,0xD6,0xD7,0xD6,0xD7,0xEE,0xEF,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF }, { 0xFE,0xFF,0xEE,0xEF,0xD6,0xD7,0xC6,0xC7,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF,0x00,0xFF } }; const cursor_info cursors[] = { /* Arrow */ { 0, 1, 1, 0, 0 }, /* Pen */ { 1, 2, 2, 0, 15 }, /* Brush */ { 5, 2, 2, 0, 15 }, /* Fill */ { 9, 2, 2, 2, 15 }, /* Eraser */ { 13, 2, 2, 0, 15 }, /* Cross */ { 17, 2, 2, 5, 10 } }; const unsigned char cursors_data[][0x10] = { /* Arrow */ { 0xFF,0x00,0xFF,0x7E,0xFF,0x7C,0xFE,0x78,0xFF,0x7C,0xFF,0x6E,0xFF,0x46,0xEF,0x00 }, /* Pen */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01 }, { 0x0F,0x02,0x1F,0x05,0x3F,0x0A,0x7F,0x14,0x7E,0x28,0xFC,0x30,0xF8,0x40,0x60,0x00 }, { 0x00,0x00,0x00,0x00,0x3C,0x00,0x7C,0x18,0xFC,0x28,0xFC,0x50,0xF8,0xA0,0xF0,0x40 }, { 0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, /* Brush */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01,0x0F,0x02 }, { 0x1F,0x05,0x7F,0x0A,0xFF,0x34,0xFE,0x78,0xFC,0x78,0xFC,0x70,0xF8,0x40,0x60,0x00 }, { 0x00,0x00,0x00,0x00,0x78,0x00,0xF8,0x30,0xF8,0x50,0xF8,0xA0,0xF0,0x40,0xE0,0x80 }, { 0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, /* Fill */ { 0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x02,0x1F,0x05,0x7F,0x08,0xFE,0x31,0xFD,0x63 }, { 0xFA,0x77,0xFD,0x6E,0xFF,0x64,0xFF,0x62,0xF7,0x21,0x73,0x20,0x70,0x20,0x50,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x00,0xE0,0x80,0xF0,0xC0,0x78,0xA0 }, { 0xF8,0x10,0xF8,0x20,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 }, /* Eraser */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x03 }, { 0x1F,0x04,0x3F,0x08,0x7F,0x11,0xFF,0x22,0xFF,0x7D,0xFF,0x46,0xFF,0x7C,0x7E,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0xE0 }, { 0xF0,0x60,0xF0,0xA0,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 }, /* Cross */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x04,0x0E,0x04 }, { 0x0E,0x04,0xFF,0x04,0xFB,0x7B,0xFF,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0xE0,0x00,0xE0,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, }; unsigned char data_buffer[NB_DATA_TILES][0x10]; const UBYTE colors[] = { WHITE, DKGREY, LTGREY, BLACK }; const UBYTE modes[] = { SOLID, OR, XOR, AND }; UBYTE current_tool; UBYTE current_color; UBYTE current_mode; UBYTE current_cursor; UBYTE menu_cursor_pos; UBYTE cursor_x; UBYTE cursor_y; void set_cursor() { UBYTE x, y, i; i = 0; for(x = 0; x < cursors[current_cursor].w; x++) for(y = 0; y < cursors[current_cursor].h; y++) { set_sprite_data(i, 1, cursors_data[cursors[current_cursor].data_idx+i]); set_sprite_tile(i, i); set_sprite_prop(i, 0x10); i++; } /* Hide unused sprites */ for(; i < 4; i++) { move_sprite(i, 0, 0); } } void move_cursor() { UBYTE x, y; for(x = 0; x < cursors[current_cursor].w; x++) for(y = 0; y < cursors[current_cursor].h; y++) move_sprite((x<<1)+y, cursor_x+8 - cursors[current_cursor].hot_x + (x<<3), cursor_y+16 - cursors[current_cursor].hot_y + (y<<3)); } void move_menu_cursor() { move_sprite(0, ((icons[menu_cursor_pos].x+icons[menu_cursor_pos].w)<<3) + 4, ((icons[menu_cursor_pos].y+icons[menu_cursor_pos].h)<<3) + 12); } void set_icon(UBYTE icon, UBYTE selected) { UBYTE x, y; for(x = 0; x < icons[icon].w; x++) for(y = 0; y < icons[icon].h; y++) { UWORD index = icons[icon].data_idx+((UWORD)x<<1)+y; switch_data(icons[icon].x + x, icons[icon].y + y, selected ? selected_data[index] : data[index], data_buffer[index]); } } void change_icon(UBYTE icon, UBYTE selected) { UBYTE x, y; for(x = 0; x < icons[icon].w; x++) for(y = 0; y < icons[icon].h; y++) switch_data(icons[icon].x + x, icons[icon].y + y, (selected ? selected_data[icons[icon].data_idx+((UWORD)x<<1)+y] : data[icons[icon].data_idx+((UWORD)x<<1)+y]), NULL); } void reset_icon(UBYTE icon) { UBYTE x, y; for(x = 0; x < icons[icon].w; x++) for(y = 0; y < icons[icon].h; y++) switch_data(icons[icon].x + x, icons[icon].y + y, data_buffer[icons[icon].data_idx+(x<<1)+y], NULL); } void splash() { UBYTE x, y; cursor_x = 40; cursor_y = 50; current_cursor = PEN; set_cursor(); move_cursor(); SHOW_SPRITES; for(; cursor_x < 120; cursor_x++) { wait_vbl_done(); move_cursor(); plot(cursor_x, cursor_y, BLACK, SOLID); } for(; cursor_y < 94; cursor_y++) { wait_vbl_done(); move_cursor(); plot(cursor_x, cursor_y, BLACK, SOLID); } for(; cursor_x > 40; cursor_x--) { wait_vbl_done(); move_cursor(); plot(cursor_x, cursor_y, BLACK, SOLID); } for(; cursor_y > 50; cursor_y--) { wait_vbl_done(); move_cursor(); plot(cursor_x, cursor_y, BLACK, SOLID); } cursor_x = 160/2; cursor_y = 144/2; current_cursor = FILL; set_cursor(); move_cursor(); for(y = 51; y < 94; y++) for(x = 41; x < 120; x++) plot(x, y, LTGREY, SOLID); // HIDE_SPRITES; } void menu() { UBYTE i, key; UBYTE slowdown; UBYTE cursor; slowdown = 50; for(i = 0; i < NB_TOOLS; i++) set_icon(i, i == FIRST_TOOL + current_tool || i == FIRST_COLOR + current_color || i == FIRST_MODE + current_mode); cursor = current_cursor; current_cursor = ARROW; set_cursor(); move_menu_cursor(); SHOW_SPRITES; waitpadup(); do { wait_vbl_done(); key = joypad(); if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) { if(key & J_UP) menu_cursor_pos = icons[menu_cursor_pos].up; if(key & J_DOWN) menu_cursor_pos = icons[menu_cursor_pos].down; if(key & J_LEFT) menu_cursor_pos = icons[menu_cursor_pos].left; if(key & J_RIGHT) menu_cursor_pos = icons[menu_cursor_pos].right; move_menu_cursor(); while(slowdown && key == joypad()) { wait_vbl_done(); slowdown--; } slowdown = 10; } else slowdown = 50; if(key & J_A) { if( /* menu_cursor_pos >= FIRST_TOOL && */ menu_cursor_pos <= LAST_TOOL) { if(menu_cursor_pos != /* FIRST_TOOL + */ current_tool) { change_icon(/* FIRST_TOOL + */ current_tool, UNSELECTED); current_tool = menu_cursor_pos /* - FIRST_TOOL */; change_icon(/* FIRST_TOOL + */ current_tool, SELECTED); cursor = icons[/* FIRST_TOOL + */ current_tool].cursor; } } else if(menu_cursor_pos >= FIRST_COLOR && menu_cursor_pos <= LAST_COLOR) { if(menu_cursor_pos != FIRST_COLOR + current_color) { change_icon(FIRST_COLOR + current_color, UNSELECTED); current_color = menu_cursor_pos - FIRST_COLOR; change_icon(FIRST_COLOR + current_color, SELECTED); } } else if(menu_cursor_pos >= FIRST_MODE && menu_cursor_pos <= LAST_MODE) { if(menu_cursor_pos != FIRST_MODE + current_mode) { change_icon(FIRST_MODE + current_mode, UNSELECTED); current_mode = menu_cursor_pos - FIRST_MODE; change_icon(FIRST_MODE + current_mode, SELECTED); } } } } while(key != J_SELECT); waitpadup(); for(i = 0; i < NB_TOOLS; i++) reset_icon(i); HIDE_SPRITES; current_cursor = cursor; } void run() { UBYTE key; UBYTE slowdown; UBYTE drawn, erased; slowdown = 10; drawn = erased = 0; set_cursor(); move_cursor(); SHOW_SPRITES; while(1) { wait_vbl_done(); key = joypad(); if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) { if(key & J_UP && cursor_y > 0) cursor_y--; if(key & J_DOWN && cursor_y < 143) cursor_y++; if(key & J_LEFT && cursor_x > 0) cursor_x--; if(key & J_RIGHT && cursor_x < 159) cursor_x++; move_cursor(); while(slowdown && key == joypad()) { wait_vbl_done(); slowdown--; } slowdown = 1; drawn = erased = 0; } else slowdown = 10; if(key & J_SELECT) { HIDE_SPRITES; menu(); set_cursor(); move_cursor(); SHOW_SPRITES; } if((key & (J_A|J_B)) == J_A) { if(!drawn) { drawn++; plot(cursor_x, cursor_y, colors[current_color], modes[current_mode]); } } else drawn = 0; if((key & (J_A|J_B)) == J_B) { if(!erased) { erased++; plot(cursor_x, cursor_y, WHITE, SOLID); } } else erased = 0; } } void main() { /* Initialize sprite palette */ OBP1_REG = 0xE0U; splash(); current_tool = 0; current_color = BLACK; current_mode = SOLID; current_cursor = PEN; menu_cursor_pos = 0; cursor_x = 160/2; cursor_y = 144/2; run(); } ================================================ FILE: examples/space/Make.bat ================================================ echo off set BIN=..\..\bin set OBJ=obj if "%1"=="clean" ( if exist %OBJ% rd /s/q %OBJ% if exist space.gb del space.gb goto end ) if not exist %OBJ% mkdir %OBJ% call %BIN%\gbdk-n-assemble.bat %OBJ%\space.rel space.s call %BIN%\gbdk-n-link.bat %OBJ%\space.rel -o %OBJ%\space.ihx call %BIN%\gbdk-n-make-rom.bat %OBJ%\space.ihx space.gb :end ================================================ FILE: examples/space/Makefile ================================================ BIN=../../bin OBJ=./obj build: mkdir -p $(OBJ) $(BIN)/gbdk-n-assemble.sh $(OBJ)/space.rel space.s $(BIN)/gbdk-n-link.sh $(OBJ)/space.rel -o $(OBJ)/space.ihx $(BIN)/gbdk-n-make-rom.sh $(OBJ)/space.ihx space.gb clean: rm -rf $(OBJ) rm -f space.gb ================================================ FILE: examples/space/space.s ================================================ ;; Little demo illustrating how to use the graphical possibilities ;; of the GB (background, window and animated sprite) ;; I have used fixed-point values for both the position and ;; speed of objects to get smooth movements ;; ;; OBJ data : 0x8000 -> 0x8FFF (unsigned) ;; Window data : 0x8800 -> 0x97FF (signed) ;; Background data : 0x8800 -> 0x97FF (signed) ;; ;; Tiled 0xFC -> 0xFF are standard tiles (all black -> all white) ;; ;; Keys: ;; Arrow keys : Change the speed (and direction) of the sprite ;; Arrow keys + A : Change the speed (and direction) of the window ;; Arrow keys + B : Change the speed (and direction) of the background ;; START : Open/close the door ;; SELECT : Basic fading effect ;; ;; Note that the window is kept in the lower right part of the screen ;; since it can't be made transparent .include "../../libc/global.s" .globl .init_vram .globl .copy_vram .globl .init_wtt .globl .init_btt .globl .set_xy_wtt .globl .mv_sprite .globl .set_sprite_prop .globl .set_sprite_tile .globl .jpad .NBDFRAMES = .endfilm-.film ; Nb frames for the door .NBSFRAMES = 0x07 ; Nb frames for the sprite .WINSZX = 0x80 ; Size of the picture in the window .WINSZY = 0x50 .MINWINX = .MAXWNDPOSX-.WINSZX+1 ; Bounds of the window origin .MINWINY = .MAXWNDPOSY-.WINSZY+1 .MAXWINX = .MAXWNDPOSX .MAXWINY = .MAXWNDPOSY .FADESTEP = 0x10 ; Nb steps for the fading effect .STARTFADE = 0x06*.FADESTEP ; Initial value for the fading effect .CLOSED = 0x00 .OPENING = 0x01 .OPENED = 0x02 .CLOSING = 0x03 .module Space .area _BSS .time: ; Global "time" value (counter) .ds 0x01 .doorstate: ; State of the door (OPENED, CLOSED...) .ds 0x01 .doorpos: ; Current position in the door animation .ds 0x01 .color: ; Current color for fading effect .ds 0x01 .sframe: ; Current frame of the sprite .ds 0x01 .bposx: ; Background position (fixed point) .ds 0x02 .bposy: .ds 0x02 .bspx: ; Background speed (fixed point) .ds 0x02 .bspy: .ds 0x02 .wposx: ; Window position (fixed point) .ds 0x02 .wposy: .ds 0x02 .wspx: ; Window speed (fixed point) .ds 0x02 .wspy: .ds 0x02 .sposx: ; Sprite position (fixed point) .ds 0x02 .sposy: .ds 0x02 .sspx: ; Sprite speed (fixed point) .ds 0x02 .sspy: .ds 0x02 .area _CODE _main:: DI ; Disable interrupts ;; Turn the screen off CALL .display_off XOR A LD (.time),A LD (.color),A LD A,#0b11100100 LDH (.BGP),A LDH (.OBP0),A ; Initialize tiles LD HL,#0x8000 LD DE,#0x1000 LD B,#0x00 CALL .init_vram ; Init the tile set at 0x8000 with 0x00 LD B,#0xFF CALL .init_btt ; Init the tiles tables with 0xFF CALL .init_wtt LD BC,#.tp0 ; Move tiles (standard tiles) LD HL,#0x9000-(.endtp0-.tp0) LD DE,#.endtp0-.tp0 CALL .copy_vram LD BC,#.tp1 ; Move tiles (earth) LD HL,#0x8000 LD DE,#.endtp1-.tp1 CALL .copy_vram LD BC,#.tp2 ; Move tiles (door) LD HL,#0x8800 LD DE,#.endtp2-.tp2 CALL .copy_vram LD BC,#.tp3 ; Move tiles (background) LD HL,#0x9000 LD DE,#.endtp3-.tp3 CALL .copy_vram ;; Draw the background LD BC,#.bkg_tiles LD HL,#0x9800 LD DE,#0x0400 ; One whole GB Screen CALL .copy_vram ;; Draw the frame in the window LD BC,#.frame_tiles LD DE,#0x0000/8 ; Place image at (0x00,0x00) LD HL,#0x8050/8 ; Image size is 0x80 x 0x50 CALL .set_xy_wtt ;; Draw the door in the window LD BC,#.door1_tiles LD DE,#0x1010/8 ; Place image at (0x10,0x10) LD HL,#0x6030/8 ; Image size is 0x60 x 0x30 CALL .set_xy_wtt LD A,#.CLOSED LD (.doorstate),A ; Initialize background XOR A LD (.bposx),A LDH (.SCX),A LD (.bposx+1),A LD (.bposy),A LDH (.SCY),A LD (.bposy+1),A LD A,#-0x01 LD (.bspx),A XOR A LD (.bspx+1),A XOR A LD (.bspy),A LD A,#0x80 LD (.bspy+1),A ; Initialize window LD A,#.MAXWNDPOSX LD (.wposx),A LDH (.WX),A XOR A LD (.wposx+1),A LD A,#.MAXWNDPOSY LD (.wposy),A LDH (.WY),A XOR A LD (.wposy+1),A LD A,#-0x01 LD (.wspx),A LD A,#0x80 LD (.wspx+1),A LD A,#-0x01 LD (.wspy),A LD A,#0xC0 LD (.wspy+1),A ; Initialize sprite XOR A LD (.sframe),A LD C,#0x00 ; Sprite 0x00 LD D,#0x00 ; Default sprite properties CALL .set_sprite_prop LD C,#0x01 ; Sprite 0x01 LD D,#0x00 ; Default sprite properties CALL .set_sprite_prop LD A,#0x10 LD (.sposx),A XOR A LD (.sposx+1),A LD A,#0x10 LD (.sposy),A XOR A LD (.sposy+1),A XOR A LD (.sspx),A LD A,#0x40 LD (.sspx+1),A XOR A LD (.sspy),A LD A,#0x40 LD (.sspy+1),A CALL .tile_sprite ; Set sprite tiles CALL .place_sprite ; Place sprites LD A,#0b11100111 ; LCD = On ; WindowBank = 0x9C00 ; Window = On ; BG Chr = 0x8800 ; BG Bank = 0x9800 ; OBJ = 8x16 ; OBJ = On ; BG = On LDH (.LCDC),A EI ; Enable interrupts 1$: LD A,(.time) INC A LD (.time),A LD B,#0x04 ; Skip four VBLs (slow down animation) 2$: CALL .wait_vbl_done DEC B JR NZ,2$ CALL .fade CALL .door CALL .scroll CALL .animate_sprite CALL .jpad LD D,A AND #.B ; Is B pressed ? JP NZ,10$ LD A,D AND #.A ; Is A pressed ? JP NZ,20$ LD A,D AND #.SELECT ; Is SELECT pressed ? JR Z,3$ LD A,#.STARTFADE LD (.color),A 3$: LD A,D AND #.START ; Is START pressed ? JR Z,5$ LD A,(.doorstate) CP #.CLOSED JR NZ,4$ LD A,#.OPENING LD (.doorstate),A XOR A LD (.doorpos),A JR 5$ 4$: CP #.OPENED JR NZ,5$ LD A,#.CLOSING LD (.doorstate),A LD A,#.NBDFRAMES LD (.doorpos),A 5$: LD A,D AND #.UP ; Is UP pressed ? JR Z,6$ LD BC,#0x0010 LD A,(.sspy) ; Load speed into HL LD H,A LD A,(.sspy+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.sspy+1),A LD A,H SBC B LD (.sspy),A ; Store new speed JR 7$ 6$: LD A,D AND #.DOWN ; Is DOWN pressed ? JR Z,7$ LD BC,#0x0010 LD A,(.sspy) ; Load speed into HL LD H,A LD A,(.sspy+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.sspy),A LD A,L LD (.sspy+1),A 7$: LD A,D AND #.LEFT ; Is LEFT pressed ? JR Z,8$ LD BC,#0x0010 LD A,(.sspx) ; Load speed into HL LD H,A LD A,(.sspx+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.sspx+1),A LD A,H SBC B LD (.sspx),A ; Store new speed JP 1$ 8$: LD A,D AND #.RIGHT ; Is RIGHT pressed ? JP Z,1$ LD BC,#0x0010 LD A,(.sspx) ; Load speed into HL LD H,A LD A,(.sspx+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.sspx),A LD A,L LD (.sspx+1),A JP 1$ 10$: LD A,D AND #.UP ; Is UP pressed ? JP Z,11$ LD BC,#0x0010 LD A,(.bspy) ; Load speed into HL LD H,A LD A,(.bspy+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.bspy+1),A LD A,H SBC B LD (.bspy),A ; Store new speed JR 12$ 11$: LD A,D AND #.DOWN ; Is DOWN pressed ? JP Z,12$ LD BC,#0x0010 LD A,(.bspy) ; Load speed into HL LD H,A LD A,(.bspy+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.bspy),A LD A,L LD (.bspy+1),A 12$: LD A,D AND #.LEFT ; Is LEFT pressed ? JP Z,13$ LD BC,#0x0010 LD A,(.bspx) ; Load speed into HL LD H,A LD A,(.bspx+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.bspx+1),A LD A,H SBC B LD (.bspx),A ; Store new speed JP 1$ 13$: LD A,D AND #.RIGHT ; Is RIGHT pressed ? JP Z,1$ LD BC,#0x0010 LD A,(.bspx) ; Load speed into HL LD H,A LD A,(.bspx+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.bspx),A LD A,L LD (.bspx+1),A JP 1$ 20$: LD A,D AND #.UP ; Is UP pressed ? JP Z,21$ LD BC,#0x0010 LD A,(.wspy) ; Load speed into HL LD H,A LD A,(.wspy+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.wspy+1),A LD A,H SBC B LD (.wspy),A ; Store new speed JR 22$ 21$: LD A,D AND #.DOWN ; Is DOWN pressed ? JP Z,22$ LD BC,#0x0010 LD A,(.wspy) ; Load speed into HL LD H,A LD A,(.wspy+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.wspy),A LD A,L LD (.wspy+1),A 22$: LD A,D AND #.LEFT ; Is LEFT pressed ? JP Z,23$ LD BC,#0x0010 LD A,(.wspx) ; Load speed into HL LD H,A LD A,(.wspx+1) LD L,A LD A,L ; Substract BC from HL SUB C LD (.wspx+1),A LD A,H SBC B LD (.wspx),A ; Store new speed JP 1$ 23$: LD A,D AND #.RIGHT ; Is RIGHT pressed ? JP Z,1$ LD BC,#0x0010 LD A,(.wspx) ; Load speed into HL LD H,A LD A,(.wspx+1) LD L,A ADD HL,BC ; Add them LD A,H ; Store new speed LD (.wspx),A LD A,L LD (.wspx+1),A JP 1$ RET ;; Fade the screen (off and on) .fade: LD A,(.color) ; Load color into A CP #0x00 RET Z CP #.STARTFADE JR NZ,1$ LD A,#0b11111001 JR 6$ 1$: CP #.STARTFADE-.FADESTEP JR NZ,2$ LD A,#0b11111110 JR 6$ 2$: CP #.STARTFADE-0x02*.FADESTEP JR NZ,3$ LD A,#0b11111111 JR 6$ 3$: CP #.STARTFADE-0x03*.FADESTEP JR NZ,4$ LD A,#0b11111110 JR 6$ 4$: CP #.STARTFADE-0x04*.FADESTEP JR NZ,5$ LD A,#0b11111001 JR 6$ 5$: CP #.STARTFADE-0x05*.FADESTEP JR NZ,7$ LD A,#0b11100100 6$: LDH (.BGP),A 7$: LD A,(.color) DEC A LD (.color),A RET ;; Scroll the background, the window and the sprite .scroll: ;; Update background LD A,(.bposx) ; Load background position into HL LD H,A LD A,(.bposx+1) LD L,A LD A,(.bspx) ; Load background speed into BC LD B,A LD A,(.bspx+1) LD C,A ADD HL,BC ; Add them LD A,L ; Store new background position LD (.bposx+1),A LD A,H LD (.bposx),A LDH (.SCX),A ; Update position LD A,(.bposy) ; Load background position into HL LD H,A LD A,(.bposy+1) LD L,A LD A,(.bspy) ; Load background speed into BC LD B,A LD A,(.bspy+1) LD C,A ADD HL,BC ; Add them LD A,L ; Store new background position LD (.bposy+1),A LD A,H LD (.bposy),A LDH (.SCY),A ; Update position ;; Update window LD A,(.wspx) ; Load window speed into BC LD B,A LD A,(.wspx+1) LD C,A LD A,(.wposx) ; Load window position into HL LD H,A LD A,(.wposx+1) LD L,A ADD HL,BC ; Add them LD A,L ; Store new window position LD (.wposx+1),A LD A,H LD (.wposx),A ;; X position LD A,(.wposx) ; Check window position LD H,#0x00 ; We must use 16 bit registers since the LD L,A ; window is not less than 0x80 pixels LD BC,#.MAXWINX LD A,L ; Substract BC from HL SUB C LD A,H SBC B AND #0x80 JR NZ,1$ ; Maximum value ? LD A,#.MAXWINX LD (.wposx),A ; Correct window position LD A,(.wspx+1) ; Load window speed into BC LD C,A LD A,(.wspx) LD B,A AND #0x80 ; Speed is already negative ? JR NZ,3$ JR 2$ 1$: LD A,(.wposx) ; Check window position LD H,#0x00 ; We must use 16 bit registers since the LD L,A ; window is not less than 0x80 pixels LD BC,#.MINWINX+1 LD A,L ; Substract BC from HL SUB C LD A,H SBC B AND #0x80 JR Z,3$ ; Minimum value ? LD A,#.MINWINX LD (.wposx),A ; Correct window position LD A,(.wspx+1) ; Load window speed into BC LD C,A LD A,(.wspx) LD B,A AND #0x80 ; Speed is already positive ? JR Z,3$ 2$: LD HL,#0x00 ; Invert speed LD A,L ; Substract BC from HL SUB C LD (.wspx+1),A LD A,H SBC B LD (.wspx),A ; Store new speed 3$: LD A,(.wposx) LDH (.WX),A ; Update position LD A,(.wspy) ; Load window speed into BC LD B,A LD A,(.wspy+1) LD C,A LD A,(.wposy) ; Load window position into HL LD H,A LD A,(.wposy+1) LD L,A ADD HL,BC ; Add them LD A,L ; Store new window position LD (.wposy+1),A LD A,H LD (.wposy),A ;; Y position LD A,(.wposy) ; Check window position LD H,#0x00 ; We must use 16 bit registers since the LD L,A ; window is not less than 0x80 pixels LD BC,#.MAXWINY LD A,L ; Substract BC from HL SUB C LD A,H SBC B AND #0x80 JR NZ,4$ ; Maximum value ? LD A,#.MAXWINY LD (.wposy),A ; Correct window position LD A,(.wspy+1) ; Load window speed into BC LD C,A LD A,(.wspy) LD B,A AND #0x80 ; Speed is already negative ? JR NZ,6$ JR 5$ 4$: LD A,(.wposy) ; Check window position LD H,#0x00 ; We must use 16 bit registers since the LD L,A ; window is not less than 0x80 pixels LD BC,#.MINWINY+1 LD A,L ; Substract BC from HL SUB C LD A,H SBC B AND #0x80 JR Z,6$ ; Minimum value ? LD A,#.MINWINY LD (.wposy),A ; Correct window position LD A,(.wspy+1) ; Load window speed into BC LD C,A LD A,(.wspy) LD B,A AND #0x80 ; Speed is already positive ? JR Z,6$ 5$: LD HL,#0x00 ; Invert speed LD A,L ; Substract BC from HL SUB C LD (.wspy+1),A LD A,H SBC B LD (.wspy),A ; Store new speed 6$: LD A,(.wposy) LDH (.WY),A ; Update position ;; Update sprite LD A,(.sposx) ; Load sprite position into HL LD H,A LD A,(.sposx+1) LD L,A LD A,(.sspx) ; Load sprite speed into BC LD B,A LD A,(.sspx+1) LD C,A ADD HL,BC ; Add them LD A,L ; Store new sprite position LD (.sposx+1),A LD A,H LD (.sposx),A LD A,(.sposy) ; Load sprite position into HL LD H,A LD A,(.sposy+1) LD L,A LD A,(.sspy) ; Load sprite speed into BC LD B,A LD A,(.sspy+1) LD C,A ADD HL,BC ; Add them LD A,L ; Store new sprite position LD (.sposy+1),A LD A,H LD (.sposy),A CALL .place_sprite ; Update position RET ;; Open and close the door .door: LD A,(.doorstate) CP #.OPENING JP Z,.open_door CP #.CLOSING JP Z,.close_door RET .open_door: LD A,(.doorpos) LD HL,#.film+0x02 LD B,#0x00 LD C,A ADD HL,BC LD C,(HL) INC HL LD B,(HL) LD DE,#0x1010/8 ; Place image at (0x10,0x10) LD HL,#0x6030/8 ; Image size is 0x60 x 0x30 CALL .set_xy_wtt LD A,(.doorpos) ADD A,#0x02 LD (.doorpos),A CP #.NBDFRAMES RET NZ LD A,#.OPENED LD (.doorstate),A RET .close_door: LD A,(.doorpos) LD HL,#.film-0x02 LD B,#0x00 LD C,A ADD HL,BC LD C,(HL) INC HL LD B,(HL) LD DE,#0x1010/8 ; Place image at (0x10,0x10) LD HL,#0x6030/8 ; Image size is 0x60 x 0x30 CALL .set_xy_wtt LD A,(.doorpos) SUB A,#0x02 LD (.doorpos),A RET NZ LD A,#.CLOSED LD (.doorstate),A RET ;; Animate sprite .animate_sprite: LD A,(.time) AND #0x07 RET NZ LD A,(.sframe) INC A CP #.NBSFRAMES JR NZ,1$ XOR A 1$: LD (.sframe),A CALL .tile_sprite RET ;; Set sprite tiles .tile_sprite: LD A,(.sframe) LD HL,#.earth_tiles RLCA LD B,#0x00 LD C,A ADD HL,BC LD C,#0x00 ; Sprite 0x00 LD A,(HL+) LD D,A PUSH HL CALL .set_sprite_tile POP HL LD C,#0x01 ; Sprite 0x01 LD A,(HL+) LD D,A CALL .set_sprite_tile RET ;; Place sprite .place_sprite: LD C,#0x00 ; Sprite 0x00 LD A,(.sposx) LD D,A LD A,(.sposy) LD E,A PUSH DE ; Store position CALL .mv_sprite LD C,#0x01 ; Sprite 0x01 POP DE ; Restore position LD A,#0x08 ADD A,D LD D,A CALL .mv_sprite RET .area _LIT .tp0: .std_data: ; Basic tiles (0xFC to 0xFF) .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00 .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .endtp0: .tp1: .earth_data: ; Tile 0x00 .byte 0x07,0x07,0x18,0x1F,0x32,0x2D,0x71,0x4E,0x70,0x4F,0xF8,0x87,0xF8,0x87,0xF8,0x87 .byte 0xFC,0x83,0xFE,0x81,0x7F,0x40,0x7F,0x40,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0xF0,0x30,0x78,0x88,0x3C,0xC4,0x5C,0xA4,0x9E,0x62,0x3E,0xC2,0x3E,0xC2 .byte 0x5E,0xA2,0x7E,0x82,0x0C,0xF4,0x0C,0xF4,0x98,0x68,0xB0,0x70,0xC0,0xC0,0x00,0x00 .byte 0x07,0x07,0x1F,0x18,0x2F,0x30,0x4F,0x70,0x6F,0x50,0x9F,0xE0,0x9F,0xE0,0xBF,0xC0 .byte 0xFF,0x80,0xB7,0xC8,0x63,0x5C,0x43,0x7C,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0xB0,0x70,0x18,0xE8,0x0C,0xF4,0x0C,0xF4,0x82,0x7E,0x82,0x7E,0x86,0x7A .byte 0xC6,0x3A,0xE6,0x1A,0xF4,0x0C,0xFC,0x04,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 ; Tile 0x08 .byte 0x07,0x07,0x1E,0x19,0x20,0x3F,0x40,0x7F,0x42,0x7D,0x81,0xFE,0x81,0xFE,0x83,0xFC .byte 0xD7,0xA8,0xBB,0xC4,0x6E,0x51,0x7C,0x43,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0x70,0xB0,0xE8,0x18,0xF4,0x0C,0xF4,0x0C,0xFE,0x02,0xFE,0x02,0xFE,0x02 .byte 0xFE,0x02,0x7E,0x82,0x3C,0xC4,0x3C,0xC4,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 .byte 0x07,0x07,0x1B,0x1C,0x20,0x3F,0x40,0x7F,0x40,0x7F,0xE0,0x9F,0x90,0xEF,0x89,0xF6 .byte 0x8D,0xF2,0x9F,0xE0,0x5E,0x61,0x6F,0x50,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0xB0,0x70,0x28,0xD8,0x04,0xFC,0x2C,0xD4,0x1E,0xE2,0x1E,0xE2,0x3E,0xC2 .byte 0x7E,0x82,0xB6,0x4A,0xE4,0x1C,0xC4,0x3C,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 ; Tile 0x10 .byte 0x07,0x07,0x18,0x1F,0x20,0x3F,0x40,0x7F,0x40,0x7F,0xEE,0x91,0xF1,0x8E,0xE0,0x9F .byte 0xE0,0x9F,0xF1,0x8E,0x71,0x4E,0x72,0x4D,0x3F,0x20,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0xF0,0x30,0x08,0xF8,0x04,0xFC,0x04,0xFC,0x02,0xFE,0x02,0xFE,0x92,0x6E .byte 0xD6,0x2A,0xFE,0x02,0xEC,0x14,0xFC,0x04,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 .byte 0x07,0x07,0x1D,0x1A,0x36,0x29,0x5C,0x63,0x6C,0x53,0xCE,0xB1,0x9F,0xE0,0x9E,0xE1 .byte 0xAE,0xD1,0xBF,0xC0,0x47,0x78,0x47,0x78,0x2F,0x30,0x1F,0x18,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0x70,0xB0,0x08,0xF8,0x04,0xFC,0x04,0xFC,0xE2,0x1E,0x32,0xCE,0x0E,0xF2 .byte 0x0E,0xF2,0x1E,0xE2,0x1C,0xE4,0x2C,0xD4,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 ; Tile 0x18 .byte 0x07,0x07,0x1E,0x19,0x33,0x2C,0x49,0x76,0x42,0x7D,0xC4,0xBB,0xC1,0xBE,0xC1,0xBE .byte 0xE2,0x9D,0xF3,0x8C,0x78,0x47,0x78,0x47,0x3C,0x23,0x1C,0x1B,0x07,0x07,0x00,0x00 .byte 0xC0,0xC0,0x70,0xB0,0x68,0x98,0xC4,0x3C,0xC4,0x3C,0xEE,0x12,0xF2,0x0E,0xE2,0x1E .byte 0xE2,0x1E,0xF2,0x0E,0x7C,0x84,0x7C,0x84,0xF8,0x08,0xF0,0x30,0xC0,0xC0,0x00,0x00 .endtp1: .tp2: .frame_data: ; Tile 0x00 .byte 0xFF,0x00,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F .byte 0xFF,0x00,0x01,0xFE,0x03,0xFC,0x07,0xF8,0x0F,0xF0,0x1F,0xE0,0x3F,0xC0,0x7F,0x80 .byte 0xFF,0x00,0xFE,0x01,0xFC,0x03,0xF8,0x07,0xF0,0x0F,0xE0,0x1F,0xC0,0x3F,0x80,0x7F .byte 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF .byte 0xFF,0x00,0xFF,0x01,0xFD,0x03,0xF9,0x07,0xF1,0x0F,0xE1,0x1F,0xC1,0x3F,0x81,0x7F .byte 0x80,0x7F,0x81,0x7E,0x83,0x7C,0x87,0x78,0x8F,0x70,0x9F,0x60,0xBF,0x40,0xFF,0x00 .byte 0xFF,0x70,0xFF,0x98,0xEF,0xB8,0xCF,0xF8,0xFF,0x70,0xFF,0x00,0xFF,0x00,0xFF,0x01 .byte 0xFF,0x00,0xFE,0x01,0xFC,0x03,0xF8,0x07,0xF0,0x0F,0xE0,0x1F,0xC0,0x3F,0xFF,0xFF ; Tile 0x08 .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF .byte 0x00,0xFF,0x01,0xFE,0x03,0xFC,0x07,0xF8,0x0F,0xF0,0x1F,0xE0,0x3F,0xC0,0xFF,0xFF .byte 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF .byte 0xFF,0x0E,0xFF,0x13,0xFD,0x17,0xF9,0x1F,0xFE,0x0F,0xE0,0x1F,0xC0,0x3F,0x80,0xFF .byte 0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF .byte 0xFF,0x01,0xFF,0x01,0xFD,0x03,0xF9,0x07,0xF1,0x0F,0xE1,0x1F,0xC1,0x3F,0x81,0x7F .byte 0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F,0x80,0x7F .byte 0x01,0xFF,0x01,0xFF,0x03,0xFD,0x07,0xF9,0x0F,0xF1,0x1F,0xE1,0x3F,0xC1,0x7F,0x81 ; Tile 0x10 .byte 0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01 .byte 0x01,0xFF,0x01,0xFE,0x03,0xFC,0x77,0xF8,0xFF,0x98,0xEF,0xB8,0xCF,0xF8,0x7F,0xF0 .byte 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x0E,0xFF,0x13,0xFD,0x17,0xF9,0x1F,0xFF,0x0E .byte 0x80,0x7F,0x81,0x7E,0x83,0x7C,0x87,0x78,0x8F,0x70,0x9F,0x60,0xBF,0x40,0xFF,0x7F .byte 0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0xFF,0xFF .door1_data: ; Tile 0x15 .byte 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF .byte 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF .door2_data: ; Tile 0x18 .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF .byte 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF .byte 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF .byte 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .door3_data: ; Tile 0x1C .byte 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF .byte 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF .byte 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .door4_data: ; Tile 0x20 .byte 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .endtp2: .tp3: .bkg_data: ; Tile 0x00 .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xF7,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xDF,0xFF,0xEF,0xFF,0xFF,0xF7,0xFF,0xFB,0xFF,0xFD,0xFF,0xFE,0xFE,0xFF ; Tile 0x08 .byte 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7D,0xFE,0x7C,0x39 .byte 0xFF,0xFF,0xF7,0xFF,0xEF,0xFF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFD .byte 0xBB,0x01,0xC7,0x83,0xC7,0x83,0xC7,0x83,0xBB,0x01,0x7C,0x39,0x7D,0xFE,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F .byte 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,0xAF,0x77,0x27,0x8F,0xDF,0x8F,0x27,0x8F ; Tile 0x10 .byte 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFB,0xFF,0xF7,0xEF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xBF,0xFF,0xDF,0xEF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFE,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xAF,0x77,0xFF,0xFB,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF ; Tile 0x18 .byte 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x7D,0xFE,0x7C,0x39 .byte 0xFF,0xFF,0xF7,0xFF,0xEF,0xFF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0x7F,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFD ; Tile 0x20 .byte 0xFF,0xFF,0xDF,0xFF,0xEF,0xFF,0xFF,0xF7,0xFF,0xFB,0xFE,0xFD,0xFD,0xFE,0xFE,0xFF .byte 0xAB,0x11,0xC7,0x83,0x83,0xC7,0xC7,0x83,0xAB,0x11,0x7C,0x39,0x7D,0xFE,0xFE,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0x7F .byte 0xFB,0xFF,0xFF,0xFD,0xFE,0xFE,0xFE,0xFF,0xFE,0xFE,0xFF,0xFD,0xFB,0xFF,0xFF,0xFF .byte 0xEF,0xFF,0xFF,0xDF,0x3F,0xBF,0x3F,0x7F,0x3F,0xBF,0xFF,0xDF,0xEF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFD,0xFE,0xFE,0xFD .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF ; Tile 0x28 .byte 0xF7,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .byte 0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF .endtp3: ; Image size: 0x40 x 0x40 ; Number of tiles (total - unique): 0x40 - 0x2D .bkg_tiles: .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0x00,0x01,0x02,0x03,0xFC,0xFC,0x04,0xFC .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0x05,0x06,0xFC,0x07,0x08,0x09,0x0A .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0xFC,0xFC,0xFC,0x02,0x0B,0x0C,0x0D,0xFC .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x0E,0x0F,0x10,0xFC,0x11,0x12,0x13,0x14 .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x15,0x16,0x17,0xFC,0x18,0x19,0x1A,0xFC .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x1B,0x1C,0x1D,0xFC,0xFC,0x1E,0x1F,0x20 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x21,0x22,0xFC,0x23,0x24,0x25,0xFC,0x26 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 .byte 0x27,0x13,0x28,0x29,0x2A,0x2B,0x2C,0x11 ; Image size: 0x10 x 0x70 ; Number of tiles (total - unique): 0x1C - 0x1C .earth_tiles: .byte 0x00,0x02 .byte 0x04,0x06 .byte 0x08,0x0A .byte 0x0C,0x0E .byte 0x10,0x12 .byte 0x14,0x16 .byte 0x18,0x1A ; Image size: 0x80 x 0x50 ; Number of tiles (total - unique): 0xA0 - 0x15 .frame_tiles: .byte 0x80,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x84 .byte 0x85,0x86,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x8B,0x8C .byte 0xFD,0x8D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E,0x8F .byte 0x82,0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85,0x90 .byte 0x8E,0x8F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x8D .byte 0x85,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x82,0x8C .byte 0xFD,0x8D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E,0x8F .byte 0x82,0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85,0x90 .byte 0x8E,0x91,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0xFD,0x82,0x83,0x81,0x92,0x8D .byte 0x93,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x88,0x89,0x8A,0x87,0x94 ; Image size: 0x60 x 0x30 ; Number of tiles (total - unique): 0x48 - 0x03 .door1_tiles: .byte 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95 .byte 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96 .byte 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97 .byte 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95 .byte 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96 .byte 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97 .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; Image size: 0x60 x 0x30 ; Number of tiles (total - unique): 0x48 - 0x04 .door2_tiles: .byte 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98 .byte 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99 .byte 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A .byte 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98 .byte 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99 .byte 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; Image size: 0x60 x 0x30 ; Number of tiles (total - unique): 0x48 - 0x04 .door3_tiles: .byte 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C .byte 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D .byte 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E .byte 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C .byte 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D .byte 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; Image size: 0x60 x 0x30 ; Number of tiles (total - unique): 0x48 - 0x01 .door4_tiles: .byte 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95 .byte 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96 .byte 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97 .byte 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95 .byte 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96 .byte 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0 .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .byte 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC .film: .word .door1_tiles+0x0C*0 .word .door2_tiles+0x0C*0 .word .door3_tiles+0x0C*0 .word .door4_tiles+0x0C*0 .word .door1_tiles+0x0C*1 .word .door2_tiles+0x0C*1 .word .door3_tiles+0x0C*1 .word .door4_tiles+0x0C*1 .word .door1_tiles+0x0C*2 .word .door2_tiles+0x0C*2 .word .door3_tiles+0x0C*2 .word .door4_tiles+0x0C*2 .word .door1_tiles+0x0C*3 .word .door2_tiles+0x0C*3 .word .door3_tiles+0x0C*3 .word .door4_tiles+0x0C*3 .word .door1_tiles+0x0C*4 .word .door2_tiles+0x0C*4 .word .door3_tiles+0x0C*4 .word .door4_tiles+0x0C*4 .word .door1_tiles+0x0C*5 .word .door2_tiles+0x0C*5 .word .door3_tiles+0x0C*5 .word .door4_tiles+0x0C*5 .endfilm: .word .door1_tiles+0x0C*6 ================================================ FILE: examples/thumby/Make.bat ================================================ echo off set BIN=..\..\bin set OBJ=obj if "%1"=="clean" ( if exist %OBJ% rd /s/q %OBJ% if exist thumby.gb del thumby.gb goto end ) if not exist %OBJ% mkdir %OBJ% call %BIN%\gbdk-n-compile.bat thumby.c -o %OBJ%\thumby.rel call %BIN%\gbdk-n-link.bat %OBJ%\thumby.rel -o %OBJ%\thumby.ihx call %BIN%\gbdk-n-make-rom.bat %OBJ%\thumby.ihx thumby.gb :end ================================================ FILE: examples/thumby/Makefile ================================================ BIN=../../bin OBJ=./obj build: mkdir -p $(OBJ) $(BIN)/gbdk-n-compile.sh thumby.c -o $(OBJ)/thumby.rel $(BIN)/gbdk-n-link.sh $(OBJ)/thumby.rel -o $(OBJ)/thumby.ihx $(BIN)/gbdk-n-make-rom.sh $(OBJ)/thumby.ihx thumby.gb clean: rm -rf $(OBJ) rm -f thumby.gb ================================================ FILE: examples/thumby/thumby.c ================================================ #include /* * Game Boy Development Kit Demonstration program * Creates a rectangle on screen * which can be moved around with the game pad * */ unsigned char backgroundcharacters[] = { 0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xF0, 0x80,0xFF,0x7F,0xE0,0x9F,0xE0,0xFF,0xF0, 0xFF,0xF9,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x87,0xFF,0xCF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0x1F,0xFF,0xEF,0x7F,0x9F,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF }; unsigned char spritetiles[] = { 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0 }; unsigned char bgmap[] = { 0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2, 1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3 }; void main() { UBYTE counter,x,y; x=40; y=17; disable_interrupts(); DISPLAY_OFF; // load background set_bkg_data(0,4,backgroundcharacters); for(counter=0;counter<=16;counter+=2) set_bkg_tiles( 0, counter, 20, 2, bgmap); // load sprite SPRITES_8x8; set_sprite_data(0, 1, spritetiles); set_sprite_tile(0,0); move_sprite(0,x,y); SHOW_BKG; SHOW_SPRITES; DISPLAY_ON; enable_interrupts(); while(1) { /* Skip four VBLs (slow down animation) */ for(counter = 0; counter < 4; counter++){ wait_vbl_done(); } counter = joypad(); if(counter & J_UP) y--; if(counter & J_DOWN) y++; if(counter & J_LEFT) x--; if(counter & J_RIGHT) x++; move_sprite(0,x,y); } } ================================================ FILE: include/asm/gbz80/provides.h ================================================ #define USE_C_MEMCPY 1 #define USE_C_STRCPY 1 #define USE_C_STRCMP 1 ================================================ FILE: include/asm/gbz80/stdarg.h ================================================ #ifndef ASM_GBZ80_STDARG_INCLUDE #define ASM_GBZ80_STDARG_INCLUDE /* sdcc pushes right to left with the real sizes, not cast up to an int. so printf(int, char, long) results in push long, push char, push int On the z80 the stack grows down, so the things seem to be in the correct order. */ typedef unsigned char * va_list; #define va_start(list, last) list = (unsigned char *)&last + sizeof(last) #define va_arg(list, type) *((type *)((list += sizeof(type)) - sizeof(type))) #define va_end(list) #endif ================================================ FILE: include/asm/gbz80/types.h ================================================ /** @file asm/gbz80/types.h Types definitions for the gb. */ #ifndef ASM_GBZ80_TYPES_INCLUDE #define ASM_GBZ80_TYPES_INCLUDE #if SDCC_PORT!=gbz80 #error gbz80 only. #endif #define NONBANKED __nonbanked #define BANKED __banked /** Signed eight bit. */ typedef signed char INT8; /** Unsigned eight bit. */ typedef unsigned char UINT8; /** Signed sixteen bit. */ typedef int INT16; /** Unsigned sixteen bit. */ typedef unsigned int UINT16; /** Signed 32 bit. */ typedef long INT32; /** Unsigned 32 bit. */ typedef unsigned long UINT32; #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED typedef unsigned int size_t; #endif /** Returned from clock @see clock */ typedef UINT16 clock_t; #endif ================================================ FILE: include/asm/types.h ================================================ /** @file asm/types.h Shared types definitions. */ #ifndef ASM_TYPES_INCLUDE #define ASM_TYPES_INCLUDE #if SDCC_PORT == gbz80 #include #elif SDCC_PORT == z80 #include #else #error Unrecognised port #endif #ifndef NONBANKED #define NONBANKED #endif #ifndef BANKED #define BANKED #endif /** TRUE or FALSE. */ typedef INT8 BOOLEAN; #if BYTE_IS_UNSIGNED typedef UINT8 BYTE; typedef UINT16 WORD; typedef UINT32 DWORD; #else /** Signed 8 bit. */ typedef INT8 BYTE; /** Unsigned 8 bit. */ typedef UINT8 UBYTE; /** Signed 16 bit */ typedef INT16 WORD; /** Unsigned 16 bit */ typedef UINT16 UWORD; /** Signed 32 bit */ typedef INT32 LWORD; /** Unsigned 32 bit */ typedef UINT32 ULWORD; /** Signed 32 bit */ typedef INT32 DWORD; /** Unsigned 32 bit */ typedef UINT32 UDWORD; /** Useful definition for fixed point values */ typedef union _fixed { struct { UBYTE l; UBYTE h; } b; UWORD w; } fixed; #endif #endif ================================================ FILE: include/asm/z80/provides.h ================================================ #undef USE_C_MEMCPY #undef USE_C_STRCPY #undef USE_C_STRCMP ================================================ FILE: include/asm/z80/stdarg.h ================================================ #ifndef ASM_Z80_STDARG_INCLUDE #define ASM_Z80_STDARG_INCLUDE /* sdcc pushes right to left with the real sizes, not cast up to an int. so printf(int, char, long) results in push long, push char, push int On the z80 the stack grows down, so the things seem to be in the correct order. */ typedef char * va_list; #define va_start(list, last) list = (char *)&last + sizeof(last) #ifdef STDIO_INCLUDE #define va_arg(list, type) *(type *)list; list + sizeof(type) #else #define va_arg(list, type) (list + sizeof(type), *(type *)(list - sizeof(type))) #endif #endif ================================================ FILE: include/asm/z80/types.h ================================================ #ifndef ASM_Z80_TYPES_INCLUDE #define ASM_Z80_TYPES_INCLUDE #if SDCC_PORT!=z80 #error z80 only. #endif typedef char INT8; typedef unsigned char UINT8; typedef int INT16; typedef unsigned int UINT16; typedef long INT32; typedef unsigned long UINT32; typedef int size_t; typedef UINT16 clock_t; #endif ================================================ FILE: include/gb/cgb.h ================================================ /** @file gb/cgb.h Support for Color GameBoy. */ #ifndef _CGB_H #define _CGB_H /** Macro to create a palette entry out of the color components. */ #define RGB(r, g, b) \ ((((UINT16)(b) & 0x1f) << 10) | (((UINT16)(g) & 0x1f) << 5) | (((UINT16)(r) & 0x1f) << 0)) /** Common colors based on the EGA default palette. */ #define RGB_RED RGB(31, 0, 0) #define RGB_DARKRED RGB(15, 0, 0) #define RGB_GREEN RGB( 0, 31, 0) #define RGB_DARKGREEN RGB( 0, 15, 0) #define RGB_BLUE RGB( 0, 0, 31) #define RGB_DARKBLUE RGB( 0, 0, 15) #define RGB_YELLOW RGB(31, 31, 0) #define RGB_DARKYELLOW RGB(21, 21, 0) #define RGB_CYAN RGB( 0, 31, 31) #define RGB_AQUA RGB(28, 5, 22) #define RGB_PINK RGB(11, 0, 31) #define RGB_PURPLE RGB(21, 0, 21) #define RGB_BLACK RGB( 0, 0, 0) #define RGB_DARKGRAY RGB(10, 10, 10) #define RGB_LIGHTGRAY RGB(21, 21, 21) #define RGB_WHITE RGB(31, 31, 31) #define RGB_LIGHTFLESH RGB(30, 20, 15) #define RGB_BROWN RGB(10, 10, 0) #define RGB_ORANGE RGB(30, 20, 0) #define RGB_TEAL RGB(15, 15, 0) /** Set bkg palette(s). */ void set_bkg_palette(UINT8 first_palette, UINT8 nb_palettes, UINT16 *rgb_data) NONBANKED; /** Set sprite palette(s). */ void set_sprite_palette(UINT8 first_palette, UINT8 nb_palettes, UINT16 *rgb_data) NONBANKED; /** Set a bkg palette entry. */ void set_bkg_palette_entry(UINT8 palette, UINT8 entry, UINT16 rgb_data); /** Set a sprite palette entry. */ void set_sprite_palette_entry(UINT8 palette, UINT8 entry, UINT16 rgb_data); /** Set CPU speed to slow operation. Make sure interrupts are disabled before call. @see cpu_fast */ void cpu_slow(void); /** Set CPU speed to fast operation. Make sure interrupts are disabled before call. @see cpu_slow */ void cpu_fast(void); /** Set defaults compatible with normal GameBoy. */ void cgb_compatibility(void); #endif /* _CGB_H */ ================================================ FILE: include/gb/console.h ================================================ /** @file gb/console.h Console functions that work like Turbo C's. Note that the font is 8x8, making the screen 20x18 characters. */ #ifndef _CONSOLE_H #define _CONSOLE_H #include /** Move the cursor to an absolute position. */ void gotoxy(UINT8 x, UINT8 y); /** Get the current X position of the cursor. */ UINT8 posx(void); /** Get the current Y position of the cursor. */ UINT8 posy(void); /** Writes out a single character at the current cursor position. Does not update the cursor or interpret the character. */ void setchar(char c); #endif /* _CONSOLE_H */ ================================================ FILE: include/gb/drawing.h ================================================ /** @file gb/drawing.h All Points Addressable (APA) mode drawing library. Drawing routines originally by Pascal Felber Legendary overhall by Jon Fuge Commenting by Michael Hope Note that the standard text printf() and putchar() cannot be used in APA mode - use gprintf() and wrtchr() instead. */ #ifndef __DRAWING_H #define __DRAWING_H /** Size of the screen in pixels */ #define GRAPHICS_WIDTH 160 #define GRAPHICS_HEIGHT 144 /** Possible drawing modes */ #if ORIGINAL #define SOLID 0x10 /* Overwrites the existing pixels */ #define OR 0x20 /* Performs a logical OR */ #define XOR 0x40 /* Performs a logical XOR */ #define AND 0x80 /* Performs a logical AND */ #else #define SOLID 0x00 /* Overwrites the existing pixels */ #define OR 0x01 /* Performs a logical OR */ #define XOR 0x02 /* Performs a logical XOR */ #define AND 0x03 /* Performs a logical AND */ #endif /** Possible drawing colours */ #define WHITE 0 #define LTGREY 1 #define DKGREY 2 #define BLACK 3 /** Possible fill styles for box() and circle() */ #define M_NOFILL 0 #define M_FILL 1 /** Possible values for signed_value in gprintln() and gprintn() */ #define SIGNED 1 #define UNSIGNED 0 #include /** Print the string 'str' with no interpretation */ void gprint(char *str) NONBANKED; /** Print the long number 'number' in radix 'radix'. signed_value should be set to SIGNED or UNSIGNED depending on whether the number is signed or not */ void gprintln(INT16 number, INT8 radix, INT8 signed_value); /** Print the number 'number' as in 'gprintln' */ void gprintn(INT8 number, INT8 radix, INT8 signed_value); /** Print the formatted string 'fmt' with arguments '...' */ INT8 gprintf(char *fmt,...) NONBANKED; /** Old style plot - try plot_point() */ void plot(UINT8 x, UINT8 y, UINT8 colour, UINT8 mode); /** Plot a point in the current drawing mode and colour at (x,y) */ void plot_point(UINT8 x, UINT8 y); /** I (MLH) have no idea what switch_data does... */ void switch_data(UINT8 x, UINT8 y, unsigned char *src, unsigned char *dst) NONBANKED; /** Ditto */ void draw_image(unsigned char *data) NONBANKED; /** Draw a line in the current drawing mode and colour from (x1,y1) to (x2,y2) */ void line(UINT8 x1, UINT8 y1, UINT8 x2, UINT8 y2); /** Draw a box (rectangle) with corners (x1,y1) and (x2,y2) using fill mode 'style' (one of NOFILL or FILL */ void box(UINT8 x1, UINT8 y1, UINT8 x2, UINT8 y2, UINT8 style); /** Draw a circle with centre at (x,y) and radius 'radius'. 'style' sets the fill mode */ void circle(UINT8 x, UINT8 y, UINT8 radius, UINT8 style); /** Returns the current colour of the pixel at (x,y) */ UINT8 getpix(UINT8 x, UINT8 y); /** Prints the character 'chr' in the default font at the current position */ void wrtchr(char chr); /** Sets the current text position to (x,y). Note that x and y have units of cells (8 pixels) */ void gotogxy(UINT8 x, UINT8 y); /** Set the current foreground colour (for pixels), background colour, and draw mode */ void color(UINT8 forecolor, UINT8 backcolor, UINT8 mode); #endif /* __DRAWING_H */ ================================================ FILE: include/gb/font.h ================================================ /** @file gb/font.h Multiple font support for the GameBoy Michael Hope, 1999 michaelh@earthling.net */ #ifndef __FONT_H #define __FONT_H #include /** Various flags in the font header. */ #define FONT_256ENCODING 0 #define FONT_128ENCODING 1 #define FONT_NOENCODING 2 #define FONT_COMPRESSED 4 /* See gb.h/M_NO_SCROLL and gb.h/M_NO_INTERP */ /** font_t is a handle to a font loaded by font_load() */ typedef UINT16 font_t; /** The default fonts */ extern UINT8 font_spect[], font_italic[], font_ibm[], font_min[]; /** Backwards compatible font */ extern UINT8 font_ibm_fixed[]; /** Init the font system. Should be called first. */ void font_init(void) NONBANKED; /** Load the font 'font'. Sets the current font to the newly loaded font. */ font_t font_load( void *font ) NONBANKED; /** Set the current font to 'font_handle', which was returned from an earlier font_load(). @return The previously used font handle. */ font_t font_set( font_t font_handle ) NONBANKED; /* Use mode() and color() to set the font modes and colours */ /** Internal representation of a font. What a font_t really is */ typedef struct sfont_handle mfont_handle; typedef struct sfont_handle *pmfont_handle; struct sfont_handle { UINT8 first_tile; /* First tile used */ void *font; /* Pointer to the base of the font */ }; #endif /* __FONT_H */ ================================================ FILE: include/gb/gb.h ================================================ /** @file gb/gb.h Gameboy specific functions. */ #ifndef _GB_H #define _GB_H #include #include #include #include /** Joypad bits. A logical OR of these is used in the wait_pad and joypad functions. For example, to see if the B button is pressed try UINT8 keys; keys = joypad(); if (keys & J_B) { ... } @see joypad */ #define J_START 0x80U #define J_SELECT 0x40U #define J_B 0x20U #define J_A 0x10U #define J_DOWN 0x08U #define J_UP 0x04U #define J_LEFT 0x02U #define J_RIGHT 0x01U /** Screen modes. Normally used by internal functions only. */ #define M_DRAWING 0x01U #define M_TEXT_OUT 0x02U #define M_TEXT_INOUT 0x03U /** Set this in addition to the others to disable scrolling If scrolling is disabled, the cursor returns to (0,0) */ #define M_NO_SCROLL 0x04U /** Set this to disable \n interpretation */ #define M_NO_INTERP 0x08U /** If this is set, sprite colours come from OBJ1PAL. Else they come from OBJ0PAL. */ #define S_PALETTE 0x10U /** If set the sprite will be flipped horizontally. */ #define S_FLIPX 0x20U /** If set the sprite will be flipped vertically. */ #define S_FLIPY 0x40U /** If this bit is clear, then the sprite will be displayed ontop of the background and window. */ #define S_PRIORITY 0x80U /* Interrupt flags */ /** Vertical blank interrupt. Occurs at the start of the vertical blank. During this period the video ram may be freely accessed. */ #define VBL_IFLAG 0x01U /** Interrupt when triggered by the STAT register. See the Pan doc. */ #define LCD_IFLAG 0x02U /** Interrupt when the timer TIMA overflows. */ #define TIM_IFLAG 0x04U /** Occurs when the serial transfer has completed. */ #define SIO_IFLAG 0x08U /** Occurs on a transition of the keypad. */ #define JOY_IFLAG 0x10U /* Limits */ /** Width of the visible screen in pixels. */ #define SCREENWIDTH 0xA0U /** Height of the visible screen in pixels. */ #define SCREENHEIGHT 0x90U #define MINWNDPOSX 0x07U #define MINWNDPOSY 0x00U #define MAXWNDPOSX 0xA6U #define MAXWNDPOSY 0x8FU /* ************************************************************ */ /** Interrupt handlers */ typedef void (*int_handler)(void) NONBANKED; /** The remove functions will remove any interrupt handler. A handler of NULL will cause bad things to happen. */ void remove_VBL(int_handler h) NONBANKED; void remove_LCD(int_handler h) NONBANKED; void remove_TIM(int_handler h) NONBANKED; void remove_SIO(int_handler h) NONBANKED; void remove_JOY(int_handler h) NONBANKED; /** Adds a V-blank interrupt handler. The handler 'h' will be called whenever a V-blank interrupt occurs. Up to 4 handlers may be added, with the last added being called last. If the remove_VBL function is to be called, only three may be added. @see remove_VBL */ void add_VBL(int_handler h) NONBANKED; /** Adds a LCD interrupt handler. Called when the LCD interrupt occurs, which is normally when LY_REG == LYC_REG. From pan/k0Pa: There are various reasons for this interrupt to occur as described by the STAT register ($FF40). One very popular reason is to indicate to the user when the video hardware is about to redraw a given LCD line. This can be useful for dynamically controlling the SCX/ SCY registers ($FF43/$FF42) to perform special video effects. @see add_VBL */ void add_LCD(int_handler h) NONBANKED; /** Adds a timer interrupt handler. From pan/k0Pa: This interrupt occurs when the TIMA register ($FF05) changes from $FF to $00. @see add_VBL */ void add_TIM(int_handler h) NONBANKED; /** Adds a serial transmit complete interrupt handler. From pan/k0Pa: This interrupt occurs when a serial transfer has completed on the game link port. @see send_byte, receive_byte, add_VBL */ void add_SIO(int_handler h) NONBANKED; /** Adds a pad tranisition interrupt handler. From pan/k0Pa: This interrupt occurs on a transition of any of the keypad input lines from high to low. Due to the fact that keypad "bounce" is virtually always present, software should expect this interrupt to occur one or more times for every button press and one or more times for every button release. @see joypad */ void add_JOY(int_handler h) NONBANKED; /* ************************************************************ */ /** Set the current mode - one of M_* defined above */ void mode(UINT8 m) NONBANKED; /** Returns the current mode */ UINT8 get_mode(void) NONBANKED; /** GB type (GB, PGB, CGB) */ extern UINT8 _cpu; /** Original GB or Super GB */ #define DMG_TYPE 0x01 /** Pocket GB or Super GB 2 */ #define MGB_TYPE 0xFF /** Color GB */ #define CGB_TYPE 0x11 /** Time in VBL periods (60Hz) */ extern UINT16 sys_time; /* ************************************************************ */ /** Send byte in _io_out to the serial port */ void send_byte(void); /** Receive byte from the serial port in _io_in */ void receive_byte(void); /** An OR of IO_* */ extern UINT8 _io_status; /** Byte just read. */ extern UINT8 _io_in; /** Write the byte to send here before calling send_byte() @see send_byte */ extern UINT8 _io_out; /* Status codes */ /** IO is completed */ #define IO_IDLE 0x00U /** Sending data */ #define IO_SENDING 0x01U /** Receiving data */ #define IO_RECEIVING 0x02U /** Error */ #define IO_ERROR 0x04U /* ************************************************************ */ /* Multiple banks */ /** Switches the upper 16k bank of the 32k rom to bank rombank using the MBC1 controller. By default the upper 16k bank is 1. Make sure the rom you compile has more than just bank 0 and bank 1, a 32k rom. This is done by feeding lcc.exe the following switches: -Wl-yt# where # is the type of cartridge. 1 for ROM+MBC1. -Wl-yo# where # is the number of rom banks. 2,4,8,16,32. */ #define SWITCH_ROM_MBC1(b) \ *(unsigned char *)0x2000 = (b) #define SWITCH_RAM_MBC1(b) \ *(unsigned char *)0x4000 = (b) #define ENABLE_RAM_MBC1 \ *(unsigned char *)0x0000 = 0x0A #define DISABLE_RAM_MBC1 \ *(unsigned char *)0x0000 = 0x00 #define SWITCH_16_8_MODE_MBC1 \ *(unsigned char *)0x6000 = 0x00 #define SWITCH_4_32_MODE_MBC1 \ *(unsigned char *)0x6000 = 0x01 /* Note the order used here. Writing the other way around * on a MBC1 always selects bank 0 (d'oh) */ /** MBC5 */ #define SWITCH_ROM_MBC5(b) \ *(unsigned char *)0x3000 = (UINT16)(b)>>8; \ *(unsigned char *)0x2000 = (UINT8)(b) #define SWITCH_RAM_MBC5(b) \ *(unsigned char *)0x4000 = (b) #define ENABLE_RAM_MBC5 \ *(unsigned char *)0x0000 = 0x0A #define DISABLE_RAM_MBC5 \ *(unsigned char *)0x0000 = 0x00 /* ************************************************************ */ /** Delays the given number of milliseconds. Uses no timers or interrupts, and can be called with interrupts disabled (why nobody knows :) */ void delay(UINT16 d) NONBANKED; /* ************************************************************ */ /** Reads and returns the current state of the joypad. Follows Nintendo's guidelines for reading the pad. Return value is an OR of J_* @see J_START */ UINT8 joypad(void) NONBANKED; /** Waits until all the keys given in mask are pressed. Normally only used for checking one key, but it will support many, even J_LEFT at the same time as J_RIGHT :) @see joypad, J_START */ UINT8 waitpad(UINT8 mask) NONBANKED; /** Waits for the pad and all buttons to be released. */ void waitpadup(void) NONBANKED; /* ************************************************************ */ /** Enables unmasked interrupts @see disable_interrupts */ void enable_interrupts(void) NONBANKED; /** Disables interrupts. This function may be called as many times as you like; however the first call to enable_interrupts will re-enable them. @see enable_interrupts */ void disable_interrupts(void) NONBANKED; /** Clears any pending interrupts and sets the interrupt mask register IO to flags. @see VBL_IFLAG @param flags A logical OR of *_IFLAGS */ void set_interrupts(UINT8 flags) NONBANKED; /** Performs a warm reset by reloading the CPU value then jumping to the start of crt0 (0x0150) */ void reset(void) NONBANKED; /** Waits for the vertical blank interrupt (VBL) to finish. This can be used to sync animation with the screen re-draw. If VBL interrupt is disabled, this function will never return. If the screen is off this function returns immediatly. */ void wait_vbl_done(void) NONBANKED; /** Turns the display off. Waits until the VBL interrupt before turning the display off. @see DISPLAY_ON */ void display_off(void) NONBANKED; /* ************************************************************ */ /** Copies data from somewhere in the lower address space to part of hi-ram. @param dst Offset in high ram (0xFF00 and above) to copy to. @param src Area to copy from @param n Number of bytes to copy. */ void hiramcpy(UINT8 dst, const void *src, UINT8 n) NONBANKED; /* ************************************************************ */ /** Turns the display back on. @see display_off, DISPLAY_OFF */ #define DISPLAY_ON \ LCDC_REG|=0x80U /** Turns the display off immediatly. @see display_off, DISPLAY_ON */ #define DISPLAY_OFF \ display_off(); /** Turns on the background layer. Sets bit 0 of the LCDC register to 1. */ #define SHOW_BKG \ LCDC_REG|=0x01U /** Turns off the background layer. Sets bit 0 of the LCDC register to 0. */ #define HIDE_BKG \ LCDC_REG&=0xFEU /** Turns on the window layer Sets bit 5 of the LCDC register to 1. */ #define SHOW_WIN \ LCDC_REG|=0x20U /** Turns off the window layer. Clears bit 5 of the LCDC register to 0. */ #define HIDE_WIN \ LCDC_REG&=0xDFU /** Turns on the sprites layer. Sets bit 1 of the LCDC register to 1. */ #define SHOW_SPRITES \ LCDC_REG|=0x02U /** Turns off the sprites layer. Clears bit 1 of the LCDC register to 0. */ #define HIDE_SPRITES \ LCDC_REG&=0xFDU /** Sets sprite size to 8x16 pixels, two tiles one above the other. Sets bit 2 of the LCDC register to 1. */ #define SPRITES_8x16 \ LCDC_REG|=0x04U /** Sets sprite size to 8x8 pixels, one tile. Clears bit 2 of the LCDC register to 0. */ #define SPRITES_8x8 \ LCDC_REG&=0xFBU /* ************************************************************ */ /** Sets the tile patterns in the Background Tile Pattern table. Starting with the tile pattern x and carrying on for n number of tile patterns.Taking the values starting from the pointer data. Note that patterns 128-255 overlap with patterns 128-255 of the sprite Tile Pattern table. GBC: Depending on the VBK_REG this determines which bank of Background tile patterns are written to. VBK_REG=0 indicates the first bank, and VBK_REG=1 indicates the second. @param first_tile Range 0 - 255 @param nb_tiles Range 0 - 255 */ void set_bkg_data(UINT8 first_tile, UINT8 nb_tiles, unsigned char *data) NONBANKED; /** Sets the tiles in the background tile table. Starting at position x,y in tiles and writing across for w tiles and down for h tiles. Taking the values starting from the pointer data. For the GBC, also see the pan/k00Pa section on VBK_REG. @param x Range 0 - 31 @param y Range 0 - 31 @param w Range 0 - 31 @param h Range 0 - 31 @param data Pointer to an unsigned char. Usually the first element in an array. */ void set_bkg_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *tiles) NONBANKED; void get_bkg_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *tiles) NONBANKED; /** Moves the background layer to the position specified in x and y in pixels. Where 0,0 is the top left corner of the GB screen. You'll notice the screen wraps around in all 4 directions, and is always under the window layer. */ void move_bkg(UINT8 x, UINT8 y) NONBANKED; /** Moves the background relative to it's current position. @see move_bkg */ void scroll_bkg(INT8 x, INT8 y) NONBANKED; /* ************************************************************ */ /** Sets the window tile data. This is the same as set_bkg_data, as both the window layer and background layer share the same Tile Patterns. @see set_bkg_data */ void set_win_data(UINT8 first_tile, UINT8 nb_tiles, unsigned char *data) NONBANKED; /** Sets the tiles in the win tile table. Starting at position x,y in tiles and writing across for w tiles and down for h tiles. Taking the values starting from the pointer data. Note that patterns 128-255 overlap with patterns 128-255 of the sprite Tile Pattern table. GBC only. Depending on the VBK_REG this determines if you're setting the tile numbers VBK_REG=0; or the attributes for those tiles VBK_REG=1;. The bits in the attributes are defined as: Bit 7 - Priority flag. When this is set, it puts the tile above the sprites with colour 0 being transparent. 0: below sprites, 1: above sprites Note SHOW_BKG needs to be set for these priorities to take place. Bit 6 - Vertical flip. Dictates which way up the tile is drawn vertically. 0: normal, 1: upside down. Bit 5 - Horizontal flip. Dictates which way up the tile is drawn horizontally. 0: normal, 1:back to front. Bit 4 - Not used. Bit 3 - Character Bank specification. Dictates from which bank of Background Tile Patterns the tile is taken. 0: Bank 0, 1: Bank 1 Bit 2 - See bit 0. Bit 1 - See bit 0. Bit 0 - Bits 0-2 indicate which of the 7 BKG colour palettes the tile is assigned. @param x Range 0 - 31 @param y Range 0 - 31 @param w Range 0 - 31 @param h Range 0 - 31 */ void set_win_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *tiles) NONBANKED; void get_win_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *tiles) NONBANKED; /** Moves the window layer to the position specified in x and y in pixels. Where 7,0 is the top left corner of the GB screen. The window is locked to the bottom right corner, and is always over the background layer. @see SHOW_WIN, HIDE_WIN */ void move_win(UINT8 x, UINT8 y) NONBANKED; /** Move the window relative to its current position. @see move_win */ void scroll_win(INT8 x, INT8 y) NONBANKED; /* ************************************************************ */ /** Sets the tile patterns in the Sprite Tile Pattern table. Starting with the tile pattern x and carrying on for n number of tile patterns.Taking the values starting from the pointer data. Note that patterns 128-255 overlap with patterns 128-255 of the Background Tile Pattern table. GBC only. Depending on the VBK_REG this determines which bank of Background tile patterns are written to. VBK_REG=0 indicates the first bank, and VBK_REG=1 indicates the second. */ void set_sprite_data(UINT8 first_tile, UINT8 nb_tiles, unsigned char *data) NONBANKED; void get_sprite_data(UINT8 first_tile, UINT8 nb_tiles, unsigned char *data) NONBANKED; /** Sets sprite n to display tile number t, from the sprite tile data. If the GB is in 8x16 sprite mode then it will display the next tile, t+1, below the first tile. @param nb Sprite number, range 0 - 39 */ void set_sprite_tile(UINT8 nb, UINT8 tile) NONBANKED; UINT8 get_sprite_tile(UINT8 nb) NONBANKED; /** Sets the property of sprite n to those defined in p. Where the bits in p represent: Bit 7 - Priority flag. When this is set the sprites appear behind the background and window layer. 0: infront, 1: behind. Bit 6 - GBC only. Vertical flip. Dictates which way up the sprite is drawn vertically. 0: normal, 1:upside down. Bit 5 - GBC only. Horizontal flip. Dictates which way up the sprite is drawn horizontally. 0: normal, 1:back to front. Bit 4 - DMG only. Assigns either one of the two b/w palettes to the sprite. 0: OBJ palette 0, 1: OBJ palette 1. Bit 3 - GBC only. Dictates from which bank of Sprite Tile Patterns the tile is taken. 0: Bank 0, 1: Bank 1 Bit 2 - See bit 0. Bit 1 - See bit 0. Bit 0 - GBC only. Bits 0-2 indicate which of the 7 OBJ colour palettes the sprite is assigned. @param nb Sprite number, range 0 - 39 */ void set_sprite_prop(UINT8 nb, UINT8 prop) NONBANKED; UINT8 get_sprite_prop(UINT8 nb) NONBANKED; /** Moves the given sprite to the given position on the screen. Dont forget that the top left visible pixel on the screen is at (8,16). To put sprite 0 at the top left, use move_sprite(0, 8, 16); */ void move_sprite(UINT8 nb, UINT8 x, UINT8 y) NONBANKED; /** Moves the given sprite relative to its current position. */ void scroll_sprite(INT8 nb, INT8 x, INT8 y) NONBANKED; /* ************************************************************ */ void set_data(unsigned char *vram_addr, unsigned char *data, UINT16 len) NONBANKED; void get_data(unsigned char *data, unsigned char *vram_addr, UINT16 len) NONBANKED; void set_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *vram_addr, unsigned char *tiles) NONBANKED; void get_tiles(UINT8 x, UINT8 y, UINT8 w, UINT8 h, unsigned char *tiles, unsigned char *vram_addr) NONBANKED; #endif /* _GB_H */ ================================================ FILE: include/gb/hardware.h ================================================ /** @file gb/hardware.h Defines that let the GB's hardware registers be accessed from C. See the Pan doc for what to set them to. */ #ifndef _HARDWARE_H #define _HARDWARE_H #include #if USE_SFR_FOR_REG #error SFR is unteseted and disabled in 2.96 #define __REG extern volatile sfr UINT8 __REG P1_REG ; /* Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ __REG SB_REG ; /* Serial IO data buffer */ __REG SC_REG ; /* Serial IO control register */ __REG DIV_REG ; /* Divider register */ __REG TIMA_REG ; /* Timer counter */ __REG TMA_REG ; /* Timer modulo */ __REG TAC_REG ; /* Timer control */ __REG IF_REG ; /* Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ __REG NR10_REG ; /* Sound register */ __REG NR11_REG ; /* Sound register */ __REG NR12_REG ; /* Sound register */ __REG NR13_REG ; /* Sound register */ __REG NR14_REG ; /* Sound register */ __REG NR21_REG ; /* Sound register */ __REG NR22_REG ; /* Sound register */ __REG NR23_REG ; /* Sound register */ __REG NR24_REG ; /* Sound register */ __REG NR30_REG ; /* Sound register */ __REG NR31_REG ; /* Sound register */ __REG NR32_REG ; /* Sound register */ __REG NR33_REG ; /* Sound register */ __REG NR34_REG ; /* Sound register */ __REG NR41_REG ; /* Sound register */ __REG NR42_REG ; /* Sound register */ __REG NR43_REG ; /* Sound register */ __REG NR44_REG ; /* Sound register */ __REG NR50_REG ; /* Sound register */ __REG NR51_REG ; /* Sound register */ __REG NR52_REG ; /* Sound register */ __REG LCDC_REG ; /* LCD control */ __REG STAT_REG ; /* LCD status */ __REG SCY_REG ; /* Scroll Y */ __REG SCX_REG ; /* Scroll X */ __REG LY_REG ; /* LCDC Y-coordinate */ __REG LYC_REG ; /* LY compare */ __REG DMA_REG ; /* DMA transfer */ __REG BGP_REG ; /* BG palette data */ __REG OBP0_REG ; /* OBJ palette 0 data */ __REG OBP1_REG ; /* OBJ palette 1 data */ __REG WY_REG ; /* Window Y coordinate */ __REG WX_REG ; /* Window X coordinate */ __REG KEY1_REG ; /* CPU speed */ __REG VBK_REG ; /* VRAM bank */ __REG HDMA1_REG ; /* DMA control 1 */ __REG HDMA2_REG ; /* DMA control 2 */ __REG HDMA3_REG ; /* DMA control 3 */ __REG HDMA4_REG ; /* DMA control 4 */ __REG HDMA5_REG ; /* DMA control 5 */ __REG RP_REG ; /* IR port */ __REG BCPS_REG ; /* BG color palette specification */ __REG BCPD_REG ; /* BG color palette data */ __REG OCPS_REG ; /* OBJ color palette specification */ __REG OCPD_REG ; /* OBJ color palette data */ __REG SVBK_REG ; /* WRAM bank */ __REG IE_REG ; /* Interrupt enable */ #else #define __REG volatile UINT8 * #define P1_REG (*(__REG)0xFF00) /* Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ #define SB_REG (*(__REG)0xFF01) /* Serial IO data buffer */ #define SC_REG (*(__REG)0xFF02) /* Serial IO control register */ #define DIV_REG (*(__REG)0xFF04) /* Divider register */ #define TIMA_REG (*(__REG)0xFF05) /* Timer counter */ #define TMA_REG (*(__REG)0xFF06) /* Timer modulo */ #define TAC_REG (*(__REG)0xFF07) /* Timer control */ #define IF_REG (*(__REG)0xFF0F) /* Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ #define NR10_REG (*(__REG)0xFF10) /* Sound register */ #define NR11_REG (*(__REG)0xFF11) /* Sound register */ #define NR12_REG (*(__REG)0xFF12) /* Sound register */ #define NR13_REG (*(__REG)0xFF13) /* Sound register */ #define NR14_REG (*(__REG)0xFF14) /* Sound register */ #define NR21_REG (*(__REG)0xFF16) /* Sound register */ #define NR22_REG (*(__REG)0xFF17) /* Sound register */ #define NR23_REG (*(__REG)0xFF18) /* Sound register */ #define NR24_REG (*(__REG)0xFF19) /* Sound register */ #define NR30_REG (*(__REG)0xFF1A) /* Sound register */ #define NR31_REG (*(__REG)0xFF1B) /* Sound register */ #define NR32_REG (*(__REG)0xFF1C) /* Sound register */ #define NR33_REG (*(__REG)0xFF1D) /* Sound register */ #define NR34_REG (*(__REG)0xFF1E) /* Sound register */ #define NR41_REG (*(__REG)0xFF20) /* Sound register */ #define NR42_REG (*(__REG)0xFF21) /* Sound register */ #define NR43_REG (*(__REG)0xFF22) /* Sound register */ #define NR44_REG (*(__REG)0xFF23) /* Sound register */ #define NR50_REG (*(__REG)0xFF24) /* Sound register */ #define NR51_REG (*(__REG)0xFF25) /* Sound register */ #define NR52_REG (*(__REG)0xFF26) /* Sound register */ #define LCDC_REG (*(__REG)0xFF40) /* LCD control */ #define STAT_REG (*(__REG)0xFF41) /* LCD status */ #define SCY_REG (*(__REG)0xFF42) /* Scroll Y */ #define SCX_REG (*(__REG)0xFF43) /* Scroll X */ #define LY_REG (*(__REG)0xFF44) /* LCDC Y-coordinate */ #define LYC_REG (*(__REG)0xFF45) /* LY compare */ #define DMA_REG (*(__REG)0xFF46) /* DMA transfer */ #define BGP_REG (*(__REG)0xFF47) /* BG palette data */ #define OBP0_REG (*(__REG)0xFF48) /* OBJ palette 0 data */ #define OBP1_REG (*(__REG)0xFF49) /* OBJ palette 1 data */ #define WY_REG (*(__REG)0xFF4A) /* Window Y coordinate */ #define WX_REG (*(__REG)0xFF4B) /* Window X coordinate */ #define KEY1_REG (*(__REG)0xFF4D) /* CPU speed */ #define VBK_REG (*(__REG)0xFF4F) /* VRAM bank */ #define HDMA1_REG (*(__REG)0xFF51) /* DMA control 1 */ #define HDMA2_REG (*(__REG)0xFF52) /* DMA control 2 */ #define HDMA3_REG (*(__REG)0xFF53) /* DMA control 3 */ #define HDMA4_REG (*(__REG)0xFF54) /* DMA control 4 */ #define HDMA5_REG (*(__REG)0xFF55) /* DMA control 5 */ #define RP_REG (*(__REG)0xFF56) /* IR port */ #define BCPS_REG (*(__REG)0xFF68) /* BG color palette specification */ #define BCPD_REG (*(__REG)0xFF69) /* BG color palette data */ #define OCPS_REG (*(__REG)0xFF6A) /* OBJ color palette specification */ #define OCPD_REG (*(__REG)0xFF6B) /* OBJ color palette data */ #define SVBK_REG (*(__REG)0xFF70) /* WRAM bank */ #define IE_REG (*(__REG)0xFFFF) /* Interrupt enable */ #endif #endif /* _HARDWARE_H */ ================================================ FILE: include/gb/malloc.h ================================================ /** @file gb/malloc.h Header for a simple implementation of malloc(). This library may currently be broken. */ #ifndef __SYS_MALLOC_H #define __SYS_MALLOC_H #include /* The various constants */ /** The malloc hunk flags Note: Cound have used a negative size a'la TI */ #define MALLOC_FREE 1 #define MALLOC_USED 2 /** Magic number of a header. Gives us some chance of surviving if the list is corrupted*/ #define MALLOC_MAGIC 123 /* malloc hunk header definition */ typedef struct smalloc_hunk mmalloc_hunk; typedef struct smalloc_hunk * pmmalloc_hunk; struct smalloc_hunk { UBYTE magic; /* Magic number - indicates valid hunk header */ pmmalloc_hunk next; /* Pointer to the next hunk */ UWORD size; /* Size in bytes of this region */ int status; /* One of MALLOC_FREE or MALLOC_USED */ }; /** Start of free memory, as defined by the linker */ extern UBYTE malloc_heap_start; /** First hunk */ extern pmmalloc_hunk malloc_first; /** Garbage collect (join free hunks) */ void malloc_gc(void) NONBANKED; /** debug message logger */ void debug( char *routine, char *msg ) NONBANKED; #endif /* __SYS_MALLOC_H */ ================================================ FILE: include/gb/rand.h ================================================ /** @file rand.h Random generator using the linear congruential method @author Luc Van den Borre */ #ifndef RAND_INCLUDE #define RAND_INCLUDE #include /** Initalise the random number generator. seed needs to be different each time, else the same sequence will be generated. A good source is the DIV register. */ void initrand(UINT16 seed) NONBANKED; /* Non-banked as called from asm in arand.s */ /** Returns a random value. */ INT8 _rand(void); /** Returns a random word. */ UINT16 _randw(void); /** Random generator using the linear lagged additive method Note that 'initarand()' calls 'initrand()' with the same seed value, and uses 'rand()' to initialize the random generator. @author Luc Van den Borre */ void initarand(UINT16 seed); /** Generates a random number using the linear lagged additive method. */ INT8 arand(void); #endif ================================================ FILE: include/gb/sample.h ================================================ /** @file gb/sample.h Playback raw sound sample with length len from start at 8192Hz rate. len defines the length of the sample in samples/32 or bytes/16. The format of the data is unsigned 4-bit samples, 2 samples per byte, upper 4-bits played before lower 4 bits. Adaption for GBDK by Lars Malmborg. Original code by Jeff Frohwein. */ #ifndef _SAMPLE_H #define _SAMPLE_H /** Play the given, appropriatly formatted sample. */ void play_sample(UINT8 *start, UINT16 len) NONBANKED; #endif /* _SAMPLE_H */ ================================================ FILE: include/gb/sgb.h ================================================ /** @file gb/sgb.h Super Gameboy definitions. */ #ifndef _SGB_H #define _SGB_H /** Return a non-null value if running on Super GameBoy */ UINT8 sgb_check(void); #endif /* _SGB_H */ ================================================ FILE: libc/arand.s ================================================ ;/*************************************************************************** ; * * ; * Module : arand.s * ; * * ; * Purpose : A random number generator using the lagged additive method * ; * * ; * Version : 1, January 11 1998 * ; * * ; * Author : Luc Van den Borre ( Homepage : NOC.BASE.ORG ) * ; * * ; **************************************************************************/ ;; BANKED: checked .include "global.s" .globl .initrand .globl _rand .area _BSS .randarr: .ds 55 .raxj: .ds 0x01 .raxk: .ds 0x01 .area _CODE ;; arand() operates on an array of 55 arbitrary values (here : bytes). ;; It adds two values of the array together, replaces one of the values ;; with the result, and returns the result. ;; At start, the indices into the array refer to the 55th and 24th element. ;; After each call, each index is decreased, and looped around if necessary. ;; This kind of works, but the values produces are less good than those by ;; rand(), mainly because it operates on bytes instead of words. ;; Ref : D. E. Knuth, "The Art of Computer Programming" , Volume 2 ;; ;; Exit conditions ;; DE = Random number (byte!) ;; ;; Registers used: ;; all ;; _arand:: ; Banked PUSH BC LD D,#0 LD HL,#.randarr-1 LD A,(.raxj) LD E,A DEC A ; Decrease the pointer JR NZ,1$ LD A,#55 1$: LD (.raxj),A ADD HL,DE LD B,(HL) LD HL,#.randarr-1 ; Ooh... LD A,(.raxk) LD E,A DEC A ; Decrease the pointer JR NZ,2$ LD A,#55 2$: LD (.raxk),A ADD HL,DE LD A,(HL) ADD A,B LD (HL),A ; Store new value POP BC LD D,#0 LD E,A RET ;; _initarand calls the _rand function to fill the array with random values ;; Note that this also sets the seed value of the _rand function first, ;; like _initrand ;; ;; Exit conditions ;; None ;; ;; Registers used: ;; all ;; _initarand:: ; Banked LDA HL,.BANKOV(SP) CALL .initrand PUSH BC LD A,#55 LD HL,#.randarr 1$: DEC A LD (.raxj),A LD B,H LD C,L CALL _rand LD H,B LD L,C LD (HL),D INC HL LD (HL),E INC HL LD A,(.raxj) CP #0 JR NZ,1$ LD A,#24 ; Now the array has been filled,set the pointers LD (.raxj),A LD A,#55 LD (.raxk),A POP BC RET ================================================ FILE: libc/cgb.s ================================================ .include "global.s" .title "CGB support" .module CGB ;; BANKED: checked, imperfect .area _BASE _set_bkg_palette:: ; Non-banked PUSH BC PUSH DE LDA HL,9(SP) ; Skip return address and registers LD B,(HL) ; BC = rgb_data DEC HL LD C,(HL) DEC HL LD D,(HL) ; D = nb_palettes DEC HL LD E,(HL) ; E = first_palette LD A,D ; A = nb_palettes ADD E ADD A ; A *= 8 ADD A ADD A LD D,A LD A,E ; E = first_palette ADD A ; A *= 8 ADD A ADD A LD E,A ; A = first BCPS data 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD A,E LDH (.BCPS),A LD A,(BC) LDH (.BCPD),A INC BC ; next rgb_data INC E ; next BCPS LD A,E CP A,D JR NZ,1$ POP DE POP BC RET _set_sprite_palette:: ; Non-banked PUSH BC PUSH DE LDA HL,9(SP) ; Skip return address and registers LD B,(HL) ; BC = rgb_data DEC HL LD C,(HL) DEC HL LD D,(HL) ; D = nb_palettes DEC HL LD E,(HL) ; E = first_palette LD A,D ; A = nb_palettes ADD E ADD A ; A *= 8 ADD A ADD A LD D,A LD A,E ; E = first_palette ADD A ; A *= 8 ADD A ADD A LD E,A ; A = first BCPS data 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD A,E LDH (.OCPS),A LD A,(BC) LDH (.OCPD),A INC BC ; next rgb_data INC E ; next BCPS LD A,E CP A,D JR NZ,1$ POP DE POP BC RET .area _CODE _set_bkg_palette_entry:: ; Banked PUSH BC PUSH DE LDA HL,.BANKOV+4+3(SP); Skip return address and registers LD B,(HL) ; BC = rgb_data DEC HL LD C,(HL) DEC HL LD D,(HL) ; D = pal_entry DEC HL LD E,(HL) ; E = first_palette LD A,E ; E = first_palette ADD A ; A *= 8 ADD A ADD A ADD D ; A += 2 * pal_entry ADD D LD E,A ; A = first BCPS data 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD A,E LDH (.BCPS),A LD A,C LDH (.BCPD),A INC E ; next BCPS LD A,E LDH (.BCPS),A LD A,B LDH (.BCPD),A POP DE POP BC RET _set_sprite_palette_entry:: PUSH BC PUSH DE LDA HL,.BANKOV+4+3(SP); Skip return address and registers LD B,(HL) ; BC = rgb_data DEC HL LD C,(HL) DEC HL LD D,(HL) ; D = pal_entry DEC HL LD E,(HL) ; E = first_palette LD A,E ; E = first_palette ADD A ; A *= 8 ADD A ADD A ADD D ; A += 2 * pal_entry ADD D LD E,A ; A = first BCPS data 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD A,E LDH (.OCPS),A LD A,C LDH (.OCPD),A INC E ; next BCPS LD A,E LDH (.OCPS),A LD A,B LDH (.OCPD),A POP DE POP BC RET .area _CODE _cpu_slow:: ; Banked LDH A,(.KEY1) AND #0x80 ; Is GBC in double speed mode? RET Z ; No, already in single speed shift_speed: LDH A,(.IE) PUSH AF XOR A ; A = 0 LDH (.IE),A ; Disable interrupts LDH (.IF),A LD A,#0x30 LDH (.P1),A LD A,#0x01 LDH (.KEY1),A STOP POP AF LDH (.IE),A RET _cpu_fast:: ; Banked LDH A,(.KEY1) AND #0x80 ; Is GBC in double speed mode? RET NZ ; Yes, exit JR shift_speed _cgb_compatibility:: ; Banked LD A,#0x80 LDH (.BCPS),A ; Set default bkg palette LD A,#0xff ; White LDH (.BCPD),A LD A,#0x7f LDH (.BCPD),A LD A,#0xb5 ; Light gray LDH (.BCPD),A LD A,#0x56 LDH (.BCPD),A LD A,#0x4a ; Dark gray LDH (.BCPD),A LD A,#0x29 LDH (.BCPD),A LD A,#0x00 ; Black LDH (.BCPD),A LD A,#0x00 LDH (.BCPD),A LD A,#0x80 LDH (.OCPS),A ; Set default sprite palette LD A,#0xff ; White LDH (.OCPD),A LD A,#0x7f LDH (.OCPD),A LD A,#0xb5 ; Light gray LDH (.OCPD),A LD A,#0x56 LDH (.OCPD),A LD A,#0x4a ; Dark gray LDH (.OCPD),A LD A,#0x29 LDH (.OCPD),A LD A,#0x00 ; Black LDH (.OCPD),A LD A,#0x00 LDH (.OCPD),A RET ================================================ FILE: libc/cpy_data.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Copy part (size = DE) of the VRAM from (BC) to (HL) .copy_vram:: 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD A,(BC) LD (HL+),A INC BC DEC DE LD A,D OR E JR NZ,1$ RET _set_data:: _get_data:: PUSH BC LDA HL,9(SP) ; Skip return address and registers LD D,(HL) ; DE = len DEC HL LD E,(HL) DEC HL LD B,(HL) ; BC = src DEC HL LD C,(HL) DEC HL LD A,(HL-) ; HL = dst LD L,(HL) LD H,A CALL .copy_vram POP BC RET ================================================ FILE: libc/crt0.s ================================================ .include "global.s" ;; **************************************** ;; Beginning of module ;; BANKED: checked .title "Runtime" .module Runtime .area _HEADER (ABS) ;; Standard header for the GB .org 0x00 RET ; Empty function (default for interrupts) .org 0x10 .byte 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 .byte 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 ;; Interrupt vectors .org 0x40 ; VBL .int_VBL: PUSH HL LD HL,#.int_0x40 JP .int .org 0x48 ; LCD .int_LCD: PUSH HL LD HL,#.int_0x48 JP .int .org 0x50 ; TIM .int_TIM: PUSH HL LD HL,#.int_0x50 JP .int .org 0x58 ; SIO .int_SIO: PUSH HL LD HL,#.int_0x58 JP .int .org 0x60 ; JOY .int_JOY: PUSH HL LD HL,#.int_0x60 JP .int .int: PUSH AF PUSH BC PUSH DE 1$: LD A,(HL+) OR (HL) JR Z,2$ PUSH HL LD A,(HL-) LD L,(HL) LD H,A CALL 3$ POP HL INC HL JR 1$ 2$: POP DE POP BC POP AF POP HL RETI 3$: JP (HL) ;; GameBoy Header ;; DO NOT CHANGE... .org 0x100 .header: NOP JP 0x150 .byte 0xCE,0xED,0x66,0x66 .byte 0xCC,0x0D,0x00,0x0B .byte 0x03,0x73,0x00,0x83 .byte 0x00,0x0C,0x00,0x0D .byte 0x00,0x08,0x11,0x1F .byte 0x88,0x89,0x00,0x0E .byte 0xDC,0xCC,0x6E,0xE6 .byte 0xDD,0xDD,0xD9,0x99 .byte 0xBB,0xBB,0x67,0x63 .byte 0x6E,0x0E,0xEC,0xCC .byte 0xDD,0xDC,0x99,0x9F .byte 0xBB,0xB9,0x33,0x3E ;; Title of the game .org 0x134 .asciz "Title" .org 0x144 .byte 0,0,0 ;; Cartridge type is ROM only .org 0x147 .byte 0 ;; ROM size is 32kB .org 0x148 .byte 0 ;; RAM size is 0kB .org 0x149 .byte 0 ;; Maker ID .org 0x14A .byte 0x00,0x00 ;; Version number .org 0x14C .byte 0x01 ;; Complement check .org 0x14D .byte 0x00 ;; Checksum .org 0x14E .byte 0x00,0x00 ;; **************************************** .org 0x150 .code_start: ;; Beginning of the code DI ; Disable interrupts LD D,A ; Store CPU type in D XOR A ;; Initialize the stack LD SP,#.STACK ;; Clear from 0xC000 to 0xDFFF LD HL,#0xDFFF LD C,#0x20 LD B,#0x00 1$: LD (HL-),A DEC B JR NZ,1$ DEC C JR NZ,1$ ;; Clear from 0xFE00 to 0xFEFF LD HL,#0xFEFF LD B,#0x00 2$: LD (HL-),A DEC B JR NZ,2$ ;; Clear from 0xFF80 to 0xFFFF LD HL,#0xFFFF LD B,#0x80 3$: LD (HL-),A DEC B JR NZ,3$ ; LD (.mode),A ; Clearing (.mode) is performed when clearing RAM ;; Store CPU type LD A,D LD (__cpu),A ;; Turn the screen off CALL .display_off ;; Initialize the display XOR A LDH (.SCY),A LDH (.SCX),A LDH (.STAT),A LDH (.WY),A LD A,#0x07 LDH (.WX),A ;; Copy refresh_OAM routine to HIRAM LD BC,#.refresh_OAM LD HL,#.start_refresh_OAM LD B,#.end_refresh_OAM-.start_refresh_OAM 4$: LD A,(HL+) LDH (C),A INC C DEC B JR NZ,4$ ;; Install interrupt routines LD BC,#.vbl CALL .add_VBL LD BC,#.serial_IO CALL .add_SIO ;; Standard color palettes LD A,#0b11100100 ; Grey 3 = 11 (Black) ; Grey 2 = 10 (Dark grey) ; Grey 1 = 01 (Light grey) ; Grey 0 = 00 (Transparent) LDH (.BGP),A LDH (.OBP0),A LD A,#0b00011011 LDH (.OBP1),A ;; Turn the screen on LD A,#0b11000000 ; LCD = On ; WindowBank = 0x9C00 ; Window = Off ; BG Chr = 0x8800 ; BG Bank = 0x9800 ; OBJ = 8x8 ; OBJ = Off ; BG = Off LDH (.LCDC),A XOR A LDH (.IF),A LD A,#0b00001001 ; Pin P10-P13 = Off ; Serial I/O = On ; Timer Ovfl = Off ; LCDC = Off ; V-Blank = On LDH (.IE),A XOR A LDH (.NR52),A ; Turn sound off LDH (.SC),A ; Use external clock LD A,#.DT_IDLE LDH (.SB),A ; Send IDLE byte LD A,#0x80 LDH (.SC),A ; Use external clock XOR A ; Erase the malloc list ; LD (_malloc_heap_start+0),A ; LD (_malloc_heap_start+1),A ; LD (.sys_time+0),A ; Zero the system clock ; LD (.sys_time+1),A call gsinit ; CALL .init EI ; Enable interrupts ;; Call the main function CALL banked_call .dw _main .if __RGBDS__ .dw BANK(_main) .else .dw 1 .endif _exit:: 99$: HALT JR 99$ ; Wait forever .org .MODE_TABLE ;; Jump table for modes RET ;; **************************************** ;; Ordering of segments for the linker ;; Code that really needs to be in bank 0 .area _HOME ;; Similar to _HOME .area _BASE ;; Code .area _CODE ;; Constant data .area _LIT ;; Constant data used to init _DATA .area _GSINIT .area _GSINITTAIL .area _GSFINAL ;; Initialised in ram data .area _DATA ;; Uninitialised ram data .area _BSS ;; For malloc .area _HEAP .area _BSS __cpu:: .ds 0x01 ; GB type (GB, PGB, CGB) .mode:: .ds 0x01 ; Current mode __io_out:: .ds 0x01 ; Byte to send __io_in:: .ds 0x01 ; Received byte __io_status:: .ds 0x01 ; Status of serial IO .vbl_done:: .ds 0x01 ; Is VBL interrupt finished? __current_bank:: .ds 0x01 ; Current MBC1 style bank. .sys_time:: _sys_time:: .ds 0x02 ; System time in VBL units .int_0x40:: .blkw 0x08 .int_0x48:: .blkw 0x08 .int_0x50:: .blkw 0x08 .int_0x58:: .blkw 0x08 .int_0x60:: .blkw 0x08 ;; Runtime library .area _GSINIT gsinit:: .area _GSINITTAIL ret .area _HOME ;; Call the initialization function for the mode specified in HL .set_mode:: LD A,L LD (.mode),A ;; AND to get rid of the extra flags AND #0x03 LD L,A LD BC,#.MODE_TABLE SLA L ; Multiply mode by 4 SLA L ADD HL,BC JP (HL) ; Jump to initialization routine ;; Add interrupt routine in BC to the interrupt list .remove_VBL:: LD HL,#.int_0x40 JP .remove_int .remove_LCD:: LD HL,#.int_0x48 JP .remove_int .remove_TIM:: LD HL,#.int_0x50 JP .remove_int .remove_SIO:: LD HL,#.int_0x58 JP .remove_int .remove_JOY:: LD HL,#.int_0x60 JP .remove_int .add_VBL:: LD HL,#.int_0x40 JP .add_int .add_LCD:: LD HL,#.int_0x48 JP .add_int .add_TIM:: LD HL,#.int_0x50 JP .add_int .add_SIO:: LD HL,#.int_0x58 JP .add_int .add_JOY:: LD HL,#.int_0x60 JP .add_int ;; Remove interrupt BC from interrupt list HL if it exists ;; Abort if a 0000 is found (end of list) ;; Will only remove last int on list .remove_int:: 1$: LD A,(HL+) LD E,A LD D,(HL) OR D RET Z ; No interrupt found LD A,E CP C JR NZ,1$ LD A,D CP B JR NZ,1$ XOR A LD (HL-),A LD (HL),A INC A ; Clear Z flag ;; Now do a memcpy from here until the end of the list LD D,H LD E,L DEC DE INC HL 2$: LD A,(HL+) LD (DE),A LD B,A INC DE LD A,(HL+) LD (DE),A INC DE OR B RET Z JR 2$ ;; Add interrupt routine in BC to the interrupt list in HL .add_int:: 1$: LD A,(HL+) OR (HL) JR Z,2$ INC HL JR 1$ 2$: LD (HL),B DEC HL LD (HL),C RET ;; VBlank interrupt .vbl: LD HL,#.sys_time INC (HL) JR NZ,2$ INC HL INC (HL) 2$: CALL .refresh_OAM LD A,#0x01 LD (.vbl_done),A RET ;; Wait for VBL interrupt to be finished .wait_vbl_done:: _wait_vbl_done:: ;; Check if the screen is on LDH A,(.LCDC) ADD A RET NC ; Return if screen is off XOR A DI LD (.vbl_done),A ; Clear any previous sets of vbl_done EI 1$: HALT ; Wait for any interrupt NOP ; HALT sometimes skips the next instruction LD A,(.vbl_done) ; Was it a VBlank interrupt? ;; Warning: we may lose a VBlank interrupt, if it occurs now OR A JR Z,1$ ; No: back to sleep! XOR A LD (.vbl_done),A RET .display_off:: _display_off:: ;; Check if the screen is on LDH A,(.LCDC) ADD A RET NC ; Return if screen is off 1$: ; We wait for the *NEXT* VBL LDH A,(.LY) CP #0x92 ; Smaller than or equal to 0x91? JR NC,1$ ; Loop until smaller than or equal to 0x91 2$: LDH A,(.LY) CP #0x91 ; Bigger than 0x90? JR C,2$ ; Loop until bigger than 0x90 LDH A,(.LCDC) AND #0b01111111 LDH (.LCDC),A ; Turn off screen RET ;; Copy OAM data to OAM RAM .start_refresh_OAM: LD A,#>.OAM LDH (.DMA),A ; Put A into DMA registers LD A,#0x28 ; We need to wait 160 ns 1$: DEC A JR NZ,1$ RET .end_refresh_OAM: ;; Serial interrupt .serial_IO:: LD A,(__io_status) ; Get status CP #.IO_RECEIVING JR NZ,10$ ;; Receiving data LDH A,(.SB) ; Get data byte LD (__io_in),A ; Store it LD A,#.IO_IDLE JR 11$ 10$: CP #.IO_SENDING JR NZ,99$ ;; Sending data LDH A,(.SB) ; Get data byte CP #.DT_RECEIVING JR Z,11$ LD A,#.IO_ERROR JR 12$ 11$: LD A,#.IO_IDLE 12$: LD (__io_status),A ; Store status XOR A LDH (.SC),A ; Use external clock LD A,#.DT_IDLE LDH (.SB),A ; Reply with IDLE byte 99$: LD A,#0x80 LDH (.SC),A ; Enable transfer with external clock RET _mode:: LDA HL,2(SP) ; Skip return address LD L,(HL) LD H,#0x00 CALL .set_mode RET _get_mode:: LD HL,#.mode LD E,(HL) RET _enable_interrupts:: EI RET _disable_interrupts:: DI RET .reset:: _reset:: LD A,(__cpu) JP .code_start _set_interrupts:: DI LDA HL,2(SP) ; Skip return address XOR A LDH (.IF),A ; Clear pending interrupts LD A,(HL) LDH (.IE),A EI ; Enable interrupts RET _remove_VBL:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .remove_VBL POP BC RET _remove_LCD:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .remove_LCD POP BC RET _remove_TIM:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .remove_TIM POP BC RET _remove_SIO:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .remove_SIO POP BC RET _remove_JOY:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .remove_JOY POP BC RET _add_VBL:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .add_VBL POP BC RET _add_LCD:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .add_LCD POP BC RET _add_TIM:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .add_TIM POP BC RET _add_SIO:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .add_SIO POP BC RET _add_JOY:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) INC HL LD B,(HL) CALL .add_JOY POP BC RET _clock:: ld hl,#.sys_time di ld a,(hl+) ei ;; Interrupts are disabled for the next instruction... ld d,(hl) ld e,a ret __printTStates:: ret ;; Performs a long call. ;; Basically: ;; call banked_call ;; .dw low ;; .dw bank ;; remainder of the code ;; Total m-cycles: ;; 3+4+4 + 2+2+2+2+2+2 + 4+4+ 3+4+1+1+1 ;; = 41 for the call ;; 3+3+4+4+1 ;; = 15 for the ret banked_call:: pop hl ; Get the return address ld a,(__current_bank) push af ; Push the current bank onto the stack ld e,(hl) ; Fetch the call address inc hl ld d,(hl) inc hl ld a,(hl+) ; ...and page inc hl ; Yes this should be here push hl ; Push the real return address ld (__current_bank),a ld (.MBC1_ROM_PAGE),a ; Perform the switch ld hl,#banked_ret ; Push the fake return address push hl ld l,e ld h,d jp (hl) banked_ret:: pop hl ; Get the return address pop af ; Pop the old bank ld (.MBC1_ROM_PAGE),a ld (__current_bank),a jp (hl) .area _HEAP _malloc_heap_start:: ================================================ FILE: libc/delay.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Delay DE milliseconds ;; ;; Entry conditions ;; DE = number of milliseconds to delay (1 to 65536, 0 = 65536) ;; ;; Register used: AF, DE .CPMS = 4194/4 ; 4.194304 MHz .delay:: ; 6 cycles for the CALL PUSH BC ; 4 cycles CALL .dly ; 12 cycles to return from .dly (6+1+5) LD B,#.CPMS/20-2 ; 2 cycles ; ========= ; 24 cycles .ldlp: JR 1$ ; 3 cycles 1$: JR 2$ ; 3 cycles 2$: JR 3$ ; 3 cycles 3$: JR 4$ ; 3 cycles 4$: JR 5$ ; 3 cycles 5$: DEC B ; 1 cycles JP NZ,.ldlp ; 3 cycles (if TRUE: 4 cycles) NOP ; 1 cycles ; ========= ; 20 cycles ;; Exit in 16 cycles POP BC ; 3 cycles JR 6$ ; 3 cycles 6$: JR 7$ ; 3 cycles 7$: JR 8$ ; 3 cycles 8$: RET ; 4 cycles ; ========= ; 16 cycles ;; Delay all but last millisecond .dly: DEC DE ; 2 cycles LD A,E ; 1 cycles OR D ; 1 cycles RET Z ; 2 cycles (upon return: 5 cycles) LD B,#.CPMS/20-1 ; 2 cycles ; ========= ; 8 cycles .dlp: JR 1$ ; 3 cycles 1$: JR 2$ ; 3 cycles 2$: JR 3$ ; 3 cycles 3$: JR 4$ ; 3 cycles 4$: JR 5$ ; 3 cycles 5$: DEC B ; 1 cycles JP NZ,.dlp ; 3 cycles (if TRUE: 4 cycles) NOP ; 1 cycles ; ========= ; 20 cycles ;; Exit in 15 cycles JR 6$ ; 3 cycles 6$: JR 7$ ; 3 cycles 7$: JR 8$ ; 3 cycles 8$: JR .dly ; 3 cycles ; ========= ; 12 cycles _delay:: LDA HL,2(SP) ; Skip return address LD E,(HL) ; DE = delay INC HL LD D,(HL) CALL .delay RET ================================================ FILE: libc/digits.c ================================================ #pragma bank=BASE const char * const digits = "0123456789ABCDEF"; ================================================ FILE: libc/drawing.s ================================================ ;; Optimised Drawing library ;; By Jon Fuge (jonny@q-continuum.demon.co.uk) based on original file ;; Updates ;; 990223 Michael Removed mod_col, splitting it up into ;; fg_colour, bg_colour, and draw_mode ;; Note: some optimisations are available with unneded PUSH DE/POP DE's ;; BANKED: checked .include "global.s" .globl .init_vram .globl .copy_vram .M_SOLID = 0x00 .M_OR = 0x01 .M_XOR = 0x02 .M_AND = 0x03 .if 0 .M_SOLID = 0x10 .M_OR = 0x20 .M_XOR = 0x40 .M_AND = 0x80 .endif ;; Format of mod_col ;; 7 6 5 4 3 2 1 0 ;; mode fg bg .area _HEADER (ABS) .org .MODE_TABLE+4*.G_MODE JP .gmode .module Drawing1 ;; Data .area _BSS ;; Foreground drawing colour .fg_colour:: .ds 1 ;; Background drawing colour .bg_colour:: .ds 1 ;; Drawing mode (.SOILD etc) .draw_mode: .ds 1 ;; Fill style .style: .ds 0x01 ;; Various varibles .x_s: .ds 2 .y_s: .ds 2 .delta_x: .ds 1 .delta_y: .ds 1 .l_inc: .ds 1 .l_d: .ds 2 .dinc1: .ds 2 .dinc2: .ds 2 .tx: .ds 1 .ty: .ds 1 .area _BASE ;; Enter graphic mode .gmode:: DI ; Disable interrupts ;; Turn the screen off LDH A,(.LCDC) BIT 7,A JR Z,1$ ;; Turn the screen off CALL .display_off 1$: LD HL,#0x8000+0x10*0x10 LD DE,#0x1800-0x18*0x10 LD B,#0x00 CALL .init_vram ; Init the charset at 0x8000 ;; Install interrupt routines LD BC,#.vbl CALL .add_VBL LD BC,#.lcd CALL .add_LCD LD A,#72 ; Set line at which LCD interrupt occurs LDH (.LYC),A LD A,#0b01000100 ; Set LCD interrupt to occur when LY = LCY LDH (.STAT),A LDH A,(.IE) OR #0b00000010 ; Enable LCD interrupt LDH (.IE),A ;; (9*20) = 180 tiles are used in the upper part of the screen ;; (9*20) = 180 tiles are used in the lower part of the screen ;; => We have 24 tiles free ;; We keep 16 at 0x8000->0x80FF, and 8 at 0x9780->97FF LD HL,#0x9800 LD A,#0x10 ; Keep 16 tiles free LD BC,#12 ; 12 unused columns LD E,#18 ; 18 lines 2$: LD D,#20 ; 20 used columns 3$: LD (HL+),A INC A DEC D JR NZ,3$ ADD HL,BC DEC E JR NZ,2$ ;; Turn the screen on LDH A,(.LCDC) OR #0b10010001 ; LCD = On ; BG Chr = 0x8000 ; BG = On AND #0b11110111 ; BG Bank = 0x9800 LDH (.LCDC),A LD A,#.G_MODE LD (.mode),A ;; Setup the default colours and draw modes LD A,#.M_SOLID LD (.draw_mode),A LD A,#0x03 ; Black LD (.fg_colour),A LD A,#0x00 ; White LD (.bg_colour),A EI ; Enable interrupts RET .vbl:: LDH A,(.LCDC) OR #0b00010000 ; Set BG Chr to 0x8000 LDH (.LCDC),A LD A,#72 ; Set line at which LCD interrupt occurs LDH (.LYC),A RET ;; Is the STAT check required, as we are already in the HBL? .lcd:: 1$: LDH A,(.STAT) BIT 1,A JR NZ,1$ LDH A,(.LCDC) AND #0b11101111 ; Set BG Chr to 0x8800 LDH (.LCDC),A RET ;; Draw a full-screen image at (BC) .draw_image:: LD HL,#0x8000+0x10*0x10 LD DE,#0x1680 CALL .copy_vram ; Move the charset RET ;; Replace tile data at (B,C) with data at DE and store old value at HL .switch_data:: PUSH DE ; Save src PUSH HL ; Save dst LD L,B SLA L SLA L SLA L LD H,#0x00 ADD HL,HL LD D,H LD E,L LD HL,#.y_table SLA C SLA C SLA C LD B,#0x00 ADD HL,BC ADD HL,BC LD B,(HL) INC HL LD H,(HL) LD L,B ADD HL,DE LD B,H ; BC = src LD C,L POP HL ; HL = dst PUSH BC ; Save dst LD A,H OR L JR Z,1$ LD DE,#0x10 CALL .copy_vram 1$: POP HL ; HL = dst POP BC ; BC = src LD DE,#0x10 CALL .copy_vram RET .area _CODE ;; Advance the cursor .adv_gcurs:: PUSH HL LD HL,#.tx ; X coordinate LD A,#.MAXCURSPOSX CP (HL) JR Z,1$ INC (HL) JR 99$ 1$: LD (HL),#0x00 LD HL,#.ty ; Y coordinate LD A,#.MAXCURSPOSY CP (HL) JR Z,2$ INC (HL) JR 99$ 2$: LD (HL),#0x00 99$: POP HL RET ;; Draw a circle from (B,C) with radius D .circle:: LD A,B ;Store center values LD (.x_s),A LD A,C LD (.y_s),A XOR A LD (.x_s+1),A LD A,D LD (.y_s+1),A CPL LD L,A LD H,#0xFF INC HL LD BC,#0 ADD HL,BC LD A,L LD (.l_d+1),A LD A,H LD (.l_d),A cloop$: LD A,(.x_s+1) LD B,A LD A,(.y_s+1) SUB B RET C LD A,(.style) OR A CALL Z,.circplot LD A,(.l_d) BIT 7,A JR Z,ycirc$ LD A,(.style) OR A CALL NZ,.horlin LD A,(.x_s+1) INC A LD (.x_s+1),A LD A,(.l_d) LD B,A LD A,(.l_d+1) LD C,A LD H,#0 LD A,(.x_s+1) LD L,A ADD HL,HL ADD HL,HL ADD HL,BC LD BC,#6 ADD HL,BC LD A,H LD (.l_d),A LD A,L LD (.l_d+1),A JR cloop$ ycirc$: LD A,(.style) OR A CALL NZ,.verlin LD A,(.x_s+1) INC A LD (.x_s+1),A LD B,#0 LD A,(.x_s+1) LD C,A LD H,#0xFF LD A,(.y_s+1) CPL LD L,A INC HL ADD HL,BC LD A,(.l_d) LD B,A LD A,(.l_d+1) LD C,A ADD HL,HL ADD HL,HL ADD HL,BC LD BC,#10 ADD HL,BC LD A,H LD (.l_d),A LD A,L LD (.l_d+1),A LD A,(.y_s+1) DEC A LD (.y_s+1),A JP cloop$ .horlin:: LD A,(.x_s) LD B,A LD A,(.y_s) LD C,A LD A,(.x_s+1) LD D,A LD A,(.y_s+1) LD E,A PUSH BC PUSH DE LD A,B SUB E LD H,A LD A,B ADD E LD B,A LD A,C ADD D LD C,A LD D,H LD E,C CALL .line POP DE POP BC LD A,D OR A RET Z PUSH BC PUSH DE LD A,B SUB E LD H,A LD A,B ADD E LD B,A LD A,C SUB D LD C,A LD D,H LD E,C CALL .line POP DE POP BC RET .verlin:: LD A,(.x_s) LD B,A LD A,(.y_s) LD C,A LD A,(.x_s+1) LD D,A LD A,(.y_s+1) LD E,A PUSH BC PUSH DE LD A,B SUB E LD H,A LD A,B ADD E LD B,A LD A,C ADD D LD C,A LD D,H LD E,C CALL .line POP DE POP BC PUSH BC PUSH DE LD A,B SUB E LD H,A LD A,B ADD E LD B,A LD A,C SUB D LD C,A LD D,H LD E,C CALL .line POP DE POP BC LD A,D SUB E RET Z PUSH BC PUSH DE LD A,B SUB D LD H,A LD A,B ADD D LD B,A LD A,C SUB E LD C,A LD D,H LD E,C CALL .line POP DE POP BC PUSH BC PUSH DE LD A,B SUB D LD H,A LD A,B ADD D LD B,A LD A,C ADD E LD C,A LD D,H LD E,C CALL .line POP DE POP BC RET .circplot:: LD A,(.x_s) LD B,A LD A,(.y_s) LD C,A LD A,(.x_s+1) LD D,A LD A,(.y_s+1) LD E,A PUSH BC PUSH DE LD A,B ADD D LD B,A LD A,C SUB E LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B SUB E LD B,A LD A,C SUB D LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B SUB D LD B,A LD A,C ADD E LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B ADD E LD B,A LD A,C ADD D LD C,A CALL .plot POP DE POP BC LD A,D OR A RET Z SUB E RET Z PUSH BC PUSH DE LD A,B SUB D LD B,A LD A,C SUB E LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B SUB E LD B,A LD A,C ADD D LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B ADD D LD B,A LD A,C ADD E LD C,A CALL .plot POP DE POP BC PUSH BC PUSH DE LD A,B ADD E LD B,A LD A,C SUB D LD C,A CALL .plot POP DE POP BC RET ;; Draw a box between (B,C) and (D,E) .box:: LD A,(.x_s) LD B,A LD A,(.x_s+1) LD C,A SUB B JR NC,ychk$ LD A,C LD (.x_s),A LD A,B LD (.x_s+1),A ychk$: LD A,(.y_s) LD B,A LD A,(.y_s+1) LD C,A SUB B JR NC,dbox$ LD A,C LD (.y_s),A LD A,B LD (.y_s+1),A dbox$: LD A,(.x_s) LD B,A LD D,A LD A,(.y_s) LD C,A LD A,(.y_s+1) LD E,A CALL .line LD A,(.x_s+1) LD B,A LD D,A LD A,(.y_s) LD C,A LD A,(.y_s+1) LD E,A CALL .line LD A,(.x_s) INC A LD (.x_s),A LD A,(.x_s+1) DEC A LD (.x_s+1),A LD A,(.x_s) LD B,A LD A,(.x_s+1) LD D,A LD A,(.y_s) LD C,A LD E,A CALL .line LD A,(.x_s) LD B,A LD A,(.x_s+1) LD D,A LD A,(.y_s+1) LD C,A LD E,A CALL .line LD A,(.style) OR A RET Z LD A,(.x_s) LD B,A LD A,(.x_s+1) SUB B RET C LD A,(.y_s) INC A LD (.y_s),A LD A,(.y_s+1) DEC A LD (.y_s+1),A LD A,(.y_s) LD B,A LD A,(.y_s+1) SUB B RET C .if 0 LD A,(.mod_col) ;Swap fore + back colours. LD D,A AND #0xF0 LD C,A ;Preserve Style LD A,D AND #0x0C RRCA RRCA OR C ;Foreground->background + style LD C,A LD A,D AND #0x03 RLCA RLCA OR C LD (.mod_col),A .else LD A,(.fg_colour) LD C,A LD A,(.bg_colour) LD (.fg_colour),A LD A,C LD (.bg_colour),A .endif filllp$: LD A,(.x_s) LD B,A LD A,(.x_s+1) LD D,A LD A,(.y_s) LD C,A LD E,A CALL .line LD A,(.y_s+1) LD B,A LD A,(.y_s) CP B JR Z,swap$ INC A LD (.y_s),A JR filllp$ swap$: .if 0 LD A,(.mod_col) ;Swap fore + back colours. LD D,A AND #0xF0 LD C,A ;Preserve Style LD A,D AND #0x0C RRCA RRCA OR C ;Foreground->background + style LD C,A LD A,D AND #0x03 RLCA RLCA OR C LD (.mod_col),A .else LD A,(.fg_colour) LD C,A LD A,(.bg_colour) LD (.fg_colour),A LD A,C LD (.bg_colour),A .endif RET ;; Draw a line between (B,C) and (D,E) .line:: LD A,C ;Calculate Delta Y SUB E JR NC,s1$ CPL INC A s1$: LD (.delta_y),A LD H,A LD A,B ;Calculate Delta X SUB D JR NC,s2$ CPL INC A s2$: LD (.delta_x),A SUB H JP C,y1 ;; Use Delta X LD A,B SUB D JP NC,x2$ LD A,C SUB E JR Z,x3$ LD A,#0x00 JR NC,x3$ LD A,#0xFF JR x3$ x2$: LD A,E SUB C JR Z,x2a$ LD A,#0x00 JR NC,x2a$ LD A,#0xFF x2a$: LD B,D LD C,E ;BC holds start X,Y x3$: LD (.l_inc),A ;Store Y increment LD HL,#.y_table LD D,#0x00 LD E,C ADD HL,DE ADD HL,DE LD A,(HL+) LD H,(HL) LD L,A LD A,B AND #0xf8 LD E,A ADD HL,DE ADD HL,DE LD A,(.delta_y) OR A JP Z,.xonly ;; Got to do it the hard way. ; Calculate (2*deltay) -> dinc1 PUSH HL LD H,#0x00 LD L,A ADD HL,HL LD A,H LD (.dinc1),A LD A,L LD (.dinc1+1),A ; Calculate (2*deltay)-deltax -> d LD D,H LD E,L LD A,(.delta_x) CPL LD L,A LD H,#0xFF INC HL dx1$: ADD HL,DE LD A,H LD (.l_d),A LD A,L LD (.l_d+1),A ; Calculate (deltay-deltax)*2 -> dinc2 LD A,(.delta_x) CPL LD L,A LD H,#0xFF INC HL LD A,(.delta_y) LD D,#0x00 LD E,A ADD HL,DE ADD HL,HL LD A,H LD (.dinc2),A LD A,L LD (.dinc2+1),A POP HL .if 0 LD A,(.mod_col) LD D,A .endif LD A,(.delta_x) LD E,A LD A,B AND #7 ADD #0x10 ; Table of bits is located at 0x0010 LD C,A LD B,#0x00 LD A,(BC) ; Get start bit LD B,A LD C,A xloop$: RRC C LD A,(.l_d) BIT 7,A JR Z,ychg$ PUSH DE BIT 7,C JR Z,nbit$ LD A,B CPL LD C,A CALL .wrbyte DEC HL LD C,#0x80 LD B,C nbit$: LD A,(.l_d+1) LD D,A LD A,(.dinc1+1) ADD D LD (.l_d+1),A LD A,(.l_d) LD D,A LD A,(.dinc1) ADC D LD (.l_d),A POP DE JR nchg$ ychg$: PUSH DE PUSH BC LD A,B CPL LD C,A CALL .wrbyte LD A,(.l_inc) OR A JR Z,ydown$ INC HL LD A,L AND #0x0F JR NZ,bound$ LD DE,#0x0130 ADD HL,DE ;Correct screen address JR bound$ ydown$: DEC HL DEC HL DEC HL LD A,L AND #0x0F XOR #0x0E JR NZ,bound$ LD DE,#0xFED0 ADD HL,DE ;Correct screen address bound$: LD A,(.l_d+1) LD D,A LD A,(.dinc2+1) ADD D LD (.l_d+1),A LD A,(.l_d) LD D,A LD A,(.dinc2) ADC D LD (.l_d),A POP BC LD B,C POP DE nchg$: BIT 7,C JR Z,nadj$ PUSH DE LD DE,#0x0010 ADD HL,DE ;Correct screen address POP DE LD B,C nadj$: LD A,B OR C LD B,A DEC E JP NZ,xloop$ LD A,B CPL LD C,A JP .wrbyte .xonly:: ;; Draw accelerated horizontal line .if 0 ;; xxx needed? LD A,(.mod_col) LD D,A .endif LD A,(.delta_x) LD E,A INC E LD A,B ;check X AND #7 ;just look at bottom 3 bits JR Z,2$ PUSH HL ADD #0x10 ;Table of bits is located at 0x0010 LD L,A LD H,#0x00 LD C,(HL) POP HL XOR A ;Clear A 1$: RRCA ;Shift data right 1 OR C DEC E JR Z,3$ BIT 0,A JR Z,1$ JR 3$ 2$: LD A,E DEC A AND #0xF8 JR Z,4$ JR 8$ 3$: LD B,A CPL LD C,A PUSH DE CALL .wrbyte LD DE,#0x0F ADD HL,DE ;Correct screen address POP DE 8$: LD A,E OR A RET Z AND #0xF8 JR Z,4$ XOR A LD C,A CPL LD B,A PUSH DE CALL .wrbyte LD DE,#0x0F ADD HL,DE ;Correct screen address POP DE LD A,E SUB #8 RET Z LD E,A JR 8$ 4$: LD A,#0x80 5$: DEC E JR Z,6$ SRA A JR 5$ 6$: LD B,A CPL LD C,A JP .wrbyte ;; Use Delta Y y1: LD A,C SUB E JP NC,y2$ LD A,B SUB D JR Z,y3$ LD A,#0x00 JR NC,y3$ LD A,#0xFF JR y3$ y2$: LD A,C SUB E JR Z,y2a$ LD A,#0x00 JR NC,y2a$ LD A,#0xFF y2a$: LD B,D LD C,E ;BC holds start X,Y y3$: LD (.l_inc),A ;Store X increment LD HL,#.y_table LD D,#0x00 LD E,C ADD HL,DE ADD HL,DE LD A,(HL+) LD H,(HL) LD L,A LD A,B AND #0xf8 LD E,A ADD HL,DE ADD HL,DE .if 0 ;; Trashed by later instructions LD A,(.mod_col) LD D,A .endif LD A,(.delta_y) LD E,A INC E LD A,(.delta_x) OR A JP Z,.yonly ;; Got to do it the hard way. ; Calculate (2*deltax) -> dinc1 PUSH HL LD H,#0x00 LD L,A ADD HL,HL LD A,H LD (.dinc1),A LD A,L LD (.dinc1+1),A ; Calculate (2*deltax)-deltay -> d LD D,H LD E,L LD A,(.delta_y) CPL LD L,A LD H,#0xFF INC HL dy1$: ADD HL,DE LD A,H LD (.l_d),A LD A,L LD (.l_d+1),A ; Calculate (deltax-deltay)*2 -> dinc2 LD A,(.delta_y) CPL LD L,A LD H,#0xFF INC HL LD A,(.delta_x) LD D,#0x00 LD E,A ADD HL,DE ADD HL,HL LD A,H LD (.dinc2),A LD A,L LD (.dinc2+1),A POP HL .if 0 ;; xxx Not used? LD A,(.mod_col) LD D,A .endif LD A,(.delta_y) LD E,A LD A,B AND #7 ADD #0x10 ; Table of bits is located at 0x0010 LD C,A LD B,#0x00 LD A,(BC) ; Get start bit LD B,A LD C,A yloop$: PUSH DE PUSH BC LD A,B CPL LD C,A CALL .wrbyte INC HL LD A,L AND #0x0F JR NZ,nybound$ LD DE,#0x0130 ADD HL,DE ;Correct screen address nybound$: POP BC LD A,(.l_d) BIT 7,A JR Z,xchg$ LD A,(.l_d+1) LD D,A LD A,(.dinc1+1) ADD D LD (.l_d+1),A LD A,(.l_d) LD D,A LD A,(.dinc1) ADC D LD (.l_d),A JR nchgy$ xchg$: LD A,(.l_inc) OR A JR NZ,yright$ RLC B BIT 0,B JR Z,boundy$ LD DE,#0xFFF0 ADD HL,DE ;Correct screen address JR boundy$ yright$: RRC B BIT 7,B JR Z,boundy$ LD DE,#0x0010 ADD HL,DE ;Correct screen address boundy$: LD A,(.l_d+1) LD D,A LD A,(.dinc2+1) ADD D LD (.l_d+1),A LD A,(.l_d) LD D,A LD A,(.dinc2) ADC D LD (.l_d),A nchgy$: POP DE DEC E JR NZ,yloop$ LD A,B CPL LD C,A JP .wrbyte .yonly:: ;; Draw accelerated vertical line LD A,B ;check X AND #7 ;just look at bottom 3 bits PUSH HL ADD #0x10 ;Table of bits is located at 0x0010 LD L,A LD H,#0x00 LD A,(HL) ;Get mask bit POP HL LD B,A CPL LD C,A 1$: PUSH DE CALL .wrbyte INC HL ;Correct screen address LD A,L AND #0x0F JR NZ,2$ LD DE,#0x0130 ADD HL,DE 2$: POP DE DEC E RET Z JR 1$ ;; Draw a point at (B,C) with mode and color D .plot:: LD HL,#.y_table LD D,#0x00 LD E,C ADD HL,DE ADD HL,DE LD A,(HL+) LD H,(HL) LD L,A LD A,B AND #0xf8 LD E,A ADD HL,DE ADD HL,DE LD A,B AND #7 ADD #0x10 ; Table of bits is located at 0x0010 LD C,A LD B,#0x00 LD A,(BC) LD B,A CPL LD C,A .wrbyte:: .if 0 LD A,(.mod_col) ; Restore color and mode LD D,A BIT 5,D JR NZ,10$ BIT 6,D JR NZ,20$ BIT 7,D JR NZ,30$ .else LD A,(.fg_colour) LD D,A LD A,(.draw_mode) CP #.M_OR JR Z,10$ CP #.M_XOR JR Z,20$ CP #.M_AND JR Z,30$ .endif ; Fall through to SOLID by default 1$: ;; Solid LD E,B .if 0 BIT 2,D .else BIT 0,D .endif JR NZ,2$ PUSH BC LD B,#0x00 2$: .if 0 BIT 3,D .else BIT 1,D .endif JR NZ,3$ LD E,#0x00 3$: LDH A,(.STAT) BIT 1,A JR NZ,3$ LD A,(HL) AND C OR B LD (HL+),A LD A,(HL) AND C OR E LD (HL),A LD A,B OR A RET NZ POP BC RET 10$: ;; Or LD C,B .if 0 BIT 2,D .else BIT 0,D .endif JR NZ,11$ LD B,#0x00 11$: .if 0 BIT 3,D .else BIT 1,D .endif JR NZ,12$ LD C,#0x00 12$: LDH A,(.STAT) BIT 1,A JR NZ,12$ LD A,(HL) OR B LD (HL+),A LD A,(HL) OR C LD (HL),A RET 20$: ;; Xor LD C,B .if 0 BIT 2,D .else BIT 0,D .endif JR NZ,21$ LD B,#0x00 21$: .if 0 BIT 3,D .else BIT 1,D .endif JR NZ,22$ LD C,#0x00 22$: LDH A,(.STAT) BIT 1,A JR NZ,22$ LD A,(HL) XOR B LD (HL+),A LD A,(HL) XOR C LD (HL),A RET 30$: ;; And LD B,C .if 0 BIT 2,D .else BIT 0,D .endif JR Z,31$ LD B,#0xFF 31$: .if 0 BIT 3,D .else BIT 1,D .endif JR Z,32$ LD C,#0xFF 32$: LDH A,(.STAT) BIT 1,A JR NZ,32$ LD A,(HL) AND B LD (HL+),A LD A,(HL) AND C LD (HL),A RET ;; Get color of pixel at point (B,C) returns in A .getpix:: LD HL,#.y_table LD D,#0x00 LD E,C ADD HL,DE ADD HL,DE LD A,(HL+) LD H,(HL) LD L,A LD A,B AND #0xf8 LD E,A ADD HL,DE ADD HL,DE LD A,B AND #7 ADD #0x10 ; Table of bits is located at 0x0010 LD C,A LD B,#0x00 LD A,(BC) LD C,A gp$: LDH A,(.STAT) BIT 1,A JR NZ,gp$ LD A,(HL+) LD D,A LD A,(HL+) LD E,A LD B,#0 LD A,D AND C JR Z,npix$ SET 0,B npix$: LD A,E AND C JR Z,end$ SET 1,B end$: LD E,B RET ;; Write character C .wrtchr:: LD HL,#.y_table LD D,#0x00 LD A,(.ty) RLCA RLCA RLCA LD E,A ADD HL,DE ADD HL,DE LD B,(HL) INC HL LD H,(HL) LD L,B LD A,(.tx) RLCA RLCA RLCA LD E,A ADD HL,DE ADD HL,DE LD A,C LD B,H LD C,L LD H,D LD L,A ADD HL,HL ADD HL,HL ADD HL,HL .if 0 LD DE,#.tp1 .else .globl _font_ibm_fixed_tiles LD DE,#_font_ibm_fixed_tiles .endif ADD HL,DE LD D,H LD E,L LD H,B LD L,C .if 0 LD A,(.mod_col) LD C,A .else LD A,(.fg_colour) LD C,A .endif chrloop$: LD A,(DE) INC DE PUSH DE .if 1 PUSH HL LD HL,#.bg_colour LD L,(HL) .endif LD B,A XOR A .if 0 BIT 0,C .else BIT 0,L .endif JR Z,a0$ CPL a0$: OR B .if 0 BIT 2,C .else BIT 0,C .endif JR NZ,a1$ XOR B a1$: LD D,A XOR A .if 0 BIT 1,C .else BIT 1,L .endif JR Z,b0$ CPL b0$: OR B .if 0 BIT 3,C .else BIT 1,C .endif JR NZ,b1$ XOR B b1$: LD E,A .if 1 POP HL .endif chrwait$: LDH A,(.STAT) BIT 1,A JR NZ,chrwait$ LD A,D LD (HL+),A LD A,E LD (HL+),A POP DE LD A,L AND #0x0F JR NZ,chrloop$ RET .area _CODE _gotogxy:: ; Banked LDA HL,.BANKOV(SP) ; Skip return address LD A,(HL+) ; A = x LD (.tx),A LD A,(HL+) ; A = y LD (.ty),A RET _wrtchr:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL) LD C,A ; C = Char to print CALL .wrtchr CALL .adv_gcurs POP BC RET _getpix:: ; Banked PUSH BC LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x LD B,A LD A,(HL+) ; C = y LD C,A CALL .getpix POP BC RET _color:: ; Banked LDA HL,.BANKOV(SP) ; Skip return address and registers LD A,(HL+) ; A = Foreground LD (.fg_colour),a LD A,(HL+) LD (.bg_colour),a LD A,(HL) LD (.draw_mode),a RET _circle:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x LD B,A LD A,(HL+) ; C = y LD C,A LD A,(HL+) ; D = Radius LD D,A LD A,(HL) LD (.style),A CALL .circle POP BC RET _box:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x1 LD (.x_s),A LD A,(HL+) ; C = y1 LD (.y_s),A LD A,(HL+) ; D = x2 LD (.x_s+1),A LD A,(HL+) ; E = y2 LD (.y_s+1),A LD A,(HL) LD (.style),A CALL .box POP BC RET _line:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x1 LD B,A LD A,(HL+) ; C = y1 LD C,A LD A,(HL+) ; D = x2 LD D,A LD A,(HL+) ; E = y2 LD E,A CALL .line POP BC RET _plot_point:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x LD B,A LD A,(HL+) ; C = y LD C,A CALL .plot POP BC RET ;; Old, compatible version of plot() _plot:: ; Banked PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,.BANKOV+2(SP) ; Skip return address and registers LD A,(HL+) ; B = x LD B,A LD A,(HL+) ; C = y LD C,A LD A,(HL+) ; colour LD (.fg_colour),A LD A,(HL+) ; mode LD (.draw_mode),A CALL .plot POP BC RET .area _BASE _switch_data:: ; Non Banked as pointer PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,4(SP) ; Skip return address and registers LD A,(HL+) ; B = x LD B,A LD A,(HL+) ; C = y LD C,A LD A,(HL+) ; DE = src LD E,A LD A,(HL+) LD D,A LD A,(HL+) ; HL = dst LD H,(HL) LD L,A CALL .switch_data POP BC RET _draw_image:: ; Non banked as pointer PUSH BC LD A,(.mode) CP #.G_MODE CALL NZ,.gmode LDA HL,4(SP) ; Skip return address and registers LD A,(HL+) ; HL = data LD C,A LD B,(HL) CALL .draw_image POP BC RET .area _BASE .y_table:: .word 0x8100,0x8102,0x8104,0x8106,0x8108,0x810A,0x810C,0x810E .word 0x8240,0x8242,0x8244,0x8246,0x8248,0x824A,0x824C,0x824E .word 0x8380,0x8382,0x8384,0x8386,0x8388,0x838A,0x838C,0x838E .word 0x84C0,0x84C2,0x84C4,0x84C6,0x84C8,0x84CA,0x84CC,0x84CE .word 0x8600,0x8602,0x8604,0x8606,0x8608,0x860A,0x860C,0x860E .word 0x8740,0x8742,0x8744,0x8746,0x8748,0x874A,0x874C,0x874E .word 0x8880,0x8882,0x8884,0x8886,0x8888,0x888A,0x888C,0x888E .word 0x89C0,0x89C2,0x89C4,0x89C6,0x89C8,0x89CA,0x89CC,0x89CE .word 0x8B00,0x8B02,0x8B04,0x8B06,0x8B08,0x8B0A,0x8B0C,0x8B0E .word 0x8C40,0x8C42,0x8C44,0x8C46,0x8C48,0x8C4A,0x8C4C,0x8C4E .word 0x8D80,0x8D82,0x8D84,0x8D86,0x8D88,0x8D8A,0x8D8C,0x8D8E .word 0x8EC0,0x8EC2,0x8EC4,0x8EC6,0x8EC8,0x8ECA,0x8ECC,0x8ECE .word 0x9000,0x9002,0x9004,0x9006,0x9008,0x900A,0x900C,0x900E .word 0x9140,0x9142,0x9144,0x9146,0x9148,0x914A,0x914C,0x914E .word 0x9280,0x9282,0x9284,0x9286,0x9288,0x928A,0x928C,0x928E .word 0x93C0,0x93C2,0x93C4,0x93C6,0x93C8,0x93CA,0x93CC,0x93CE .word 0x9500,0x9502,0x9504,0x9506,0x9508,0x950A,0x950C,0x950E .word 0x9640,0x9642,0x9644,0x9646,0x9648,0x964A,0x964C,0x964E ================================================ FILE: libc/f_ibm_sh.s ================================================ ; ibm_fixed.ms - fixed width IBM font ;; BANKED: checked, imperfect .area _BASE ; 898 bytes giving ' '-'0'-'@'-'A'-'Z'-'???'-'a'-'z'-127 _font_ibm:: .byte 1+4 ; 128 character encoding .byte 128-32 ; Tiles required .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; All map to space .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ; 0x20 .byte 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 .byte 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47 ; 0x40 .byte 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 .byte 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79 ; 0x60 .byte 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x00 .byte 0x66,0x66,0x44,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x24,0x7E,0x24,0x24,0x7E,0x24,0x00 .byte 0x14,0x3E,0x55,0x3C,0x1E,0x55,0x3E,0x14 .byte 0x62,0x66,0x0C,0x18,0x30,0x66,0x46,0x00 .byte 0x78,0xCC,0x61,0xCE,0xCC,0xCC,0x78,0x00 .byte 0x18,0x18,0x10,0x00,0x00,0x00,0x00,0x00 .byte 0x04,0x08,0x18,0x18,0x18,0x18,0x08,0x04 .byte 0x20,0x10,0x18,0x18,0x18,0x18,0x10,0x20 .byte 0x00,0x54,0x38,0xFE,0x38,0x54,0x00,0x00 .byte 0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20 .byte 0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 .byte 0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00 .byte 0x3C,0x66,0x6E,0x76,0x66,0x66,0x3C,0x00 .byte 0x18,0x38,0x18,0x18,0x18,0x18,0x18,0x00 .byte 0x3C,0x66,0x0E,0x1C,0x38,0x70,0x7E,0x00 .byte 0x7E,0x0C,0x18,0x3C,0x06,0x46,0x3C,0x00 .byte 0x0C,0x1C,0x2C,0x4C,0x7E,0x0C,0x0C,0x00 .byte 0x7E,0x60,0x7C,0x06,0x06,0x46,0x3C,0x00 .byte 0x1C,0x20,0x60,0x7C,0x66,0x66,0x3C,0x00 .byte 0x7E,0x06,0x0E,0x1C,0x18,0x18,0x18,0x00 .byte 0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00 .byte 0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00 .byte 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00 .byte 0x00,0x18,0x18,0x00,0x18,0x18,0x10,0x00 .byte 0x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00 .byte 0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00 .byte 0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00 .byte 0x3C,0x46,0x06,0x0C,0x18,0x18,0x00,0x18 .byte 0x3C,0x66,0x6E,0x6A,0x6E,0x60,0x3C,0x00 .byte 0x3C,0x66,0x66,0x7E,0x66,0x66,0x66,0x00 .byte 0x7C,0x66,0x66,0x7C,0x66,0x66,0x7C,0x00 .byte 0x3C,0x62,0x60,0x60,0x60,0x62,0x3C,0x00 .byte 0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00 .byte 0x7E,0x60,0x60,0x7C,0x60,0x60,0x7E,0x00 .byte 0x7E,0x60,0x60,0x7C,0x60,0x60,0x60,0x00 .byte 0x3C,0x62,0x60,0x6E,0x66,0x66,0x3E,0x00 .byte 0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00 .byte 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00 .byte 0x06,0x06,0x06,0x06,0x06,0x46,0x3C,0x00 .byte 0x66,0x6C,0x78,0x70,0x78,0x6C,0x66,0x00 .byte 0x60,0x60,0x60,0x60,0x60,0x60,0x7C,0x00 .byte 0xFC,0xD6,0xD6,0xD6,0xD6,0xC6,0xC6,0x00 .byte 0x62,0x72,0x7A,0x5E,0x4E,0x46,0x42,0x00 .byte 0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00 .byte 0x7C,0x66,0x66,0x7C,0x60,0x60,0x60,0x00 .byte 0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x06 .byte 0x7C,0x66,0x66,0x7C,0x66,0x66,0x66,0x00 .byte 0x3C,0x62,0x70,0x3C,0x0E,0x46,0x3C,0x00 .byte 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00 .byte 0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00 .byte 0x66,0x66,0x66,0x66,0x66,0x64,0x78,0x00 .byte 0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFC,0x00 .byte 0x66,0x66,0x66,0x3C,0x66,0x66,0x66,0x00 .byte 0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00 .byte 0x7E,0x0E,0x1C,0x38,0x70,0x60,0x7E,0x00 .byte 0x1E,0x18,0x18,0x18,0x18,0x18,0x1E,0x00 .byte 0x40,0x60,0x30,0x18,0x0C,0x06,0x02,0x00 .byte 0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00 .byte 0x10,0x38,0x6C,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00 .byte 0x00,0xC0,0xC0,0x60,0x00,0x00,0x00,0x00 .byte 0x00,0x3C,0x46,0x3E,0x66,0x66,0x3E,0x00 .byte 0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00 .byte 0x00,0x3C,0x62,0x60,0x60,0x62,0x3C,0x00 .byte 0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00 .byte 0x00,0x3C,0x66,0x7E,0x60,0x62,0x3C,0x00 .byte 0x1E,0x30,0x7C,0x30,0x30,0x30,0x30,0x00 .byte 0x00,0x3E,0x66,0x66,0x66,0x3E,0x46,0x3C .byte 0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x00 .byte 0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00 .byte 0x00,0x08,0x18,0x18,0x18,0x18,0x58,0x30 .byte 0x60,0x64,0x68,0x70,0x78,0x6C,0x66,0x00 .byte 0x18,0x18,0x18,0x18,0x18,0x18,0x0C,0x00 .byte 0x00,0xFC,0xD6,0xD6,0xD6,0xD6,0xC6,0x00 .byte 0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x00 .byte 0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00 .byte 0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60 .byte 0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06 .byte 0x00,0x6C,0x70,0x60,0x60,0x60,0x60,0x00 .byte 0x00,0x3C,0x72,0x38,0x1C,0x4E,0x3C,0x00 .byte 0x18,0x3C,0x18,0x18,0x18,0x18,0x0C,0x00 .byte 0x00,0x66,0x66,0x66,0x66,0x66,0x3E,0x00 .byte 0x00,0x66,0x66,0x66,0x66,0x64,0x78,0x00 .byte 0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFC,0x00 .byte 0x00,0x66,0x66,0x3C,0x66,0x66,0x66,0x00 .byte 0x00,0x66,0x66,0x66,0x26,0x1E,0x46,0x3C .byte 0x00,0x7E,0x0E,0x1C,0x38,0x70,0x7E,0x00 .byte 0x0E,0x18,0x18,0x30,0x18,0x18,0x0E,0x00 .byte 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 .byte 0x70,0x18,0x18,0x0C,0x18,0x18,0x70,0x00 .byte 0x00,0x60,0xF2,0x9E,0x0C,0x00,0x00,0x00 .byte 0x10,0x10,0x28,0x28,0x44,0x44,0x82,0xFE ================================================ FILE: libc/f_italic.s ================================================ ; font: italic ;; BANKED: checked,imperfect .area _BASE _font_italic:: .db 1+4 ; 128 char encoding, compressed .db 93 ; Number of tiles ; Encoding table .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 .db 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F .db 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 .db 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F .db 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 .db 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F .db 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 .db 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x00 .db 0x00,0x3F,0x40,0x41,0x42,0x43,0x44,0x45 .db 0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D .db 0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55 .db 0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x00 ; Tile data ; Default character (space) .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: ! (21) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00000000 ; .db 0b00100000 ; o ; Character: " (22) .db 0b00000000 ; .db 0b00100100 ; o o .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: # (23) .db 0b00000000 ; .db 0b00100100 ; o o .db 0b01111110 ; oooooo .db 0b00100100 ; o o .db 0b00100100 ; o o .db 0b01111110 ; oooooo .db 0b00100100 ; o o .db 0b00000000 ; ; Character: $ (24) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00111110 ; ooooo .db 0b00101000 ; o o .db 0b00111110 ; ooooo .db 0b00001010 ; o o .db 0b00111110 ; ooooo .db 0b00001000 ; o ; Character: % (25) .db 0b00000000 ; .db 0b01100010 ; oo o .db 0b01100100 ; oo o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100110 ; o oo .db 0b01000110 ; o oo .db 0b00000000 ; ; Character: & (26) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00101000 ; o o .db 0b00010000 ; o .db 0b00101010 ; o o o .db 0b01000100 ; o o .db 0b00111010 ; ooo o .db 0b00000000 ; ; Character: ' (27) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ( (28) .db 0b00000000 ; .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00000100 ; o .db 0b00000000 ; ; Character: ) (29) .db 0b00000000 ; .db 0b00100000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00000000 ; ; Character: * (2A) .db 0b00000000 ; .db 0b00000000 ; .db 0b00100100 ; o o .db 0b00011000 ; oo .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00100100 ; o o .db 0b00000000 ; ; Character: + (2B) .db 0b00000000 ; .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00111110 ; ooooo .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00000000 ; ; Character: , (2C) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00010000 ; o ; Character: - (2D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: . (2E) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: / (2F) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000010 ; o .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00000000 ; ; Character: 0 (30) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100110 ; o oo .db 0b01001010 ; o o o .db 0b01010100 ; o o o .db 0b10100100 ; o o o .db 0b11001000 ; oo o .db 0b01110000 ; ooo ; Character: 1 (31) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00101000 ; o o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o .db 0b11111000 ; ooooo ; Character: 2 (32) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b00000100 ; o .db 0b00011000 ; oo .db 0b01100000 ; oo .db 0b10000000 ; o .db 0b11111100 ; oooooo ; Character: 3 (33) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b00000010 ; o .db 0b00001100 ; oo .db 0b00000010 ; o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: 4 (34) .db 0b00000000 ; .db 0b00001100 ; oo .db 0b00110100 ; oo o .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b11111110 ; ooooooo .db 0b00010000 ; o .db 0b00010000 ; o ; Character: 5 (35) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01111000 ; oooo .db 0b00000100 ; o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: 6 (36) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01000000 ; o .db 0b01111000 ; oooo .db 0b10000100 ; o o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: 7 (37) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000010 ; o .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o ; Character: 8 (38) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b10000100 ; o o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: 9 (39) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b01000010 ; o o .db 0b00111100 ; oooo .db 0b00000100 ; o .db 0b00001000 ; o .db 0b11110000 ; oooo ; Character: : (3A) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00001000 ; o .db 0b00000000 ; .db 0b00000000 ; .db 0b00010000 ; o .db 0b00000000 ; ; Character: ; (3B) .db 0b00000000 ; .db 0b00000000 ; .db 0b00010000 ; o .db 0b00000000 ; .db 0b00000000 ; .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o ; Character: < (3C) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00001000 ; o .db 0b00000100 ; o .db 0b00000000 ; ; Character: = (3D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: > (3E) .db 0b00000000 ; .db 0b00000000 ; .db 0b00010000 ; o .db 0b00001000 ; o .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00000000 ; ; Character: ? (3F) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b00000010 ; o .db 0b00001100 ; oo .db 0b00010000 ; o .db 0b00000000 ; .db 0b00110000 ; oo ; Character: @ (40) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01001010 ; o o o .db 0b01010110 ; o o oo .db 0b01011110 ; o oooo .db 0b01000000 ; o .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: A (41) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01111100 ; ooooo .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b10001000 ; o o ; Character: B (42) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b01000010 ; o o .db 0b10000100 ; o o .db 0b11111000 ; ooooo ; Character: C (43) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01000000 ; o .db 0b01000000 ; o .db 0b10000000 ; o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: D (44) .db 0b00000000 ; .db 0b00111000 ; ooo .db 0b00100100 ; o o .db 0b00100010 ; o o .db 0b01000010 ; o o .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b11110000 ; oooo ; Character: E (45) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01111000 ; oooo .db 0b01000000 ; o .db 0b10000000 ; o .db 0b11111000 ; ooooo ; Character: F (46) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01111000 ; oooo .db 0b01000000 ; o .db 0b10000000 ; o .db 0b10000000 ; o ; Character: G (47) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01000000 ; o .db 0b01000000 ; o .db 0b10001110 ; o ooo .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: H (48) .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01111100 ; ooooo .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b10001000 ; o o ; Character: I (49) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o .db 0b11111000 ; ooooo ; Character: J (4A) .db 0b00000000 ; .db 0b00000010 ; o .db 0b00000010 ; o .db 0b00000100 ; o .db 0b00000100 ; o .db 0b10001000 ; o o .db 0b10001000 ; o o .db 0b01110000 ; ooo ; Character: K (4B) .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100100 ; o o .db 0b01001000 ; o o .db 0b01110000 ; ooo .db 0b01001000 ; o o .db 0b10001000 ; o o .db 0b10000100 ; o o ; Character: L (4C) .db 0b00000000 ; .db 0b00100000 ; o .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01000000 ; o .db 0b01000000 ; o .db 0b10000000 ; o .db 0b11111100 ; oooooo ; Character: M (4D) .db 0b00000000 ; .db 0b00110110 ; oo oo .db 0b00101010 ; o o o .db 0b01010100 ; o o o .db 0b01010100 ; o o o .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b10001000 ; o o ; Character: N (4E) .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00110010 ; oo o .db 0b01010100 ; o o o .db 0b01010100 ; o o o .db 0b01010100 ; o o o .db 0b10011000 ; o oo .db 0b10001000 ; o o ; Character: O (4F) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01000010 ; o o .db 0b01000100 ; o o .db 0b10000100 ; o o .db 0b10001000 ; o o .db 0b01110000 ; ooo ; Character: P (50) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b01000010 ; o o .db 0b01111100 ; ooooo .db 0b01000000 ; o .db 0b10000000 ; o .db 0b10000000 ; o ; Character: Q (51) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01000010 ; o o .db 0b01000100 ; o o .db 0b10010100 ; o o o .db 0b10001000 ; o o .db 0b01110100 ; ooo o ; Character: R (52) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b01000010 ; o o .db 0b01111100 ; ooooo .db 0b01001000 ; o o .db 0b10000100 ; o o .db 0b10000100 ; o o ; Character: S (53) .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00100000 ; o .db 0b00100000 ; o .db 0b00011000 ; oo .db 0b00000100 ; o .db 0b10000100 ; o o .db 0b01111000 ; oooo ; Character: T (54) .db 0b00000000 ; .db 0b11111110 ; ooooooo .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01000000 ; o ; Character: U (55) .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b10001000 ; o o .db 0b01110000 ; ooo ; Character: V (56) .db 0b00000000 ; .db 0b01000010 ; o o .db 0b01000010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o .db 0b10001000 ; o o .db 0b10010000 ; o o .db 0b11100000 ; ooo ; Character: W (57) .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01010100 ; o o o .db 0b10101000 ; o o o .db 0b10101000 ; o o o .db 0b01010000 ; o o ; Character: X (58) .db 0b00000000 ; .db 0b01000010 ; o o .db 0b00100100 ; o o .db 0b00101000 ; o o .db 0b00010000 ; o .db 0b00101000 ; o o .db 0b01001000 ; o o .db 0b10000100 ; o o ; Character: Y (59) .db 0b00000000 ; .db 0b01000010 ; o o .db 0b00100100 ; o o .db 0b00101000 ; o o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o ; Character: Z (5A) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b01000000 ; o .db 0b11111100 ; oooooo ; Character: [ (5B) .db 0b00000000 ; .db 0b00001110 ; ooo .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001110 ; ooo .db 0b00000000 ; ; Character: \ (5C) .db 0b00000000 ; .db 0b00000000 ; .db 0b01000000 ; o .db 0b00100000 ; o .db 0b00010000 ; o .db 0b00001000 ; o .db 0b00000100 ; o .db 0b00000000 ; ; Character: ] (5D) .db 0b00000000 ; .db 0b01110000 ; ooo .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b01110000 ; ooo .db 0b00000000 ; ; Character: ^ (5E) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00111000 ; ooo .db 0b01010100 ; o o o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00000000 ; ; Character: a (61) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00000010 ; o .db 0b00111110 ; ooooo .db 0b01000100 ; o o .db 0b00111100 ; oooo ; Character: b (62) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01111000 ; oooo ; Character: c (63) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01000000 ; o .db 0b00111100 ; oooo ; Character: d (64) .db 0b00000000 ; .db 0b00000010 ; o .db 0b00000010 ; o .db 0b00000100 ; o .db 0b00111100 ; oooo .db 0b01000100 ; o o .db 0b01001000 ; o o .db 0b00111000 ; ooo ; Character: e (65) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b01111100 ; ooooo .db 0b01000000 ; o .db 0b00111000 ; ooo ; Character: f (66) .db 0b00000000 ; .db 0b00001110 ; ooo .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00111000 ; ooo .db 0b00100000 ; o .db 0b01000000 ; o .db 0b01000000 ; o ; Character: g (67) .db 0b00000000 ; .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b00111100 ; oooo .db 0b00000100 ; o .db 0b01111000 ; oooo ; Character: h (68) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o ; Character: i (69) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b01110000 ; ooo ; Character: j (6A) .db 0b00000000 ; .db 0b00000100 ; o .db 0b00000000 ; .db 0b00000100 ; o .db 0b00000100 ; o .db 0b01001000 ; o o .db 0b01001000 ; o o .db 0b00110000 ; oo ; Character: k (6B) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100100 ; o o .db 0b00111000 ; ooo .db 0b01000100 ; o o .db 0b01000100 ; o o ; Character: l (6C) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o .db 0b00011000 ; oo ; Character: m (6D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00110100 ; oo o .db 0b00101010 ; o o o .db 0b00101010 ; o o o .db 0b01010100 ; o o o .db 0b01010100 ; o o o ; Character: n (6E) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o ; Character: o (6F) .db 0b00000000 ; .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o .db 0b00111000 ; ooo ; Character: p (70) .db 0b00000000 ; .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00010010 ; o o .db 0b00100010 ; o o .db 0b00111100 ; oooo .db 0b01000000 ; o .db 0b01000000 ; o ; Character: q (71) .db 0b00000000 ; .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00100010 ; o o .db 0b00100100 ; o o .db 0b00011100 ; ooo .db 0b00001000 ; o .db 0b00001100 ; oo ; Character: r (72) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00001110 ; ooo .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o .db 0b00100000 ; o ; Character: s (73) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00100000 ; o .db 0b00011000 ; oo .db 0b00000100 ; o .db 0b01111000 ; oooo ; Character: t (74) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00011100 ; ooo .db 0b00001000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00100000 ; o ; Character: u (75) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o .db 0b00111000 ; ooo ; Character: v (76) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b01000100 ; o o .db 0b01001000 ; o o .db 0b00110000 ; oo ; Character: w (77) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00101010 ; o o o .db 0b01010100 ; o o o .db 0b01010100 ; o o o .db 0b00101000 ; o o ; Character: x (78) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00100100 ; o o .db 0b00101000 ; o o .db 0b00011000 ; oo .db 0b00100100 ; o o .db 0b01000100 ; o o ; Character: y (79) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00100010 ; o o .db 0b00100010 ; o o .db 0b00011100 ; ooo .db 0b00000100 ; o .db 0b01111000 ; oooo ; Character: z (7A) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000100 ; o .db 0b00011000 ; oo .db 0b00100000 ; o .db 0b01111100 ; ooooo ; Character: { (7B) .db 0b00000000 ; .db 0b00001110 ; ooo .db 0b00001000 ; o .db 0b00110000 ; oo .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001110 ; ooo .db 0b00000000 ; ; Character: | (7C) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00001000 ; o .db 0b00000000 ; ; Character: } (7D) .db 0b00000000 ; .db 0b01110000 ; ooo .db 0b00010000 ; o .db 0b00001100 ; oo .db 0b00010000 ; o .db 0b00010000 ; o .db 0b01110000 ; ooo .db 0b00000000 ; ; Character: ~ (7E) .db 0b00000000 ; .db 0b00010100 ; o o .db 0b00101000 ; o o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ================================================ FILE: libc/f_min.s ================================================ ; font_min.s ; Text font ; Michael Hope, 1998 ; michaelh@earthling.net ; Distrubuted under the Artistic License - see www.opensource.org ; ;; BANKED: checked, imperfect .module font_min .area _BASE _font_min:: .byte 1+4 ; 128 character encoding .byte 37 ; Tiles required .byte 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 ; All map to space .byte 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 ; All map to space .byte 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 ; All map to space .byte 01,02,03,04,05,06,07,08,09,10,00,00,00,00,00,00 .byte 00,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 .byte 26,27,28,29,30,21,32,33,34,35,36,00,00,00,00,00 .byte 00,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 .byte 26,27,28,29,30,21,32,33,34,35,36,00,00,00,00,00 .db 0 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: 0 .db 0b00000000 .db 0b00111100 .db 0b01000110 .db 0b01001010 .db 0b01010010 .db 0b01100010 .db 0b00111100 .db 0b00000000 ; Character: 1 .db 0b00000000 .db 0b00011000 .db 0b00101000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00111110 .db 0b00000000 ; Character: 2 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00000010 .db 0b00111100 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: 3 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00001100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 4 .db 0b00000000 .db 0b00001000 .db 0b00011000 .db 0b00101000 .db 0b01001000 .db 0b01111110 .db 0b00001000 .db 0b00000000 ; Character: 5 .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 6 .db 0b00000000 .db 0b00111100 .db 0b01000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 7 .db 0b00000000 .db 0b01111110 .db 0b00000010 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: 8 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 9 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b00111110 .db 0b00000010 .db 0b00111100 .db 0b00000000 ; Character: A .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01111110 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: B .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b00000000 ; Character: C .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000000 .db 0b01000000 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: D .db 0b00000000 .db 0b01111000 .db 0b01000100 .db 0b01000010 .db 0b01000010 .db 0b01000100 .db 0b01111000 .db 0b00000000 ; Character: E .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: F .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b00000000 ; Character: G .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000000 .db 0b01001110 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: H .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01111110 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: I .db 0b00000000 .db 0b00111110 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00111110 .db 0b00000000 ; Character: J .db 0b00000000 .db 0b00000010 .db 0b00000010 .db 0b00000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: K .db 0b00000000 .db 0b01000100 .db 0b01001000 .db 0b01110000 .db 0b01001000 .db 0b01000100 .db 0b01000010 .db 0b00000000 ; Character: L .db 0b00000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: M .db 0b00000000 .db 0b01000010 .db 0b01100110 .db 0b01011010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: N .db 0b00000000 .db 0b01000010 .db 0b01100010 .db 0b01010010 .db 0b01001010 .db 0b01000110 .db 0b01000010 .db 0b00000000 ; Character: O .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: P .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b00000000 ; Character: Q .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01010010 .db 0b01001010 .db 0b00111100 .db 0b00000000 ; Character: R .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b01000100 .db 0b01000010 .db 0b00000000 ; Character: S .db 0b00000000 .db 0b00111100 .db 0b01000000 .db 0b00111100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: T .db 0b00000000 .db 0b11111110 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: U .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: V .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00100100 .db 0b00011000 .db 0b00000000 ; Character: W .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01011010 .db 0b00100100 .db 0b00000000 ; Character: X .db 0b00000000 .db 0b01000010 .db 0b00100100 .db 0b00011000 .db 0b00011000 .db 0b00100100 .db 0b01000010 .db 0b00000000 ; Character: Y .db 0b00000000 .db 0b10000010 .db 0b01000100 .db 0b00101000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: Z .db 0b00000000 .db 0b01111110 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00100000 .db 0b01111110 .db 0b00000000 ================================================ FILE: libc/f_spect.s ================================================ ; font_spect.ms ; Text font ; Michael Hope, 1998 ; michaelh@earthling.net ; Distrubuted under the Artistic License - see www.opensource.org ; ;; BANKED: checked, imperfect .module font_spect .area _BASE _font_spect:: .byte 1+4 ; 128 character encoding .byte 128-32 ; Tiles required .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; All map to space .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ; 0x20 .byte 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 .byte 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47 ; 0x40 .byte 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 .byte 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79 ; 0x60 .byte 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95 .db 0 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: ! .db 0b00000000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 .db 0b00010000 .db 0b00000000 ; Character: " .db 0b00000000 .db 0b00100100 .db 0b00100100 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: # .db 0b00000000 .db 0b00100100 .db 0b01111110 .db 0b00100100 .db 0b00100100 .db 0b01111110 .db 0b00100100 .db 0b00000000 ; Character: $ .db 0b00000000 .db 0b00001000 .db 0b00111110 .db 0b00101000 .db 0b00111110 .db 0b00001010 .db 0b00111110 .db 0b00001000 ; Character: % .db 0b00000000 .db 0b01100010 .db 0b01100100 .db 0b00001000 .db 0b00010000 .db 0b00100110 .db 0b01000110 .db 0b00000000 ; Character: & .db 0b00000000 .db 0b00010000 .db 0b00101000 .db 0b00010000 .db 0b00101010 .db 0b01000100 .db 0b00111010 .db 0b00000000 ; Character: ' .db 0b00000000 .db 0b00001000 .db 0b00010000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: ( .db 0b00000000 .db 0b00000100 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00000100 .db 0b00000000 ; Character: ) .db 0b00000000 .db 0b00100000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00100000 .db 0b00000000 ; Character: * .db 0b00000000 .db 0b00000000 .db 0b00010100 .db 0b00001000 .db 0b00111110 .db 0b00001000 .db 0b00010100 .db 0b00000000 ; Character: + .db 0b00000000 .db 0b00000000 .db 0b00001000 .db 0b00001000 .db 0b00111110 .db 0b00001000 .db 0b00001000 .db 0b00000000 ; Character: , .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00001000 .db 0b00001000 .db 0b00010000 ; Character: - .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00111110 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: . .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00011000 .db 0b00011000 .db 0b00000000 ; Character: / .db 0b00000000 .db 0b00000000 .db 0b00000010 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00100000 .db 0b00000000 ; Character: 0 .db 0b00000000 .db 0b00111100 .db 0b01000110 .db 0b01001010 .db 0b01010010 .db 0b01100010 .db 0b00111100 .db 0b00000000 ; Character: 1 .db 0b00000000 .db 0b00011000 .db 0b00101000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00111110 .db 0b00000000 ; Character: 2 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00000010 .db 0b00111100 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: 3 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00001100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 4 .db 0b00000000 .db 0b00001000 .db 0b00011000 .db 0b00101000 .db 0b01001000 .db 0b01111110 .db 0b00001000 .db 0b00000000 ; Character: 5 .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 6 .db 0b00000000 .db 0b00111100 .db 0b01000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 7 .db 0b00000000 .db 0b01111110 .db 0b00000010 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: 8 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: 9 .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b00111110 .db 0b00000010 .db 0b00111100 .db 0b00000000 ; Character: : .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00010000 .db 0b00000000 .db 0b00000000 .db 0b00010000 .db 0b00000000 ; Character: ; .db 0b00000000 .db 0b00000000 .db 0b00010000 .db 0b00000000 .db 0b00000000 .db 0b00010000 .db 0b00010000 .db 0b00100000 ; Character: < .db 0b00000000 .db 0b00000000 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00001000 .db 0b00000100 .db 0b00000000 ; Character: = .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00111110 .db 0b00000000 .db 0b00111110 .db 0b00000000 .db 0b00000000 ; Character: > .db 0b00000000 .db 0b00000000 .db 0b00010000 .db 0b00001000 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00000000 ; Character: ? .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b00000100 .db 0b00001000 .db 0b00000000 .db 0b00001000 .db 0b00000000 ; Character: @ .db 0b00000000 .db 0b00111100 .db 0b01001010 .db 0b01010110 .db 0b01011110 .db 0b01000000 .db 0b00111100 .db 0b00000000 ; Character: A .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01111110 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: B .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b00000000 ; Character: C .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000000 .db 0b01000000 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: D .db 0b00000000 .db 0b01111000 .db 0b01000100 .db 0b01000010 .db 0b01000010 .db 0b01000100 .db 0b01111000 .db 0b00000000 ; Character: E .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: F .db 0b00000000 .db 0b01111110 .db 0b01000000 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b00000000 ; Character: G .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000000 .db 0b01001110 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: H .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01111110 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: I .db 0b00000000 .db 0b00111110 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00111110 .db 0b00000000 ; Character: J .db 0b00000000 .db 0b00000010 .db 0b00000010 .db 0b00000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: K .db 0b00000000 .db 0b01000100 .db 0b01001000 .db 0b01110000 .db 0b01001000 .db 0b01000100 .db 0b01000010 .db 0b00000000 ; Character: L .db 0b00000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01000000 .db 0b01111110 .db 0b00000000 ; Character: M .db 0b00000000 .db 0b01000010 .db 0b01100110 .db 0b01011010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00000000 ; Character: N .db 0b00000000 .db 0b01000010 .db 0b01100010 .db 0b01010010 .db 0b01001010 .db 0b01000110 .db 0b01000010 .db 0b00000000 ; Character: O .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: P .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b01000000 .db 0b01000000 .db 0b00000000 ; Character: Q .db 0b00000000 .db 0b00111100 .db 0b01000010 .db 0b01000010 .db 0b01010010 .db 0b01001010 .db 0b00111100 .db 0b00000000 ; Character: R .db 0b00000000 .db 0b01111100 .db 0b01000010 .db 0b01000010 .db 0b01111100 .db 0b01000100 .db 0b01000010 .db 0b00000000 ; Character: S .db 0b00000000 .db 0b00111100 .db 0b01000000 .db 0b00111100 .db 0b00000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: T .db 0b00000000 .db 0b11111110 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: U .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00111100 .db 0b00000000 ; Character: V .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b00100100 .db 0b00011000 .db 0b00000000 ; Character: W .db 0b00000000 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01000010 .db 0b01011010 .db 0b00100100 .db 0b00000000 ; Character: X .db 0b00000000 .db 0b01000010 .db 0b00100100 .db 0b00011000 .db 0b00011000 .db 0b00100100 .db 0b01000010 .db 0b00000000 ; Character: Y .db 0b00000000 .db 0b10000010 .db 0b01000100 .db 0b00101000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: Z .db 0b00000000 .db 0b01111110 .db 0b00000100 .db 0b00001000 .db 0b00010000 .db 0b00100000 .db 0b01111110 .db 0b00000000 ; Character: [ .db 0b00000000 .db 0b00001110 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001110 .db 0b00000000 ; Character: \ .db 0b00000000 .db 0b00000000 .db 0b01000000 .db 0b00100000 .db 0b00010000 .db 0b00001000 .db 0b00000100 .db 0b00000000 ; Character: ] .db 0b00000000 .db 0b01110000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b01110000 .db 0b00000000 ; Character: ^ .db 0b00000000 .db 0b00010000 .db 0b00111000 .db 0b01010100 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: _ .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b11111111 ; Character: Pound .db 0b00000000 .db 0b00011100 .db 0b00100010 .db 0b01111000 .db 0b00100000 .db 0b00100000 .db 0b01111110 .db 0b00000000 ; Character: a .db 0b00000000 .db 0b00000000 .db 0b00111000 .db 0b00000100 .db 0b00111100 .db 0b01000100 .db 0b00111100 .db 0b00000000 ; Character: b .db 0b00000000 .db 0b00100000 .db 0b00100000 .db 0b00111100 .db 0b00100010 .db 0b00100010 .db 0b00111100 .db 0b00000000 ; Character: c .db 0b00000000 .db 0b00000000 .db 0b00011100 .db 0b00100000 .db 0b00100000 .db 0b00100000 .db 0b00011100 .db 0b00000000 ; Character: d .db 0b00000000 .db 0b00000100 .db 0b00000100 .db 0b00111100 .db 0b01000100 .db 0b01000100 .db 0b00111100 .db 0b00000000 ; Character: e .db 0b00000000 .db 0b00000000 .db 0b00111000 .db 0b01000100 .db 0b01111000 .db 0b01000000 .db 0b00111100 .db 0b00000000 ; Character: f .db 0b00000000 .db 0b00001100 .db 0b00010000 .db 0b00011000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00000000 ; Character: g .db 0b00000000 .db 0b00000000 .db 0b00111100 .db 0b01000100 .db 0b01000100 .db 0b00111100 .db 0b00000100 .db 0b00111000 ; Character: h .db 0b00000000 .db 0b01000000 .db 0b01000000 .db 0b01111000 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b00000000 ; Character: i .db 0b00000000 .db 0b00010000 .db 0b00000000 .db 0b00110000 .db 0b00010000 .db 0b00010000 .db 0b00111000 .db 0b00000000 ; Character: j .db 0b00000000 .db 0b00000100 .db 0b00000000 .db 0b00000100 .db 0b00000100 .db 0b00000100 .db 0b00100100 .db 0b00011000 ; Character: k .db 0b00000000 .db 0b00100000 .db 0b00101000 .db 0b00110000 .db 0b00110000 .db 0b00101000 .db 0b00100100 .db 0b00000000 ; Character: l .db 0b00000000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00001100 .db 0b00000000 ; Character: m .db 0b00000000 .db 0b00000000 .db 0b01101000 .db 0b01010100 .db 0b01010100 .db 0b01010100 .db 0b01010100 .db 0b00000000 ; Character: n .db 0b00000000 .db 0b00000000 .db 0b01111000 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b00000000 ; Character: o .db 0b00000000 .db 0b00000000 .db 0b00111000 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b00111000 .db 0b00000000 ; Character: p .db 0b00000000 .db 0b00000000 .db 0b01111000 .db 0b01000100 .db 0b01000100 .db 0b01111000 .db 0b01000000 .db 0b01000000 ; Character: q .db 0b00000000 .db 0b00000000 .db 0b00111100 .db 0b01000100 .db 0b01000100 .db 0b00111100 .db 0b00000100 .db 0b00000110 ; Character: r .db 0b00000000 .db 0b00000000 .db 0b00011100 .db 0b00100000 .db 0b00100000 .db 0b00100000 .db 0b00100000 .db 0b00000000 ; Character: s .db 0b00000000 .db 0b00000000 .db 0b00111000 .db 0b01000000 .db 0b00111000 .db 0b00000100 .db 0b01111000 .db 0b00000000 ; Character: t .db 0b00000000 .db 0b00010000 .db 0b00111000 .db 0b00010000 .db 0b00010000 .db 0b00010000 .db 0b00001100 .db 0b00000000 ; Character: u .db 0b00000000 .db 0b00000000 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b00111000 .db 0b00000000 ; Character: v .db 0b00000000 .db 0b00000000 .db 0b01000100 .db 0b01000100 .db 0b00101000 .db 0b00101000 .db 0b00010000 .db 0b00000000 ; Character: w .db 0b00000000 .db 0b00000000 .db 0b01000100 .db 0b01010100 .db 0b01010100 .db 0b01010100 .db 0b00101000 .db 0b00000000 ; Character: x .db 0b00000000 .db 0b00000000 .db 0b01000100 .db 0b00101000 .db 0b00010000 .db 0b00101000 .db 0b01000100 .db 0b00000000 ; Character: y .db 0b00000000 .db 0b00000000 .db 0b01000100 .db 0b01000100 .db 0b01000100 .db 0b00111100 .db 0b00000100 .db 0b00111000 ; Character: z .db 0b00000000 .db 0b00000000 .db 0b01111100 .db 0b00001000 .db 0b00010000 .db 0b00100000 .db 0b01111100 .db 0b00000000 ; Character: { .db 0b00000000 .db 0b00001110 .db 0b00001000 .db 0b00110000 .db 0b00001000 .db 0b00001000 .db 0b00001110 .db 0b00000000 ; Character: | .db 0b00000000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00001000 .db 0b00000000 ; Character: } .db 0b00000000 .db 0b01110000 .db 0b00010000 .db 0b00001100 .db 0b00010000 .db 0b00010000 .db 0b01110000 .db 0b00000000 ; Character: ~ .db 0b00000000 .db 0b00010100 .db 0b00101000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: Copyright .db 0b00111100 .db 0b01000010 .db 0b10011001 .db 0b10100001 .db 0b10100001 .db 0b10011001 .db 0b01000010 .db 0b00111100 ================================================ FILE: libc/font.s ================================================ ; font.ms ; ; Michael Hope, 1999 ; michaelh@earthling.net ; Distrubuted under the Artistic License - see www.opensource.org ; .include "global.s" .globl .cr_curs .globl .adv_curs .globl .cury, .curx .globl .display_off ; Structure offsets sfont_handle_sizeof = 3 sfont_handle_font = 1 sfont_handle_first_tile = 0 ; Encoding types - lower 2 bits of font FONT_256ENCODING = 0 FONT_128ENCODING = 1 FONT_NOENCODING = 2 ; Other bits FONT_BCOMPRESSED = 2 .CR = 0x0A ; Unix .SPACE = 0x00 ; Maximum number of fonts .MAX_FONTS = 6 .area _HEADER (ABS) .org .MODE_TABLE+4*.T_MODE JP .tmode .module font.ms ; Globals from drawing.s ; FIXME: Hmmm... check the linkage of these .globl .fg_colour .globl .bg_colour .area _BSS ; The current font font_current:: .ds sfont_handle_sizeof ; Cached copy of the first free tile font_first_free_tile:: .ds 1 ; Table containing descriptors for all of the fonts font_table:: .ds sfont_handle_sizeof*.MAX_FONTS .area _BASE ; Copy uncompressed 16 byte tiles from (BC) to (HL), length = DE*2 ; Note: HL must be aligned on a UWORD boundry font_copy_uncompressed:: ld a,d or e ret z ld a,h cp #0x98 jr c,4$ sub #0x98-0x88 ld h,a 4$: xor a cp e ; Special for when e=0 you will get another loop jr nz,1$ dec d 1$: ldh a,(.STAT) bit 1,a jr nz,#.-4 ld a,(bc) ld (hl+),a inc bc ldh a,(.STAT) bit 1,a jr nz,#.-4 ld a,(bc) ld (hl),a inc bc inc l jr nz,2$ inc h ld a,h ; Special wrap-around cp #0x98 jr nz,2$ ld h,#0x88 2$: dec e jr nz,1$ dec d bit 7,d ; -1? jr z,1$ ret ; Copy a set of compressed (8 bytes/cell) tiles to VRAM ; Sets the foreground and background colours based on the current ; font colours ; Entry: ; From (BC) to (HL), length (DE) where DE = #cells * 8 ; Uses the current fg_colour and bg_colour fields font_copy_compressed:: ld a,d or e ret z ; Do nothing ld a,h cp #0x98 ; Take care of the 97FF -> 8800 wrap around jr c,font_copy_compressed_loop sub #0x98-0x88 ld h,a font_copy_compressed_loop: push de ld a,(bc) ld e,a inc bc push bc ld bc,#0 ; Do the background colour first ld a,(.bg_colour) bit 0,a jr z,font_copy_compressed_bg_grey1 ld b,#0xFF font_copy_compressed_bg_grey1: bit 1,a jr z,font_copy_compressed_bg_grey2 ld c,#0xFF font_copy_compressed_bg_grey2: ; BC contains the background colour ; Compute what xoring we need to do to get the correct fg colour ld d,a ld a,(.fg_colour) xor d ld d,a bit 0,d jr z,font_copy_compressed_grey1 ld a,e xor b ld b,a font_copy_compressed_grey1: bit 1,d jr z,font_copy_compressed_grey2 ld a,e xor c ld c,a font_copy_compressed_grey2: ldh a,(.STAT) bit 1,a jr nz,#.-4 ld (hl),b inc hl ldh a,(.STAT) bit 1,a jr nz,#.-4 ld (hl),c inc hl ld a,h ; Take care of the 97FFF -> 8800 wrap around cp #0x98 jr nz,1$ ld h,#0x88 1$: pop bc pop de dec de ld a,d or e jr nz,font_copy_compressed_loop ret ; Load the font HL font_load:: call .display_off push hl ; Find the first free font entry ld hl,#font_table+sfont_handle_font ld b,#.MAX_FONTS font_load_find_slot: ld a,(hl) ; Check to see if this entry is free inc hl ; Free is 0000 for the font pointer or (hl) cp #0 jr z,font_load_found inc hl inc hl dec b jr nz,font_load_find_slot pop hl ld hl,#0 jr font_load_exit ; Couldn't find a free space font_load_found: ; HL points to the end of the free font table entry pop de ld (hl),d ; Copy across the font struct pointer dec hl ld (hl),e ld a,(font_first_free_tile) dec hl ld (hl),a push hl call font_set ; Set this new font to be the default ; Only copy the tiles in if were in text mode ld a,(.mode) and #.T_MODE call nz,font_copy_current ; Increase the 'first free tile' counter ld hl,#font_current+sfont_handle_font ld a,(hl+) ld h,(hl) ld l,a inc hl ; Number of tiles used ld a,(font_first_free_tile) add a,(hl) ld (font_first_free_tile),a pop hl ; Return font setup in HL font_load_exit: ;; Turn the screen on LDH A,(.LCDC) OR #0b10000001 ; LCD = On ; BG = On AND #0b11100111 ; BG Chr = 0x8800 ; BG Bank = 0x9800 LDH (.LCDC),A RET ; Copy the tiles from the current font into VRAM font_copy_current:: ; Find the current font data ld hl,#font_current+sfont_handle_font ld a,(hl+) ld h,(hl) ld l,a inc hl ; Points to the 'tiles required' entry ld e,(hl) ld d,#0 rl e ; Multiple DE by 8 rl d rl e rl d rl e rl d ; DE has the length of the tile data dec hl ld a,(hl) ; Get the flags push af and #3 ; Only lower 2 bits set encoding table size ld bc,#128 cp #FONT_128ENCODING ; 0 for 256 char encoding table, 1 for 128 char jr z,font_copy_current_copy ld bc,#0 cp #FONT_NOENCODING jr z,font_copy_current_copy ld bc,#256 ; Must be 256 element encoding font_copy_current_copy: inc hl inc hl ; Points to the start of the encoding table add hl,bc ld c,l ld b,h ; BC points to the start of the tile data ; Find the offset in VRAM for this font ld a,(font_current+sfont_handle_first_tile) ; First tile used for this font ld l,a ld h,#0 add hl,hl add hl,hl add hl,hl add hl,hl ld a,#0x90 ; Tile 0 is at 9000h add a,h ld h,a ; Is this font compressed? pop af ; Recover flags bit FONT_BCOMPRESSED,a ; Do the jump in a mildly different way jp z,font_copy_uncompressed jp font_copy_compressed ; Set the current font to HL font_set:: ld a,(hl+) ld (font_current),a ld a,(hl+) ld (font_current+1),a ld a,(hl+) ld (font_current+2),a ret ;; Print a character with interpretation .put_char:: ; See if it's a special char cp #.CR jr nz,1$ ; Now see if were checking special chars push af ld a,(.mode) and #.M_NO_INTERP jr nz,2$ call .cr_curs pop af ret 2$: pop af 1$: CALL .set_char CALL .adv_curs RET ;; Print a character without interpretation .out_char:: CALL .set_char CALL .adv_curs RET ;; Delete a character .del_char:: CALL .rew_curs LD A,#.SPACE CALL .set_char RET ;; Print the character in A .set_char: push af ld a,(font_current+2) ; Must be non-zero if the font system is setup (cant have a font in page zero) or a jr nz,3$ ; Font system is not yet setup - init it and copy in the ibm font ; Kind of a compatibility mode call _font_init ; Need all of the tiles xor a ld (font_first_free_tile),a .globl _font_load_ibm_fixed call banked_call .dw _font_load_ibm_fixed .if __RGBDS__ .dw BANK(_font_load_ibm_fixed); .else .dw 0 .endif 3$: pop af push bc push de push hl ; Compute which tile maps to this character ld e,a ld hl,#font_current+sfont_handle_font ld a,(hl+) ld h,(hl) ld l,a ld a,(hl+) and #3 cp #FONT_NOENCODING jr z,set_char_no_encoding inc hl ; Now at the base of the encoding table ; E is set above ld d,#0 add hl,de ld e,(hl) ; That's the tile! set_char_no_encoding: ld a,(font_current+0) add a,e ld e,a LD A,(.cury) ; Y coordinate LD L,A LD H,#0x00 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD A,(.curx) ; X coordinate LD C,A LD B,#0x00 ADD HL,BC LD BC,#0x9800 ADD HL,BC ldh a,(.STAT) bit 1,a jr nz,#.-4 LD (HL),E POP HL POP DE POP BC RET .area _CODE _putchar:: ; Banked PUSH BC LDA HL,.BANKOV+2(SP); Skip return address LD A,(HL) ; A = c CALL .put_char POP BC RET _setchar:: ; Banked PUSH BC LDA HL,.BANKOV+2(SP); Skip return address LD A,(HL) ; A = c CALL .set_char POP BC RET .area _BASE _font_load:: push bc LDA HL,4(SP) ; Skip return address and bc LD A,(HL) ; A = c inc hl ld h,(hl) ld l,a call font_load push hl pop de ; Return in DE pop bc RET _font_set:: push bc LDA HL,4(SP) ; Skip return address LD A,(HL) ; A = c inc hl ld h,(hl) ld l,a call font_set pop bc ld de,#0 ; Always good... RET _font_init:: push bc .globl .tmode call .tmode ld a,#1 ; We use the first tile as a space _always_ ld (font_first_free_tile),a ; Clear the font table xor a ld hl,#font_table ld b,#sfont_handle_sizeof*.MAX_FONTS 1$: ld (hl+),a dec b jr nz,1$ ld a,#3 ld (.fg_colour),a ld a,#0 ld (.bg_colour),a call .cls pop bc ret _cls:: .cls:: PUSH DE PUSH HL LD HL,#0x9800 LD E,#0x20 ; E = height 1$: LD D,#0x20 ; D = width 2$: ldh a,(.STAT) bit 1,a jr nz,#.-4 LD (HL),#.SPACE ; Always clear INC HL DEC D JR NZ,2$ DEC E JR NZ,1$ POP HL POP DE RET .area _CODE ; Support routines _gotoxy:: ; Banked lda hl,.BANKOV(sp) ld a,(hl+) ld (.curx),a ld a,(hl) ld (.cury),a ret _posx:: LD A,(.mode) ; Banked AND #.T_MODE JR NZ,1$ PUSH BC CALL .tmode POP BC 1$: LD A,(.curx) LD E,A RET _posy:: ; Banked LD A,(.mode) AND #.T_MODE JR NZ,1$ PUSH BC CALL .tmode POP BC 1$: LD A,(.cury) LD E,A RET .area _BASE ;; Rewind the cursor .rew_curs: PUSH HL LD HL,#.curx ; X coordinate XOR A CP (HL) JR Z,1$ DEC (HL) JR 99$ 1$: LD (HL),#.MAXCURSPOSX LD HL,#.cury ; Y coordinate XOR A CP (HL) JR Z,99$ DEC (HL) 99$: POP HL RET .cr_curs:: PUSH HL XOR A LD (.curx),A LD HL,#.cury ; Y coordinate LD A,#.MAXCURSPOSY CP (HL) JR Z,2$ INC (HL) JR 99$ 2$: CALL .scroll 99$: POP HL RET .adv_curs:: PUSH HL LD HL,#.curx ; X coordinate LD A,#.MAXCURSPOSX CP (HL) JR Z,1$ INC (HL) JR 99$ 1$: LD (HL),#0x00 LD HL,#.cury ; Y coordinate LD A,#.MAXCURSPOSY CP (HL) JR Z,2$ INC (HL) JR 99$ 2$: ;; See if scrolling is disabled LD A,(.mode) AND #.M_NO_SCROLL JR Z,3$ ;; Nope - reset the cursor to (0,0) XOR A LD (.cury),A LD (.curx),A JR 99$ 3$: CALL .scroll 99$: POP HL RET ;; Scroll the whole screen .scroll: PUSH BC PUSH DE PUSH HL LD HL,#0x9800 LD BC,#0x9800+0x20 ; BC = next line LD E,#0x20-0x01 ; E = height - 1 1$: LD D,#0x20 ; D = width 2$: LDH A,(.STAT) AND #0x02 JR NZ,2$ LD A,(BC) LD (HL+),A INC BC DEC D JR NZ,2$ DEC E JR NZ,1$ LD D,#0x20 3$: LDH A,(.STAT) AND #0x02 JR NZ,3$ LD A,#.SPACE LD (HL+),A DEC D JR NZ,3$ POP HL POP DE POP BC RET .area _BSS .curx:: ; Cursor position .ds 0x01 .cury:: .ds 0x01 .area _BASE .globl .vbl .globl .lcd .globl .int_0x40 .globl .int_0x48 .globl .remove_int ;; Enter text mode .tmode:: DI ; Disable interrupts ;; Turn the screen off LDH A,(.LCDC) BIT 7,A JR Z,1$ ;; Turn the screen off CALL .display_off ;; Remove any interrupts setup by the drawing routine LD BC,#.vbl LD HL,#.int_0x40 CALL .remove_int LD BC,#.lcd LD HL,#.int_0x48 CALL .remove_int 1$: CALL .tmode_out ;; Turn the screen on LDH A,(.LCDC) OR #0b10000001 ; LCD = On ; BG = On AND #0b11100111 ; BG Chr = 0x8800 ; BG Bank = 0x9800 LDH (.LCDC),A EI ; Enable interrupts RET ;; Text mode (out only) .tmode_out:: XOR A LD (.curx),A LD (.cury),A ;; Clear screen CALL .cls LD A,#.T_MODE LD (.mode),A RET ================================================ FILE: libc/get_bk_t.s ================================================ .include "global.s" .globl .get_xy_btt ;; BANKED: checked .area _BASE _get_bkg_tiles:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y LDA HL,9(SP) LD B,(HL) ; BC = tiles DEC HL LD C,(HL) DEC HL LD A,(HL-) ; A = h LD H,(HL) ; H = w LD L,A ; L = h CALL .get_xy_btt POP BC RET ================================================ FILE: libc/get_data.s ================================================ .include "global.s" .globl .copy_vram ;; BANKED: checked .area _BASE _get_bkg_data:: _get_win_data:: LDH A,(.LCDC) BIT 4,A JP NZ,_get_sprite_data PUSH BC LDA HL,7(SP) ; Skip return address and registers LD B,(HL) ; BC = data DEC HL LD C,(HL) DEC HL LD E,(HL) ; E = nb_tiles DEC HL LD L,(HL) ; L = first_tile PUSH HL XOR A OR E ; Is nb_tiles == 0? JR NZ,1$ LD DE,#0x1000 ; DE = nb_tiles = 256 JR 2$ 1$: LD H,#0x00 ; HL = nb_tiles LD L,E ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL LD D,H ; DE = nb_tiles LD E,L 2$: POP HL ; HL = first_tile LD A,L RLCA ; Sign extend (patterns have signed numbers) SBC A LD H,A ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL PUSH BC LD BC,#0x9000 ADD HL,BC POP BC 3$: ; Special version of '.copy_vram' BIT 3,H ; Bigger than 0x9800 JR Z,4$ BIT 4,H JR Z,4$ RES 4,H ; Switch to 0x8800 4$: LDH A,(.STAT) AND #0x02 JR NZ,4$ LD A,(HL+) LD (BC),A INC BC DEC DE LD A,D OR E JR NZ,3$ POP BC RET _get_sprite_data:: PUSH BC LDA HL,7(SP) ; Skip return address and registers LD B,(HL) ; BC = data DEC HL LD C,(HL) DEC HL LD E,(HL) ; E = nb_tiles DEC HL LD L,(HL) ; L = first_tile PUSH HL XOR A OR E ; Is nb_tiles == 0? JR NZ,1$ LD DE,#0x1000 ; DE = nb_tiles = 256 JR 2$ 1$: LD H,#0x00 ; HL = nb_tiles LD L,E ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL LD D,H ; DE = nb_tiles LD E,L 2$: POP HL ; HL = first_tile LD L,A ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL PUSH BC LD BC,#0x8000 ADD HL,BC LD B,H LD C,L POP HL CALL .copy_vram POP BC RET ================================================ FILE: libc/get_prop.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Get properties of sprite number C .get_sprite_prop:: LD HL,#.OAM+3 ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,(HL) ; Get sprite properties LD E,A RET _get_sprite_prop:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb CALL .get_sprite_prop POP BC RET ================================================ FILE: libc/get_spr.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Get tile of sprite number C .get_sprite_tile:: LD HL,#.OAM+2 ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,(HL) ; Get sprite number LD E,A RET _get_sprite_tile:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb CALL .get_sprite_tile POP BC RET ================================================ FILE: libc/get_wi_t.s ================================================ .include "global.s" .globl .get_xy_wtt ;; BANKED: checked, imperfect .area _BASE _get_win_tiles:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y LDA HL,9(SP) LD B,(HL) ; BC = tiles DEC HL LD C,(HL) DEC HL LD A,(HL-) ; A = h LD H,(HL) ; H = w LD L,A ; L = h CALL .get_xy_wtt POP BC RET ================================================ FILE: libc/get_xy_t.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Store window tile table into (BC) at xy = DE of size WH = HL ;; WH >= (1,1) .get_xy_wtt:: PUSH HL ; Store WH PUSH HL ; Store WH LDH A,(.LCDC) BIT 6,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .get_xy_tt 1$: LD HL,#0x9C00 ; HL = origin JR .get_xy_tt ;; Store background tile table into (BC) at XY = DE of size WH = HL ;; WH >= (1,1) .get_xy_btt:: PUSH HL ; Store WH LDH A,(.LCDC) BIT 3,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .get_xy_tt 1$: LD HL,#0x9C00 ; HL = origin ; JR .get_xy_tt .get_xy_tt:: PUSH BC ; Store source XOR A OR E JR Z,2$ LD BC,#0x20 ; One line is 20 tiles 1$: ADD HL,BC ; Y coordinate DEC E JR NZ,1$ 2$: LD B,#0x00 ; X coordinate LD C,D ADD HL,BC POP BC ; BC = source POP DE ; DE = WH PUSH HL ; Store origin PUSH DE ; Store WH 3$: LDH A,(.STAT) AND #0x02 JR NZ,3$ LD A,(HL+) ; Copy W tiles LD (BC),A INC BC DEC D JR NZ,3$ POP HL ; HL = WH LD D,H ; Restore D = W POP HL ; HL = origin DEC E JR Z,4$ PUSH BC ; Next line LD BC,#0x20 ; One line is 20 tiles ADD HL,BC POP BC PUSH HL ; Store current origin PUSH DE ; Store WH JR 3$ 4$: RET _get_tiles:: PUSH BC LDA HL,11(SP) ; Skip return address and registers LD D,(HL) ; DE = src DEC HL LD E,(HL) DEC HL LD B,(HL) ; BC = dst DEC HL LD C,(HL) LDA HL,4(SP) ; Skip return address and registers PUSH DE ; Store address on stack for set_xy_tt LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y INC HL LD A,(HL+) ; A = w LD L,(HL) ; L = h LD H,A ; H = w CALL .get_xy_tt POP BC RET ================================================ FILE: libc/global.s ================================================ .NEAR_CALLS = 1 ; - tag so that sed can change this ;; Changed by astorgb.pl to 1 __RGBDS__ = 0 ;; Screen dimensions .MAXCURSPOSX = 0x13 ; In tiles .MAXCURSPOSY = 0x11 .START = 0x80 .SELECT = 0x40 .B = 0x20 .A = 0x10 .DOWN = 0x08 .UP = 0x04 .LEFT = 0x02 .RIGHT = 0x01 .SCREENWIDTH = 0xA0 .SCREENHEIGHT = 0x90 .MINWNDPOSX = 0x07 .MINWNDPOSY = 0x00 .MAXWNDPOSX = 0xA6 .MAXWNDPOSY = 0x8F .VBL_IFLAG = 0x01 .LCD_IFLAG = 0x02 .TIM_IFLAG = 0x04 .SIO_IFLAG = 0x08 .JOY_IFLAG = 0x10 .P1 = 0x00 ; Joystick: 1.1.P15.P14.P13.P12.P11.P10 .SB = 0x01 ; Serial IO data buffer .SC = 0x02 ; Serial IO control register .DIV = 0x04 ; Divider register .TIMA = 0x05 ; Timer counter .TMA = 0x06 ; Timer modulo .TAC = 0x07 ; Timer control .IF = 0x0F ; Interrupt flags: 0.0.0.JST.SIO.TIM.LCD.VBL .NR10 = 0x10 ; Sound register .NR11 = 0x11 ; Sound register .NR12 = 0x12 ; Sound register .NR13 = 0x13 ; Sound register .NR14 = 0x14 ; Sound register .NR21 = 0x16 ; Sound register .NR22 = 0x17 ; Sound register .NR23 = 0x18 ; Sound register .NR24 = 0x19 ; Sound register .NR30 = 0x1A ; Sound register .NR31 = 0x1B ; Sound register .NR32 = 0x1C ; Sound register .NR33 = 0x1D ; Sound register .NR34 = 0x1E ; Sound register .NR41 = 0x20 ; Sound register .NR42 = 0x21 ; Sound register .NR43 = 0x22 ; Sound register .NR44 = 0x23 ; Sound register .NR50 = 0x24 ; Sound register .NR51 = 0x25 ; Sound register .NR52 = 0x26 ; Sound register .LCDC = 0x40 ; LCD control .STAT = 0x41 ; LCD status .SCY = 0x42 ; Scroll Y .SCX = 0x43 ; Scroll X .LY = 0x44 ; LCDC Y-coordinate .LYC = 0x45 ; LY compare .DMA = 0x46 ; DMA transfer .BGP = 0x47 ; BG palette data .OBP0 = 0x48 ; OBJ palette 0 data .OBP1 = 0x49 ; OBJ palette 1 data .WY = 0x4A ; Window Y coordinate .WX = 0x4B ; Window X coordinate .KEY1 = 0x4D ; CPU speed .VBK = 0x4F ; VRAM bank .HDMA1 = 0x51 ; DMA control 1 .HDMA2 = 0x52 ; DMA control 2 .HDMA3 = 0x53 ; DMA control 3 .HDMA4 = 0x54 ; DMA control 4 .HDMA5 = 0x55 ; DMA control 5 .RP = 0x56 ; IR port .BCPS = 0x68 ; BG color palette specification .BCPD = 0x69 ; BG color palette data .OCPS = 0x6A ; OBJ color palette specification .OCPD = 0x6B ; OBJ color palette data .SVBK = 0x70 ; WRAM bank .IE = 0xFF ; Interrupt enable .G_MODE = 0x01 ; Graphic mode .T_MODE = 0x02 ; Text mode (bit 2) .T_MODE_OUT = 0x02 ; Text mode output only .T_MODE_INOUT = 0x03 ; Text mode with input .M_NO_SCROLL = 0x04 ; Disables scrolling of the screen in text mode .M_NO_INTERP = 0x08 ; Disables special character interpretation .MBC1_ROM_PAGE = 0x2000 ; Address to write to for MBC1 switching ;; Status codes for IO .IO_IDLE = 0x00 .IO_SENDING = 0x01 .IO_RECEIVING = 0x02 .IO_ERROR = 0x04 ;; Type of IO data .DT_IDLE = 0x66 .DT_RECEIVING = 0x55 ;; Table of routines for modes .MODE_TABLE = 0x01E0 ;; C related ;; Overheap of a banked call. Used for parameters ;; = ret + real ret + bank .if .NEAR_CALLS .BANKOV = 2 .else .BANKOV = 6 .endif .globl banked_call .globl banked_ret ;; Global variables .globl .mode .globl __cpu .globl __io_out .globl __io_in .globl __io_status ;; Global routines .globl .set_mode .globl .reset .globl .display_off .globl .wait_vbl_done ;; Interrupt routines .globl .add_VBL .globl .add_LCD .globl .add_TIM .globl .add_SIO .globl .add_JOY ;; Symbols defined at link time .STACK = 0xE000 .OAM = 0xC000 .refresh_OAM = 0xFF80 ;; Initialization routine .init = 0x000 ;; Main user routine .globl _main ================================================ FILE: libc/gprint.c ================================================ #include void gprint(char *str) NONBANKED { while(*str) wrtchr(*str++); } ================================================ FILE: libc/gprintf.c ================================================ #include #include INT8 gprintf(char *fmt, ...) NONBANKED { va_list ap; INT8 nb = 0; va_start(ap, fmt); for(; *fmt; fmt++) if(*fmt == '%') { switch(*++fmt) { case 'c': { /* char */ char c = va_arg(ap, char); wrtchr(c); break; } case 'd': { /* decimal int */ INT8 b = va_arg(ap, INT8); gprintn(b, 10, SIGNED); break; } case 'u': { /* unsigned int */ INT8 b = (INT8)va_arg(ap, int); gprintn(b, 10, UNSIGNED); break; } case 'o': { /* octal int */ INT8 b = va_arg(ap, INT8); gprintn(b, 8, UNSIGNED); break; } case 'x': { /* hexadecimal int */ INT8 b = va_arg(ap, INT8); gprintn(b, 16, UNSIGNED); break; } case 's': { /* string */ char *s = va_arg(ap, char *); gprint(s); break; } #if 0 case 'l': /* long */ switch(*++fmt) { case 'd': /* decimal long */ gprintln(va_arg(ap, INT16), 10, SIGNED); break; case 'u': /* unsigned long */ gprintln(va_arg(ap, INT16), 10, UNSIGNED); break; case 'o': /* octal long */ gprintln(va_arg(ap, INT16), 8, UNSIGNED); break; case 'x': /* hexadecimal long */ gprintln(va_arg(ap, INT16), 16, UNSIGNED); break; } break; #endif case '%': /* % */ wrtchr(*fmt); break; default: return -1; } nb++; } else wrtchr(*fmt); va_end(ap); return nb; } ================================================ FILE: libc/gprintln.c ================================================ #include /* Print a long number in any radix */ extern char *digits; void gprintln(INT16 number, INT8 radix, INT8 signed_value) { UINT16 l; if(number < 0 && signed_value) { wrtchr('-'); number = -number; } if((l = (UINT16)number / (UINT16)radix) != 0) gprintln(l, radix, UNSIGNED); wrtchr(digits[(UINT16)number % (UINT16)radix]); } ================================================ FILE: libc/gprintn.c ================================================ #include /* Print a number in any radix */ extern char *digits; void gprintn(BYTE number, BYTE radix, BYTE signed_value) { UBYTE i; if(number < 0 && signed_value) { wrtchr('-'); number = -number; } if((i = (UBYTE)number / (UBYTE)radix) != 0) gprintn(i, radix, UNSIGNED); wrtchr(digits[(UBYTE)number % (UBYTE)radix]); } ================================================ FILE: libc/hiramcpy.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Copy memory zone to HIRAM ;; ;; Entry conditions ;; C = destination ;; B = length ;; HL = source ;; ;; Register used: AF, BC, HL .hiramcpy:: 1$: LD A,(HL+) LDH (C),A INC C DEC B JR NZ,1$ RET _hiramcpy:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = dst LDA HL,7(SP) LD B,(HL) ; B = n DEC HL LD A,(HL-) ; HL = src LD L,(HL) LD H,A CALL .hiramcpy POP BC RET ================================================ FILE: libc/ibmfixed.s ================================================ ; font: font ;; BANKED: checked .area _BASE .globl font_load ;; Perform tricks with banking to shift this font out of ;; bank 0. Doesnt currently work as the encoding table ;; must always be visible. _font_load_ibm_fixed:: ; Banked ld hl,#_font_ibm_fixed call font_load ret _font_ibm_fixed:: .db 0+4 ; 256 char encoding, compressed .db 255 ; Number of tiles ; Encoding table ; Hack .db 0x00 .db 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 .db 0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10 .db 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18 .db 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20 .db 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28 .db 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30 .db 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 .db 0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40 .db 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48 .db 0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50 .db 0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58 .db 0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60 .db 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68 .db 0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70 .db 0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78 .db 0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80 .db 0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88 .db 0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90 .db 0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98 .db 0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0 .db 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8 .db 0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0 .db 0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8 .db 0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0 .db 0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8 .db 0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0 .db 0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8 .db 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0 .db 0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8 .db 0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0 .db 0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8 .db 0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF ; Tile data ;; Hook for the graphics routines _font_ibm_fixed_tiles:: ; Default character (space) .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 .db 0b00000000 ; Character: ? (01) .db 0b00011000 ; oo .db 0b00100100 ; o o .db 0b01000010 ; o o .db 0b10000001 ; o o .db 0b11100111 ; ooo ooo .db 0b00100100 ; o o .db 0b00100100 ; o o .db 0b00111100 ; oooo ; Character: ? (02) .db 0b00111100 ; oooo .db 0b00100100 ; o o .db 0b00100100 ; o o .db 0b11100111 ; ooo ooo .db 0b10000001 ; o o .db 0b01000010 ; o o .db 0b00100100 ; o o .db 0b00011000 ; oo ; Character: ? (03) .db 0b00011000 ; oo .db 0b00010100 ; o o .db 0b11110010 ; oooo o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b11110010 ; oooo o .db 0b00010100 ; o o .db 0b00011000 ; oo ; Character: ? (04) .db 0b00011000 ; oo .db 0b00101000 ; o o .db 0b01001111 ; o oooo .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b01001111 ; o oooo .db 0b00101000 ; o o .db 0b00011000 ; oo ; Character: ? (05) .db 0b11111111 ; oooooooo .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b11111111 ; oooooooo ; Character: ? (06) .db 0b11111000 ; ooooo .db 0b10001000 ; o o .db 0b10001111 ; o oooo .db 0b10001001 ; o o o .db 0b11111001 ; ooooo o .db 0b01000001 ; o o .db 0b01000001 ; o o .db 0b01111111 ; ooooooo ; Character: ? (07) .db 0b11111111 ; oooooooo .db 0b10001001 ; o o o .db 0b10001001 ; o o o .db 0b10001001 ; o o o .db 0b11111001 ; ooooo o .db 0b10000001 ; o o .db 0b10000001 ; o o .db 0b11111111 ; oooooooo ; Character: ? (08) .db 0b00000001 ; o .db 0b00000011 ; oo .db 0b00000110 ; oo .db 0b10001100 ; o oo .db 0b11011000 ; oo oo .db 0b01110000 ; ooo .db 0b00100000 ; o .db 0b00000000 ; ; Character: ? (09) .db 0b01111110 ; oooooo .db 0b11000011 ; oo oo .db 0b11010011 ; oo o oo .db 0b11010011 ; oo o oo .db 0b11011011 ; oo oo oo .db 0b11000011 ; oo oo .db 0b11000011 ; oo oo .db 0b01111110 ; oooooo ; Character: ? (0A) .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b00101100 ; o oo .db 0b00101100 ; o oo .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (0B) .db 0b00010000 ; o .db 0b00011100 ; ooo .db 0b00010010 ; o o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b01110000 ; ooo .db 0b11110000 ; oooo .db 0b01100000 ; oo ; Character: ? (0C) .db 0b11110000 ; oooo .db 0b11000000 ; oo .db 0b11111110 ; ooooooo .db 0b11011000 ; oo oo .db 0b11011110 ; oo oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (0D) .db 0b01110000 ; ooo .db 0b11001000 ; oo o .db 0b11011110 ; oo oooo .db 0b11011011 ; oo oo oo .db 0b11011011 ; oo oo oo .db 0b01111110 ; oooooo .db 0b00011011 ; oo oo .db 0b00011011 ; oo oo ; Character: ? (0E) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b11111111 ; oooooooo .db 0b11111111 ; oooooooo .db 0b11111111 ; oooooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (0F) .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo ; Character: ? (10) .db 0b01111100 ; ooooo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b00000000 ; .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (11) .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: ? (12) .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01111100 ; ooooo .db 0b11000000 ; oo .db 0b11000000 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (13) .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (14) .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: ? (15) .db 0b01111100 ; ooooo .db 0b11000000 ; oo .db 0b11000000 ; oo .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (16) .db 0b01111100 ; ooooo .db 0b11000000 ; oo .db 0b11000000 ; oo .db 0b01111100 ; ooooo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (17) .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: ? (18) .db 0b01111100 ; ooooo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (19) .db 0b01111100 ; ooooo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: ? (1A) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000110 ; o oo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (1B) .db 0b01111000 ; oooo .db 0b01100110 ; oo oo .db 0b01111101 ; ooooo o .db 0b01100100 ; oo o .db 0b01111110 ; oooooo .db 0b00000011 ; oo .db 0b00001011 ; o oo .db 0b00000110 ; oo ; Character: ? (1C) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011111 ; ooooo .db 0b00011111 ; ooooo .db 0b00011111 ; ooooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo ; Character: ? (1D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b11111100 ; oooooo .db 0b11111100 ; oooooo .db 0b11111100 ; oooooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo ; Character: ? (1E) .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011111 ; ooooo .db 0b00011111 ; ooooo .db 0b00011111 ; ooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (1F) .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b00011100 ; ooo .db 0b11111100 ; oooooo .db 0b11111100 ; oooooo .db 0b11111100 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: (20) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ! (21) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00000000 ; ; Character: " (22) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01000100 ; o o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: # (23) .db 0b00000000 ; .db 0b00100100 ; o o .db 0b01111110 ; oooooo .db 0b00100100 ; o o .db 0b00100100 ; o o .db 0b01111110 ; oooooo .db 0b00100100 ; o o .db 0b00000000 ; ; Character: $ (24) .db 0b00010100 ; o o .db 0b00111110 ; ooooo .db 0b01010101 ; o o o o .db 0b00111100 ; oooo .db 0b00011110 ; oooo .db 0b01010101 ; o o o o .db 0b00111110 ; ooooo .db 0b00010100 ; o o ; Character: % (25) .db 0b01100010 ; oo o .db 0b01100110 ; oo oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01100110 ; oo oo .db 0b01000110 ; o oo .db 0b00000000 ; ; Character: & (26) .db 0b01111000 ; oooo .db 0b11001100 ; oo oo .db 0b01100001 ; oo o .db 0b11001110 ; oo ooo .db 0b11001100 ; oo oo .db 0b11001100 ; oo oo .db 0b01111000 ; oooo .db 0b00000000 ; ; Character: ' (27) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00010000 ; o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ( (28) .db 0b00000100 ; o .db 0b00001000 ; o .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00001000 ; o .db 0b00000100 ; o ; Character: ) (29) .db 0b00100000 ; o .db 0b00010000 ; o .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00010000 ; o .db 0b00100000 ; o ; Character: * (2A) .db 0b00000000 ; .db 0b01010100 ; o o o .db 0b00111000 ; ooo .db 0b11111110 ; ooooooo .db 0b00111000 ; ooo .db 0b01010100 ; o o o .db 0b00000000 ; .db 0b00000000 ; ; Character: + (2B) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: , (2C) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00100000 ; o ; Character: - (2D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: . (2E) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: / (2F) .db 0b00000011 ; oo .db 0b00000110 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01100000 ; oo .db 0b11000000 ; oo .db 0b00000000 ; ; Character: 0 (30) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01101110 ; oo ooo .db 0b01110110 ; ooo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: 1 (31) .db 0b00011000 ; oo .db 0b00111000 ; ooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: 2 (32) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b00001110 ; ooo .db 0b00011100 ; ooo .db 0b00111000 ; ooo .db 0b01110000 ; ooo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: 3 (33) .db 0b01111110 ; oooooo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01000110 ; o oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: 4 (34) .db 0b00001100 ; oo .db 0b00011100 ; ooo .db 0b00101100 ; o oo .db 0b01001100 ; o oo .db 0b01111110 ; oooooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: 5 (35) .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01000110 ; o oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: 6 (36) .db 0b00011100 ; ooo .db 0b00100000 ; o .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: 7 (37) .db 0b01111110 ; oooooo .db 0b00000110 ; oo .db 0b00001110 ; ooo .db 0b00011100 ; ooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: 8 (38) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: 9 (39) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000110 ; oo .db 0b00001100 ; oo .db 0b00111000 ; ooo .db 0b00000000 ; ; Character: : (3A) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ; (3B) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00010000 ; o .db 0b00000000 ; ; Character: < (3C) .db 0b00000110 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: = (3D) .db 0b00000000 ; .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000000 ; .db 0b00000000 ; ; Character: > (3E) .db 0b01100000 ; oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01100000 ; oo .db 0b00000000 ; ; Character: ? (3F) .db 0b00111100 ; oooo .db 0b01000110 ; o oo .db 0b00000110 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo ; Character: @ (40) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01101110 ; oo ooo .db 0b01101010 ; oo o o .db 0b01101110 ; oo ooo .db 0b01100000 ; oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: A (41) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: B (42) .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: C (43) .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: D (44) .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: E (45) .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: F (46) .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b00000000 ; ; Character: G (47) .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01101110 ; oo ooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: H (48) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: I (49) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: J (4A) .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b01000110 ; o oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: K (4B) .db 0b01100110 ; oo oo .db 0b01101100 ; oo oo .db 0b01111000 ; oooo .db 0b01110000 ; ooo .db 0b01111000 ; oooo .db 0b01101100 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: L (4C) .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: M (4D) .db 0b11111100 ; oooooo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b00000000 ; ; Character: N (4E) .db 0b01100010 ; oo o .db 0b01110010 ; ooo o .db 0b01111010 ; oooo o .db 0b01011110 ; o oooo .db 0b01001110 ; o ooo .db 0b01000110 ; o oo .db 0b01000010 ; o o .db 0b00000000 ; ; Character: O (4F) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: P (50) .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b00000000 ; ; Character: Q (51) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000110 ; oo ; Character: R (52) .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: S (53) .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01110000 ; ooo .db 0b00111100 ; oooo .db 0b00001110 ; ooo .db 0b01000110 ; o oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: T (54) .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: U (55) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: V (56) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100100 ; oo o .db 0b01111000 ; oooo .db 0b00000000 ; ; Character: W (57) .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11111100 ; oooooo .db 0b00000000 ; ; Character: X (58) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: Y (59) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: Z (5A) .db 0b01111110 ; oooooo .db 0b00001110 ; ooo .db 0b00011100 ; ooo .db 0b00111000 ; ooo .db 0b01110000 ; ooo .db 0b01100000 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: [ (5B) .db 0b00011110 ; oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011110 ; oooo .db 0b00000000 ; ; Character: \ (5C) .db 0b01000000 ; o .db 0b01100000 ; oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00000110 ; oo .db 0b00000010 ; o .db 0b00000000 ; ; Character: ] (5D) .db 0b01111000 ; oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b01111000 ; oooo .db 0b00000000 ; ; Character: ^ (5E) .db 0b00010000 ; o .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: _ (5F) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ` (60) .db 0b00000000 ; .db 0b11000000 ; oo .db 0b11000000 ; oo .db 0b01100000 ; oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: a (61) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000110 ; o oo .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: b (62) .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b00000000 ; ; Character: c (63) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: d (64) .db 0b00000110 ; oo .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: e (65) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: f (66) .db 0b00011110 ; oooo .db 0b00110000 ; oo .db 0b01111100 ; ooooo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00000000 ; ; Character: g (67) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b01000110 ; o oo .db 0b00111100 ; oooo ; Character: h (68) .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: i (69) .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: j (6A) .db 0b00000000 ; .db 0b00001000 ; o .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b01011000 ; o oo .db 0b00110000 ; oo ; Character: k (6B) .db 0b01100000 ; oo .db 0b01100100 ; oo o .db 0b01101000 ; oo o .db 0b01110000 ; ooo .db 0b01111000 ; oooo .db 0b01101100 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: l (6C) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: m (6D) .db 0b00000000 ; .db 0b11111100 ; oooooo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11000110 ; oo oo .db 0b00000000 ; ; Character: n (6E) .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: o (6F) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: p (70) .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo .db 0b01100000 ; oo ; Character: q (71) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000110 ; oo ; Character: r (72) .db 0b00000000 ; .db 0b01101100 ; oo oo .db 0b01110000 ; ooo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b00000000 ; ; Character: s (73) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01110010 ; ooo o .db 0b00111000 ; ooo .db 0b00011100 ; ooo .db 0b01001110 ; o ooo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: t (74) .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: u (75) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: v (76) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100100 ; oo o .db 0b01111000 ; oooo .db 0b00000000 ; ; Character: w (77) .db 0b00000000 ; .db 0b11000110 ; oo oo .db 0b11000110 ; oo oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11111100 ; oooooo .db 0b00000000 ; ; Character: x (78) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: y (79) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00100110 ; o oo .db 0b00011110 ; oooo .db 0b01000110 ; o oo .db 0b00111100 ; oooo ; Character: z (7A) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00001110 ; ooo .db 0b00011100 ; ooo .db 0b00111000 ; ooo .db 0b01110000 ; ooo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: { (7B) .db 0b00001110 ; ooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00001110 ; ooo .db 0b00000000 ; ; Character: | (7C) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo ; Character: } (7D) .db 0b01110000 ; ooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b01110000 ; ooo .db 0b00000000 ; ; Character: ~ (7E) .db 0b00000000 ; .db 0b01100000 ; oo .db 0b11110010 ; oooo o .db 0b10011110 ; o oooo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (7F) .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00101000 ; o o .db 0b00101000 ; o o .db 0b01000100 ; o o .db 0b01000100 ; o o .db 0b10000010 ; o o .db 0b11111110 ; ooooooo ; Character: ? (80) .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00011100 ; ooo .db 0b00110000 ; oo ; Character: ? (81) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (82) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (83) .db 0b00011000 ; oo .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (84) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000110 ; o oo .db 0b00111110 ; ooooo .db 0b01000110 ; o oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (85) .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (86) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (87) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00111100 ; oooo .db 0b00001000 ; o .db 0b00011000 ; oo ; Character: ? (88) .db 0b00011000 ; oo .db 0b00110100 ; oo o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (89) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (8A) .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (8B) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (8C) .db 0b00011000 ; oo .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (8D) .db 0b00010000 ; o .db 0b00001000 ; o .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (8E) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: ? (8F) .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: ? (90) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (91) .db 0b00000000 ; .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00011011 ; oo oo .db 0b01111111 ; ooooooo .db 0b11011000 ; oo oo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (92) .db 0b00111111 ; oooooo .db 0b01111000 ; oooo .db 0b11011000 ; oo oo .db 0b11011110 ; oo oooo .db 0b11111000 ; ooooo .db 0b11011000 ; oo oo .db 0b11011111 ; oo ooooo .db 0b00000000 ; ; Character: ? (93) .db 0b00011000 ; oo .db 0b00110100 ; oo o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (94) .db 0b00100100 ; o o .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (95) .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (96) .db 0b00011000 ; oo .db 0b00100100 ; o o .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (97) .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (98) .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b01000110 ; o oo .db 0b00111100 ; oooo ; Character: ? (99) .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (9A) .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (9B) .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100010 ; oo o .db 0b00111100 ; oooo .db 0b00011000 ; oo ; Character: ? (9C) .db 0b00011100 ; ooo .db 0b00111010 ; ooo o .db 0b00110000 ; oo .db 0b01111100 ; ooooo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (9D) .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (9E) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01101100 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b11101100 ; ooo oo .db 0b00000000 ; ; Character: ? (9F) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo ; Character: ? (A0) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (A1) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (A2) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (A3) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (A4) .db 0b00110100 ; oo o .db 0b01011000 ; o oo .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: ? (A5) .db 0b00011010 ; oo o .db 0b00101100 ; o oo .db 0b01100010 ; oo o .db 0b01110010 ; ooo o .db 0b01011010 ; o oo o .db 0b01001110 ; o ooo .db 0b01000110 ; o oo .db 0b00000000 ; ; Character: ? (A6) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01000110 ; o oo .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b00111110 ; ooooo .db 0b00000000 ; .db 0b01111110 ; oooooo ; Character: ? (A7) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; .db 0b01111110 ; oooooo ; Character: ? (A8) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01100000 ; oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo ; Character: ? (A9) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00110000 ; oo .db 0b00000000 ; ; Character: ? (AA) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: ? (AB) .db 0b01100010 ; oo o .db 0b11100100 ; ooo o .db 0b01101000 ; oo o .db 0b01110110 ; ooo oo .db 0b00101011 ; o o oo .db 0b01000011 ; o oo .db 0b10000110 ; o oo .db 0b00001111 ; oooo ; Character: ? (AC) .db 0b01100010 ; oo o .db 0b11100100 ; ooo o .db 0b01101000 ; oo o .db 0b01110110 ; ooo oo .db 0b00101110 ; o ooo .db 0b01010110 ; o o oo .db 0b10011111 ; o ooooo .db 0b00000110 ; oo ; Character: ? (AD) .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo ; Character: ? (AE) .db 0b00011011 ; oo oo .db 0b00110110 ; oo oo .db 0b01101100 ; oo oo .db 0b11011000 ; oo oo .db 0b01101100 ; oo oo .db 0b00110110 ; oo oo .db 0b00011011 ; oo oo .db 0b00000000 ; ; Character: ? (AF) .db 0b11011000 ; oo oo .db 0b01101100 ; oo oo .db 0b00110110 ; oo oo .db 0b00011011 ; oo oo .db 0b00110110 ; oo oo .db 0b01101100 ; oo oo .db 0b11011000 ; oo oo .db 0b00000000 ; ; Character: ? (B0) .db 0b00110100 ; oo o .db 0b01011000 ; o oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (B1) .db 0b00110100 ; oo o .db 0b01011000 ; o oo .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (B2) .db 0b00000010 ; o .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01101110 ; oo ooo .db 0b01110110 ; ooo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01000000 ; o ; Character: ? (B3) .db 0b00000000 ; .db 0b00000010 ; o .db 0b00111100 ; oooo .db 0b01101110 ; oo ooo .db 0b01110110 ; ooo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01000000 ; o ; Character: ? (B4) .db 0b00000000 ; .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b11011011 ; oo oo oo .db 0b11011110 ; oo oooo .db 0b11011000 ; oo oo .db 0b01111111 ; ooooooo .db 0b00000000 ; ; Character: ? (B5) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b11011000 ; oo oo .db 0b11011000 ; oo oo .db 0b11111100 ; oooooo .db 0b11011000 ; oo oo .db 0b11011000 ; oo oo .db 0b11011110 ; oo oooo ; Character: ? (B6) .db 0b00100000 ; o .db 0b00010000 ; o .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo ; Character: ? (B7) .db 0b00110100 ; oo o .db 0b01011000 ; o oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo ; Character: ? (B8) .db 0b00110100 ; oo o .db 0b01011000 ; o oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo ; Character: ? (B9) .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (BA) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (BB) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00111000 ; ooo .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00010000 ; o .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (BC) .db 0b01111010 ; oooo o .db 0b11001010 ; oo o o .db 0b11001010 ; oo o o .db 0b11001010 ; oo o o .db 0b01111010 ; oooo o .db 0b00001010 ; o o .db 0b00001010 ; o o .db 0b00001010 ; o o ; Character: ? (BD) .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b10011001 ; o oo o .db 0b10110101 ; o oo o o .db 0b10110001 ; o oo o .db 0b10011101 ; o ooo o .db 0b01000010 ; o o .db 0b00111100 ; oooo ; Character: ? (BE) .db 0b00111100 ; oooo .db 0b01000010 ; o o .db 0b10111001 ; o ooo o .db 0b10110101 ; o oo o o .db 0b10111001 ; o ooo o .db 0b10110101 ; o oo o o .db 0b01000010 ; o o .db 0b00111100 ; oooo ; Character: ? (BF) .db 0b11110001 ; oooo o .db 0b01011011 ; o oo oo .db 0b01010101 ; o o o o .db 0b01010001 ; o o o .db 0b01010001 ; o o o .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C0) .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b11100110 ; ooo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b11110110 ; oooo oo .db 0b00000110 ; oo .db 0b00011100 ; ooo ; Character: ? (C1) .db 0b11110110 ; oooo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b11110110 ; oooo oo .db 0b00000110 ; oo .db 0b00011100 ; ooo ; Character: ? (C2) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01110110 ; ooo oo .db 0b00111100 ; oooo .db 0b01101110 ; oo ooo .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C3) .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C4) .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00000110 ; oo .db 0b00001110 ; ooo .db 0b00011110 ; oooo .db 0b00110110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C5) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C6) .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b00000110 ; oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C7) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C8) .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00001100 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (C9) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CA) .db 0b01100000 ; oo .db 0b01101110 ; oo ooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CB) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CC) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00111110 ; ooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CD) .db 0b01100000 ; oo .db 0b01111110 ; oooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00001110 ; ooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CE) .db 0b00000000 ; .db 0b01101100 ; oo oo .db 0b00111110 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01101110 ; oo ooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (CF) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00111100 ; oooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D0) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00011100 ; ooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D1) .db 0b00000000 ; .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D2) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01110110 ; ooo oo .db 0b00000110 ; oo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D3) .db 0b00000000 ; .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00001110 ; ooo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D4) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000110 ; oo .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00110100 ; oo o .db 0b00110000 ; oo .db 0b00000000 ; ; Character: ? (D5) .db 0b00000000 ; .db 0b01111000 ; oooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D6) .db 0b00000000 ; .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11111110 ; ooooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D7) .db 0b00000000 ; .db 0b01111100 ; ooooo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b11101100 ; ooo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (D8) .db 0b00000000 ; .db 0b00011100 ; ooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: ? (D9) .db 0b00000000 ; .db 0b00111110 ; ooooo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: ? (DA) .db 0b00000000 ; .db 0b11111110 ; ooooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (DB) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01110110 ; ooo oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000110 ; oo .db 0b00000000 ; ; Character: ? (DC) .db 0b00000000 ; .db 0b00110110 ; oo oo .db 0b00110110 ; oo oo .db 0b00011100 ; ooo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00001100 ; oo .db 0b00000000 ; ; Character: ? (DD) .db 0b00011100 ; ooo .db 0b00110010 ; oo o .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b01001100 ; o oo .db 0b00111000 ; ooo ; Character: ? (DE) .db 0b00000000 ; .db 0b00010000 ; o .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b11000110 ; oo oo .db 0b10000010 ; o o .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (DF) .db 0b01100110 ; oo oo .db 0b11110111 ; oooo ooo .db 0b10011001 ; o oo o .db 0b10011001 ; o oo o .db 0b11101111 ; ooo oooo .db 0b01100110 ; oo oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (E0) .db 0b00000000 ; .db 0b00000000 ; .db 0b01110110 ; ooo oo .db 0b11011100 ; oo ooo .db 0b11001000 ; oo o .db 0b11011100 ; oo ooo .db 0b01110110 ; ooo oo .db 0b00000000 ; ; Character: ? (E1) .db 0b00011100 ; ooo .db 0b00110110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01111100 ; ooooo .db 0b01100000 ; oo ; Character: ? (E2) .db 0b00000000 ; .db 0b11111110 ; ooooooo .db 0b01100110 ; oo oo .db 0b01100010 ; oo o .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b01100000 ; oo .db 0b11111000 ; ooooo ; Character: ? (E3) .db 0b00000000 ; .db 0b00000000 ; .db 0b11111110 ; ooooooo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01001000 ; o o ; Character: ? (E4) .db 0b11111110 ; ooooooo .db 0b01100110 ; oo oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01100110 ; oo oo .db 0b11111110 ; ooooooo .db 0b00000000 ; ; Character: ? (E5) .db 0b00000000 ; .db 0b00011110 ; oooo .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b00111000 ; ooo .db 0b00000000 ; ; Character: ? (E6) .db 0b00000000 ; .db 0b00000000 ; .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01111111 ; ooooooo .db 0b11000000 ; oo ; Character: ? (E7) .db 0b00000000 ; .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00010000 ; o ; Character: ? (E8) .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00011000 ; oo .db 0b00111100 ; oooo ; Character: ? (E9) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01111110 ; oooooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00111100 ; oooo .db 0b00000000 ; ; Character: ? (EA) .db 0b00000000 ; .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00100100 ; o o .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: ? (EB) .db 0b00011100 ; ooo .db 0b00110110 ; oo oo .db 0b01111000 ; oooo .db 0b11011100 ; oo ooo .db 0b11001100 ; oo oo .db 0b11101100 ; ooo oo .db 0b01111000 ; oooo .db 0b00000000 ; ; Character: ? (EC) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00111000 ; ooo .db 0b01010100 ; o o o .db 0b01010100 ; o o o .db 0b00111000 ; ooo .db 0b00110000 ; oo .db 0b01100000 ; oo ; Character: ? (ED) .db 0b00000000 ; .db 0b00010000 ; o .db 0b01111100 ; ooooo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b11010110 ; oo o oo .db 0b01111100 ; ooooo .db 0b00010000 ; o ; Character: ? (EE) .db 0b00111110 ; ooooo .db 0b01110000 ; ooo .db 0b01100000 ; oo .db 0b01111110 ; oooooo .db 0b01100000 ; oo .db 0b01110000 ; ooo .db 0b00111110 ; ooooo .db 0b00000000 ; ; Character: ? (EF) .db 0b00111100 ; oooo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b01100110 ; oo oo .db 0b00000000 ; ; Character: ? (F0) .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (F1) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b01111110 ; oooooo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (F2) .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (F3) .db 0b00001100 ; oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b00011000 ; oo .db 0b00001100 ; oo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; ; Character: ? (F4) .db 0b00000000 ; .db 0b00001110 ; ooo .db 0b00011011 ; oo oo .db 0b00011011 ; oo oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo ; Character: ? (F5) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b11011000 ; oo oo .db 0b11011000 ; oo oo .db 0b01110000 ; ooo .db 0b00000000 ; ; Character: ? (F6) .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b01111110 ; oooooo .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; ; Character: ? (F7) .db 0b00000000 ; .db 0b00110010 ; oo o .db 0b01001100 ; o oo .db 0b00000000 ; .db 0b00110010 ; oo o .db 0b01001100 ; o oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (F8) .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b00111000 ; ooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (F9) .db 0b00111000 ; ooo .db 0b01111100 ; ooooo .db 0b00111000 ; ooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (FA) .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00011000 ; oo .db 0b00011000 ; oo .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (FB) .db 0b00000000 ; .db 0b00000000 ; .db 0b00001111 ; oooo .db 0b00011000 ; oo .db 0b11011000 ; oo oo .db 0b01110000 ; ooo .db 0b00110000 ; oo .db 0b00000000 ; ; Character: ? (FC) .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b01101100 ; oo oo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (FD) .db 0b00111000 ; ooo .db 0b01101100 ; oo oo .db 0b00011000 ; oo .db 0b00110000 ; oo .db 0b01111100 ; ooooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (FE) .db 0b01111000 ; oooo .db 0b00001100 ; oo .db 0b00111000 ; ooo .db 0b00001100 ; oo .db 0b01111000 ; oooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ; Character: ? (FF) .db 0b00000000 ; .db 0b11111110 ; ooooooo .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; .db 0b00000000 ; ================================================ FILE: libc/init_tt.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Initialize part (size = DE) of the VRAM at (HL) with B .init_vram:: 1$: LDH A,(.STAT) AND #0x02 JR NZ,1$ LD (HL),B INC HL DEC DE LD A,D OR E JR NZ,1$ RET ;; Initialize window tile table with B .init_wtt:: LDH A,(.LCDC) BIT 6,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .init_tt 1$: LD HL,#0x9C00 ; HL = origin JR .init_tt ;; Initialize background tile table with B .init_btt:: LDH A,(.LCDC) BIT 3,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .init_tt 1$: LD HL,#0x9C00 ; HL = origin ; JR .init_tt .init_tt:: LD DE,#0x0400 ; One whole GB Screen JP .init_vram ================================================ FILE: libc/input.s ================================================ .include "global.s" ;; Note that while gets uses a pointer, the pointer had better ;; be in non-banked RAM else bad things will happen. ;; BANKED: checked, imperfect .globl .copy_vram .globl .set_xy_wtt .globl .mv_sprite .globl .set_sprite_prop .globl .set_sprite_tile .globl .jpad .globl .padup .MINMSPOSX = 0x02 ; In tiles .MINMSPOSY = 0x0A .MAXMSPOSX = 0x11 .MAXMSPOSY = 0x0F .INIMSPOSX = .MINMSPOSX .INIMSPOSY = .MINMSPOSY .KBDWINPOSY = 0x08 ; In tiles .KBDSIZE = 0x1006 .MSOFFSETX = 0x0C ; In pixels .MSOFFSETY = 0x14 .MINACCEL = 0x0800 .MAXACCEL = 0x0100 .CR = 0x0A ; Unix ; .CR = 0x0D ; Dos .globl .tmode_out ; From 'output.s' .globl .put_char .globl .del_char .globl .cury .area _HEADER (ABS) .org .MODE_TABLE+4*.T_MODE_INOUT JP .tmode_inout .module Terminal .area _BSS .msx: ; Mouse position .ds 0x01 .msy: .ds 0x01 .msacc: ; Mouse acceleration .ds 0x02 .msstate: ; Mouse state .ds 0x01 .mschanged: ; Did the mouse move? .ds 0x01 .string_len: ; Used length of input buffer .ds 0x01 .area _BASE ;; Enter text mode with input .tmode_inout:: DI ; Disable interrupts ;; Turn the screen off LDH A,(.LCDC) BIT 7,A JR Z,1$ ;; Turn the screen off CALL .display_off 1$: LD A,(.mode) AND #.T_MODE CALL Z,.tmode_out LD BC,#.tp1 ; Move pointer LD HL,#0x8000 LD DE,#.endtp1-.tp1 CALL .copy_vram LD A,#<.MINACCEL ; Acceleration LD (.msacc),A LD A,#>.MINACCEL LD (.msacc+1),A ;; Initialize window LD BC,#.frame_tiles LD DE,#0x0000 ; Place image at (0x00,0x00) tiles LD HL,#0x140A ; Image size is 0x14 x 0x0A tiles CALL .set_xy_wtt LD BC,#.kbdtable LD DE,#0x0202 ; Place image at (0x02,0x02) tiles LD HL,#.KBDSIZE ; Image size is 0x10 x 0x06 tiles CALL .set_xy_wtt XOR A LD A,#.MINWNDPOSX LDH (.WX),A LD A,#.MAXWNDPOSY ; Hide window LDH (.WY),A ;; Initialize sprite LD C,#0x00 ; Sprite 0x00 LD D,#0x00 ; Default sprite properties CALL .set_sprite_prop LD C,#0x00 ; Sprite 0x00 LD D,#0x00 ; Tile 0x00 CALL .set_sprite_tile LD A,#0b00101100 LDH (.OBP0),A ;; Turn the screen on LD A,#0b11000001 ; LCD = On ; WindowBank = 0x9C00 ; Window = Off ; BG Chr = 0x8800 ; BG Bank = 0x9800 ; OBJ = 8x8 ; OBJ = Off ; BG = On LDH (.LCDC),A LD A,#.T_MODE_INOUT LD (.mode),A EI ; Enable interrupts RET .area _CODE ;; Prompt the user for a char and return it in A .get_char: PUSH BC PUSH DE PUSH HL CALL .show_kbd CALL .show_mouse 1$: CALL .track_mouse CALL .update_mouse CALL .jpad LD D,A AND #.A ; Is A pressed ? JP Z,1$ LD A,(.msy) ; Look for char under the mouse SUB #.MINMSPOSY JR Z,12$ LD E,A XOR A 11$: ADD #.MAXMSPOSX-.MINMSPOSX+1 DEC E JR NZ,11$ 12$: LD E,A LD A,(.msx) SUB #.MINMSPOSX ADD E LD HL,#.kbdtable LD B,#0x00 LD C,A ADD HL,BC LD B,(HL) CALL .hide_mouse CALL .hide_kbd LD A,B POP HL POP DE POP BC RET ;; Prompt the user for a string and store it in (HL) .get_string: PUSH BC PUSH DE PUSH HL CALL .show_kbd CALL .show_bkg CALL .show_mouse XOR A LD (.string_len),A 1$: CALL .track_mouse CALL .update_mouse CALL .jpad LD D,A AND #.A ; Is A pressed ? JP NZ,10$ LD A,D AND #.B ; Is B pressed ? JP NZ,20$ LD A,D AND #.SELECT ; Is SELECT pressed ? JP NZ,30$ LD A,D AND #.START ; Is START pressed ? JR Z,1$ CALL .padup ; Wait for button to be depressed LD A,#.CR CALL .put_char LD (HL),#0x00 CALL .hide_mouse CALL .hide_bkg CALL .hide_kbd POP HL POP DE POP BC RET 10$: ;; Insert a character at cursor position LD A,(.string_len) ; Check buffer length ; CP #.BUFLEN-1 ; Keep 1 char for EOS ; JR Z,13$ INC A LD (.string_len),A ; Update it LD A,(.msy) ; Look for char under the mouse SUB #.MINMSPOSY JR Z,12$ LD E,A XOR A 11$: ADD #.MAXMSPOSX-.MINMSPOSX+1 DEC E JR NZ,11$ 12$: LD E,A LD A,(.msx) SUB #.MINMSPOSX ADD E PUSH HL LD HL,#.kbdtable LD B,#0x00 LD C,A ADD HL,BC LD A,(HL) POP HL LD (HL+),A ; Add it into input buffer CALL .put_char ; Print it CALL .show_bkg ; Ensure the text is not hidden 13$: CALL .padup ; Wait for button to be depressed JP 1$ 20$: ;; Delete a character at cursor position LD A,(.string_len) ; Is there any char in the buffer ? OR A JR Z,21$ DEC A ; Yes LD (.string_len),A ; Update buffer length DEC HL CALL .del_char 21$: CALL .padup ; Wait for button to be depressed JP 1$ 30$: CALL .hide_mouse CALL .hide_bkg CALL .hide_kbd CALL .padup ; Wait for button to be depressed CALL .show_kbd CALL .show_bkg CALL .show_mouse JP 1$ .show_kbd: PUSH BC PUSH DE LDH A,(.LCDC) OR #0b00100000 ; Window = On LDH (.LCDC),A LD A,#.MAXWNDPOSY ; Show window 1$: BIT 0,A ; Wait for VBL every 2 pixels (slow down) JR NZ,2$ LD B,A CALL .wait_vbl_done LD A,B 2$: LDH (.WY),A CP #.KBDWINPOSY*0x08 JR Z,99$ DEC A JR 1$ 99$: POP DE POP BC RET .hide_kbd: PUSH BC PUSH DE LD A,#.KBDWINPOSY*0x08+1 1$: ; Hide window BIT 0,A ; Wait for VBL every 2 pixels (slow down) JR Z,2$ LD B,A CALL .wait_vbl_done LD A,B 2$: LDH (.WY),A CP #.MAXWNDPOSY JR Z,3$ INC A JR 1$ 3$: LDH A,(.LCDC) AND #0b11011111 ; Window = Off LDH (.LCDC),A POP DE POP BC RET .show_bkg: PUSH BC PUSH DE LDH A,(.SCY) LD D,A LD A,(.cury) SUB #.KBDWINPOSY-1 JR C,99$ JR Z,99$ SLA A ; A = A * 8 SLA A SLA A SUB D JR C,99$ JR Z,99$ LD C,A LDH A,(.SCY) 1$: BIT 0,A ; Wait for VBL every 2 pixels (slow down) JR Z,2$ LD B,A CALL .wait_vbl_done LD A,B 2$: INC A LDH (.SCY),A DEC C JR Z,99$ JR 1$ 99$: POP DE POP BC RET .hide_bkg: LDH A,(.SCY) OR A RET Z PUSH BC PUSH DE 1$: BIT 0,A ; Wait for VBL every 2 pixels (slow down) JR Z,2$ LD B,A CALL .wait_vbl_done LD A,B 2$: DEC A LDH (.SCY),A JR Z,99$ JR 1$ 99$: POP DE POP BC RET .show_mouse: LD A,#.INIMSPOSX LD (.msx),A LD A,#.INIMSPOSY LD (.msy),A CALL .set_mouse LDH A,(.LCDC) OR #0b00000010 ; OBJ = On LDH (.LCDC),A RET .hide_mouse: LDH A,(.LCDC) AND #0b11111101 ; OBJ = Off LDH (.LCDC),A RET .track_mouse: PUSH BC PUSH DE PUSH HL XOR A LD (.mschanged),A ; Default to no change CALL .jpad LD D,A LD HL,#.msstate AND #.UP+.DOWN+.LEFT+.RIGHT JR NZ,1$ LD (HL),#0x00 ; Reset state JP 99$ 1$: LD A,(HL) LD (HL),#0x01 ; Set state OR A ; Was it 0 ? LD HL,#.msacc ; Acceleration JR NZ,2$ ; Yes LD (HL),#<.MINACCEL INC HL LD (HL),#>.MINACCEL JR 4$ ; Update position 2$: LD C,(HL) INC HL LD B,(HL) DEC BC LD A,B OR C JR Z,3$ LD (HL),B DEC HL LD (HL),C JP 99$ 3$: ; Set new acceleration to maximum LD (HL),#>.MAXACCEL DEC HL LD (HL),#<.MAXACCEL 4$: ; Update position LD A,#0x01 LD (.mschanged),A LD A,D AND #.UP ; Is UP pressed ? JR Z,6$ LD A,(.msy) CP #.MINMSPOSY JR Z,5$ DEC A LD (.msy),A JR 6$ 5$: LD A,#.MAXMSPOSY LD (.msy),A 6$: LD A,D AND #.DOWN ; Is DOWN pressed ? JR Z,8$ LD A,(.msy) CP #.MAXMSPOSY JR Z,7$ INC A LD (.msy),A JR 8$ 7$: LD A,#.MINMSPOSY LD (.msy),A 8$: LD A,D AND #.LEFT ; Is LEFT pressed ? JR Z,10$ LD A,(.msx) CP #.MINMSPOSX JR Z,9$ DEC A LD (.msx),A JR 10$ 9$: LD A,#.MAXMSPOSX LD (.msx),A 10$: LD A,D AND #.RIGHT ; Is RIGHT pressed ? JR Z,99$ LD A,(.msx) CP #.MAXMSPOSX JR Z,11$ INC A LD (.msx),A JR 99$ 11$: LD A,#.MINMSPOSX LD (.msx),A 99$: POP HL POP DE POP BC RET .update_mouse: LD A,(.mschanged) ; Did it change ? OR A RET Z ; No .set_mouse: PUSH BC PUSH DE PUSH HL LD C,#0x00 ; Sprite 0x00 LD A,(.msx) SLA A ; A = A * 8 SLA A SLA A ADD #.MSOFFSETX LD D,A LD A,(.msy) SLA A ; A = A * 8 SLA A SLA A ADD #.MSOFFSETY LD E,A CALL .mv_sprite POP HL POP DE POP BC RET _getchar:: ; Banked LD A,(.mode) CP #.T_MODE_INOUT JR Z,1$ PUSH BC CALL .tmode_inout POP BC 1$: CALL .get_char LD E,A RET _gets:: ; Banked LD A,(.mode) CP #.T_MODE_INOUT JR Z,1$ PUSH BC CALL .tmode_inout POP BC 1$: LDA HL,.BANKOV(SP) ; Skip return address LD A,(HL+) LD H,(HL) ; HL = s LD L,A PUSH HL CALL .get_string POP DE RET ;; PENDING: this is unfortunate. Refed from .tmode_inout .area _BASE .tp1: .pointers: ; Tile 0x00 .byte 0xFF,0xFF,0xFE,0x82,0xFC,0x84,0xFC,0x84,0xFE,0x82,0xFF,0xB1,0xCF,0xC9,0x87,0x87 .endtp1: .frame_tiles: .byte 0x1C,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x1D .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x0F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0F .byte 0x1E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x1F .kbdtable: ;; This is unfortunate. astorgb and rgbasm cant interpert: ;; .ascii " !\"#$%&'()*+,-./" ;; so we have to use the hex form here. .db 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 .db 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F .ascii "0123456789:" ;; astorgb recognises the embedded ; as a comment :) .db 0x3B .ascii "<=>?" .ascii "@ABCDEFGHIJKLMNO" .ascii "PQRSTUVWXYZ[\\]^_" .ascii "`abcdefghijklmno" .ascii "pqrstuvwxyz\{\|\}~ " ================================================ FILE: libc/mv_bkg.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE _move_bkg:: LDA HL,2(SP) ; Skip return address LD A,(HL+) LDH (.SCX),A LD A,(HL+) LDH (.SCY),A 2$: RET ================================================ FILE: libc/mv_spr.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Move sprite number C at XY = DE .mv_sprite:: LD HL,#.OAM ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,E ; Set Y LD (HL+),A LD A,D ; Set X LD (HL+),A RET _move_sprite:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb INC HL LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y CALL .mv_sprite POP BC RET ================================================ FILE: libc/mv_win.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE _move_win:: LDA HL,2(SP) ; Skip return address LD A,(HL+) LDH (.WX),A LD A,(HL+) LDH (.WY),A RET ================================================ FILE: libc/pad.s ================================================ .include "global.s" ;; BANKED: checked .area _BASE ;; Wait until all buttons have been released .padup:: _waitpadup:: PUSH AF ; Save modified registers PUSH BC 1$: LD B,#0xFF 2$: CALL .jpad OR A ; Have all buttons been released? JR NZ,1$ ; Not yet DEC B JR NZ,2$ POP BC ; Restore registers POP AF RET ;; Get Keypad Button Status ;; The following bits are set if pressed: ;; 0x80 - Start 0x08 - Down ;; 0x40 - Select 0x04 - Up ;; 0x20 - B 0x02 - Left ;; 0x10 - A 0x01 - Right .jpad:: PUSH BC ; Save modified registers LD A,#0x20 LDH (.P1),A ; Turn on P15 LDH A,(.P1) ; Delay LDH A,(.P1) CPL AND #0x0F SWAP A LD B,A LD A,#0x10 LDH (.P1),A ; Turn on P14 LDH A,(.P1) ; Delay LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) CPL AND #0x0F OR B SWAP A LD B,A LD A,#0x30 LDH (.P1),A ; Turn off P14 and P15 (reset joypad) LD A,B POP BC ; Restore registers RET ;; Wait for the key in B to be pressed .wait_pad:: 1$: CALL .jpad ; Read pad AND B ; Compare with mask? JR Z,1$ ; Loop if no intersection RET _joypad:: CALL .jpad LD E,A ; Return result in DE RET _waitpad:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD B,(HL) CALL .wait_pad LD E,A ; Return result in DE POP BC RET ================================================ FILE: libc/rand.s ================================================ ;/*************************************************************************** ; * * ; * Module : rand.s * ; * * ; * Purpose : A rand() generator using the linear congruential method * ; * * ; * Version : 1.01, January 7 1998 * ; * Added _initrand to set seed without recompiling * ; * 1, January 6 1998 * ; * * ; * Author : Luc Van den Borre ( Homepage : NOC.BASE.ORG ) * ; * * ; **************************************************************************/ ;; BANKED: checked ;; Why use an algorithm for generating random numbers? ;; ;; - Given a certain seed value, the same sequence of random numbers is generated ;; every time. This is a good thing when debugging (reproducible). On the other ;; hand, you've got 2^16 seed values, each of which will produce a sequence of ;; numbers that stays different for any of the other sequences for 'an appreciable ;; time.' (I can't say how long exactly.) ;; ;; - The linear congruential method is one of the 'best' random number generators ;; around. However, this implementation uses a 16 bit accumulator, while at least ;; 32 bits are needed for a generator that passes all the statistical tests. ;; Still, I'm relatively confident that this is random enough for even the most ;; demanding game. ;; ;; Compare this to getting random values from one of the hardware registers ;; (not reproducible, might not have all values). An array might be the best bet ;; if you don't need a lot of values (or have lots of memory spare), ;; or if you want values to be within a certain range. ;; And both would be faster than this. Also, this definitely isn't the fastest ;; algorithm I know, and certainly for games less strict algorithms might be ;; appropriate (shift and xor ?). ;; It's your choice - but if you're doing Monte Carlo physics simulations on the ;; GameBoy, this is a safe bet! .include "global.s" .area _BSS .randhi:: ; Storage for last random number (or seed) .ds 0x01 .randlo:: .ds 0x01 .area _CODE ;; Random number generator using the linear congruential method ;; X(n+1) = (a*X(n)+c) mod m ;; with a = 17, m = 16 and c = $5c93 (arbitrarily) ;; The seed value is also chosen arbitrarily as $a27e ;; Ref : D. E. Knuth, "The Art of Computer Programming" , Volume 2 ;; ;; Exit conditions ;; DE = Random number [0,2^16-1] ;; ;; Registers used: ;; A, HL (need not be saved) and DE (return register) ;; __rand:: ; Banked __randw:: ; Banked LD A,(.randlo) LD L,A LD E,A ; Save randlo LD A,(.randhi) LD D,A ; Save randhi SLA L ; * 16 RLA SLA L RLA SLA L RLA SLA L RLA LD H,A ; Save randhi*16 LD A,E ; Old randlo ADD A,L ; Add randlo*16 LD L,A ; Save randlo*17 LD A,H ; randhi*16 ADC A,D ; Add old randhi LD H,A ; Save randhi*17 LD A,L ; randlo*17 ADD A,#0x93 LD (.randlo),A LD D,A ; Return register LD A,H ; randhi*17 ADC A,#0x5c LD (.randhi),A LD E,A ; Return register ;; Note D is the low byte,E the high byte. This is intentional because ;; the high byte can be slightly 'more random' than the low byte, and I presume ;; most will cast the return value to a UBYTE. As if someone will use this, tha! RET ;; This sets the seed value. Call it whenever you like ;; ;; Exit conditions ;; None ;; ;; Registers used: ;; A, HL (need not be saved) and DE (return register) ;; .area _BASE _initrand:: ; Non banked LDA HL,2(SP) .initrand:: LD A,(HL+) LD (.randlo),A LD A,(HL) LD (.randhi),A RET ================================================ FILE: libc/sample.s ================================================ .include "global.s" ;; BANKED: checked .title "Sound sample player" .module Sample .area _BASE .AUD3WAVERAM = 0xff30 _play_sample:: push bc lda hl,4(sp) ld a,(hl+) ld d,(hl) ld e,a lda hl,6(sp) ld a,(hl+) ld b,(hl) ld c,a ld h,d ld l,e call .play_sample pop bc ret ; Playback raw sound sample with length BC from HL at 8192Hz rate. ; BC defines the length of the sample in samples/32 or bytes/16. ; The format of the data is unsigned 4-bit samples, ; 2 samples per byte, upper 4-bits played before lower 4 bits. ; ; Adaption for GBDK by Lars Malmborg. ; Original code by Jeff Frohwein. .play_sample:: ld a,#0x84 ldh (.NR52),a ;enable sound 3 ld a,#0 ldh (.NR30),a ldh (.NR51),a ld a,#0x77 ldh (.NR50),a ;select speakers ld a,#0xff ldh (.NR51),a ;enable sound 3 ld a,#0x80 ldh (.NR31),a ;sound length ld a,#0x20 ldh (.NR32),a ;sound level high ld a,#0x00 ldh (.NR33),a ;sound freq low .samp2: ld de,#.AUD3WAVERAM ;12 push bc ;16 ld b,#16 ;16 xor a ldh (.NR30),a .samp3: ld a,(hl+) ;8 ld (de),a ;8 inc de ;8 dec b ;4 jr nz,.samp3 ;12 ld a,#0x80 ldh (.NR30),a ld a,#0x87 ; (256hz) ldh (.NR34),a ld bc,#558 ;delay routine .samp4: dec bc ;8 ld a,b ;4 or c ;4 jr nz,.samp4 ;12 ld a,#0 ;more delay ld a,#0 ld a,#0 pop bc ;12 dec bc ;8 ld a,b ;4 or c ;4 jr nz,.samp2 ;12 ld a,#0xbb ldh (.NR51),a ;disable sound 3 ret ================================================ FILE: libc/scroll_b.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE _scroll_bkg:: LDA HL,2(SP) ; Skip return address XOR A CP (HL) ; Is x != 0 JR Z,1$ LDH A,(.SCX) ; Yes ADD (HL) LDH (.SCX),A 1$: INC HL XOR A CP (HL) ; Is y != 0 JR Z,2$ LDH A,(.SCY) ; Yes ADD (HL) LDH (.SCY),A 2$: RET ================================================ FILE: libc/scroll_s.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Move sprite number C at XY = DE .scroll_sprite:: LD HL,#.OAM ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,(HL) ADD E ; Set Y LD (HL+),A LD A,(HL) ADD D ; Set X LD (HL+),A RET _scroll_sprite:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb INC HL LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y CALL .scroll_sprite POP BC RET ================================================ FILE: libc/scroll_w.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE _scroll_win:: LDA HL,2(SP) ; Skip return address XOR A CP (HL) ; Is x != 0 JR Z,1$ LDH A,(.WX) ; Yes ADD (HL) LDH (.WX),A 1$: INC HL XOR A CP (HL) ; Is y != 0 JR Z,2$ LDH A,(.WY) ; Yes ADD (HL) LDH (.WY),A 2$: RET ================================================ FILE: libc/serial.s ================================================ .include "global.s" ;; BANKED: checked .area _CODE ;; Send byte in __io_out to the serial port .send_byte: _send_byte:: ; Banked LD A,#.IO_SENDING LD (__io_status),A ; Store status LD A,#0x01 LDH (.SC),A ; Use internal clock LD A,(__io_out) LDH (.SB),A ; Send data byte LD A,#0x81 LDH (.SC),A ; Use internal clock RET ;; Receive byte from the serial port in __io_in .receive_byte: _receive_byte:: ; Banked LD A,#.IO_RECEIVING LD (__io_status),A ; Store status XOR A LDH (.SC),A ; Use external clock LD A,#.DT_RECEIVING LDH (.SB),A ; Send RECEIVING byte LD A,#0x80 LDH (.SC),A ; Use external clock RET ================================================ FILE: libc/set_bk_t.s ================================================ .include "global.s" .globl .set_xy_btt ;; BANKED: checked .area _BASE _set_bkg_tiles:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y LDA HL,9(SP) LD B,(HL) ; BC = tiles DEC HL LD C,(HL) DEC HL LD A,(HL-) ; A = h LD H,(HL) ; H = w LD L,A ; L = h CALL .set_xy_btt POP BC RET ================================================ FILE: libc/set_data.s ================================================ .include "global.s" .globl .copy_vram ;; BANKED: checked .area _BASE _set_bkg_data:: _set_win_data:: LDH A,(.LCDC) BIT 4,A JP NZ,_set_sprite_data PUSH BC LDA HL,7(SP) ; Skip return address and registers LD B,(HL) ; BC = data DEC HL LD C,(HL) DEC HL LD E,(HL) ; E = nb_tiles DEC HL LD L,(HL) ; L = first_tile PUSH HL XOR A OR E ; Is nb_tiles == 0? JR NZ,1$ LD DE,#0x1000 ; DE = nb_tiles = 256 JR 2$ 1$: LD H,#0x00 ; HL = nb_tiles LD L,E ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL LD D,H ; DE = nb_tiles LD E,L 2$: POP HL ; HL = first_tile LD A,L RLCA ; Sign extend (patterns have signed numbers) SBC A LD H,A ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL PUSH BC LD BC,#0x9000 ADD HL,BC POP BC 3$: ; Special version of '.copy_vram' BIT 3,H ; Bigger than 0x9800 JR Z,4$ BIT 4,H JR Z,4$ RES 4,H ; Switch to 0x8800 4$: LDH A,(.STAT) AND #0x02 JR NZ,4$ LD A,(BC) LD (HL+),A INC BC DEC DE LD A,D OR E JR NZ,3$ POP BC RET _set_sprite_data:: PUSH BC LDA HL,7(SP) ; Skip return address and registers LD B,(HL) ; BC = data DEC HL LD C,(HL) DEC HL LD E,(HL) ; E = nb_tiles DEC HL LD L,(HL) ; L = first_tile PUSH HL XOR A OR E ; Is nb_tiles == 0? JR NZ,1$ LD DE,#0x1000 ; DE = nb_tiles = 256 JR 2$ 1$: LD H,#0x00 ; HL = nb_tiles LD L,E ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL LD D,H ; DE = nb_tiles LD E,L 2$: POP HL ; HL = first_tile LD H,#0x00 ADD HL,HL ; HL *= 16 ADD HL,HL ADD HL,HL ADD HL,HL PUSH BC LD BC,#0x8000 ADD HL,BC POP BC CALL .copy_vram POP BC RET ================================================ FILE: libc/set_prop.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Set properties of sprite number C to D .set_sprite_prop:: LD HL,#.OAM+3 ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,D ; Set sprite properties LD (HL),A RET _set_sprite_prop:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb INC HL LD D,(HL) ; D = prop CALL .set_sprite_prop POP BC RET ================================================ FILE: libc/set_spr.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Set sprite number C to tile D .set_sprite_tile:: LD HL,#.OAM+2 ; Calculate origin of sprite info SLA C ; Multiply C by 4 SLA C LD B,#0x00 ADD HL,BC LD A,D ; Set sprite number LD (HL),A RET _set_sprite_tile:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD C,(HL) ; C = nb INC HL LD D,(HL) ; D = tile CALL .set_sprite_tile POP BC RET ================================================ FILE: libc/set_wi_t.s ================================================ .include "global.s" .globl .set_xy_wtt ;; BANKED: checked, imperfect .area _BASE _set_win_tiles:: PUSH BC LDA HL,4(SP) ; Skip return address and registers LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y LDA HL,9(SP) LD B,(HL) ; BC = tiles DEC HL LD C,(HL) DEC HL LD A,(HL-) ; A = h LD H,(HL) ; H = w LD L,A ; L = h CALL .set_xy_wtt POP BC RET ================================================ FILE: libc/set_xy_t.s ================================================ .include "global.s" ;; BANKED: checked, imperfect .area _BASE ;; Set window tile table from BC at XY = DE of size WH = HL ;; wh >= (1,1) .set_xy_wtt:: PUSH HL ; Store WH LDH A,(.LCDC) BIT 6,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .set_xy_tt 1$: LD HL,#0x9C00 ; HL = origin JR .set_xy_tt ;; Set background tile table from (BC) at XY = DE of size WH = HL ;; WH >= (1,1) .set_xy_btt:: PUSH HL ; Store WH LDH A,(.LCDC) BIT 3,A JR NZ,1$ LD HL,#0x9800 ; HL = origin JR .set_xy_tt 1$: LD HL,#0x9C00 ; HL = origin ; JR .set_xy_tt .set_xy_tt:: PUSH BC ; Store source XOR A OR E JR Z,2$ LD BC,#0x20 ; One line is 20 tiles 1$: ADD HL,BC ; Y coordinate DEC E JR NZ,1$ 2$: LD B,#0x00 ; X coordinate LD C,D ADD HL,BC POP BC ; BC = source POP DE ; DE = WH PUSH HL ; Store origin PUSH DE ; Store WH 3$: LDH A,(.STAT) AND #0x02 JR NZ,3$ LD A,(BC) ; Copy W tiles LD (HL+),A INC BC DEC D JR NZ,3$ POP HL ; HL = WH LD D,H ; Restore D = W POP HL ; HL = origin DEC E JR Z,4$ PUSH BC ; Next line LD BC,#0x20 ; One line is 20 tiles ADD HL,BC POP BC PUSH HL ; Store current origin PUSH DE ; Store WH JR 3$ 4$: RET _set_tiles:: PUSH BC LDA HL,11(SP) ; Skip return address and registers LD B,(HL) ; BC = src DEC HL LD C,(HL) DEC HL LD D,(HL) ; DE = dst DEC HL LD E,(HL) LDA HL,4(SP) ; Skip return address and registers PUSH DE ; Store address on stack for set_xy_tt LD D,(HL) ; D = x INC HL LD E,(HL) ; E = y INC HL LD A,(HL+) ; A = w LD L,(HL) ; L = h LD H,A ; H = w CALL .set_xy_tt POP BC RET ================================================ FILE: libc/sfr.s ================================================ .area _SFR (ABS) .org 0xFF00 _P1_REG:: ; Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ .ds 1 .org 0xFF01 _SB_REG:: ; Serial IO data buffer */ .ds 1 .org 0xFF02 _SC_REG:: ; Serial IO control register */ .ds 1 .org 0xFF04 _DIV_REG:: ; Divider register */ .ds 1 .org 0xFF05 _TIMA_REG:: ; Timer counter */ .ds 1 .org 0xFF06 _TMA_REG:: ; Timer modulo */ .ds 1 .org 0xFF07 _TAC_REG:: ; Timer control */ .ds 1 .org 0xFF0F _IF_REG:: ; Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ .ds 1 .org 0xFF10 _NR10_REG:: ; Sound register */ .ds 1 .org 0xFF11 _NR11_REG:: ; Sound register */ .ds 1 .org 0xFF12 _NR12_REG:: ; Sound register */ .ds 1 .org 0xFF13 _NR13_REG:: ; Sound register */ .ds 1 .org 0xFF14 _NR14_REG:: ; Sound register */ .ds 1 .org 0xFF16 _NR21_REG:: ; Sound register */ .ds 1 .org 0xFF17 _NR22_REG:: ; Sound register */ .ds 1 .org 0xFF18 _NR23_REG:: ; Sound register */ .ds 1 .org 0xFF19 _NR24_REG:: ; Sound register */ .ds 1 .org 0xFF1A _NR30_REG:: ; Sound register */ .ds 1 .org 0xFF1B _NR31_REG:: ; Sound register */ .ds 1 .org 0xFF1C _NR32_REG:: ; Sound register */ .ds 1 .org 0xFF1D _NR33_REG:: ; Sound register */ .ds 1 .org 0xFF1E _NR34_REG:: ; Sound register */ .ds 1 .org 0xFF20 _NR41_REG:: ; Sound register */ .ds 1 .org 0xFF21 _NR42_REG:: ; Sound register */ .ds 1 .org 0xFF22 _NR43_REG:: ; Sound register */ .ds 1 .org 0xFF23 _NR44_REG:: ; Sound register */ .ds 1 .org 0xFF24 _NR50_REG:: ; Sound register */ .ds 1 .org 0xFF25 _NR51_REG:: ; Sound register */ .ds 1 .org 0xFF26 _NR52_REG:: ; Sound register */ .ds 1 .org 0xFF40 _LCDC_REG:: ; LCD control */ .ds 1 .org 0xFF41 _STAT_REG:: ; LCD status */ .ds 1 .org 0xFF42 _SCY_REG:: ; Scroll Y */ .ds 1 .org 0xFF43 _SCX_REG:: ; Scroll X */ .ds 1 .org 0xFF44 _LY_REG:: ; LCDC Y-coordinate */ .ds 1 .org 0xFF45 _LYC_REG:: ; LY compare */ .ds 1 .org 0xFF46 _DMA_REG:: ; DMA transfer */ .ds 1 .org 0xFF47 _BGP_REG:: ; BG palette data */ .ds 1 .org 0xFF48 _OBP0_REG:: ; OBJ palette 0 data */ .ds 1 .org 0xFF49 _OBP1_REG:: ; OBJ palette 1 data */ .ds 1 .org 0xFF4A _WY_REG:: ; Window Y coordinate */ .ds 1 .org 0xFF4B _WX_REG:: ; Window X coordinate */ .ds 1 .org 0xFF4D _KEY1_REG:: ; CPU speed */ .ds 1 .org 0xFF4F _VBK_REG:: ; VRAM bank */ .ds 1 .org 0xFF51 _HDMA1_REG:: ; DMA control 1 */ .ds 1 .org 0xFF52 _HDMA2_REG:: ; DMA control 2 */ .ds 1 .org 0xFF53 _HDMA3_REG:: ; DMA control 3 */ .ds 1 .org 0xFF54 _HDMA4_REG:: ; DMA control 4 */ .ds 1 .org 0xFF55 _HDMA5_REG:: ; DMA control 5 */ .ds 1 .org 0xFF56 _RP_REG:: ; IR port */ .ds 1 .org 0xFF68 _BCPS_REG:: ; BG color palette specification */ .ds 1 .org 0xFF69 _BCPD_REG:: ; BG color palette data */ .ds 1 .org 0xFF6A _OCPS_REG:: ; OBJ color palette specification */ .ds 1 .org 0xFF6B _OCPD_REG:: ; OBJ color palette data .ds 1 .org 0xFF70 _SVBK_REG:: ; WRAM bank */ .ds 1 .org 0xFFFF _IE_REG:: ; Interrupt enable */ .ds 1 ================================================ FILE: libc/sgb.s ================================================ .include "global.s" .PAL_01 = 0x00 .PAL_23 = 0x01 .PAL_03 = 0x02 .PAL_12 = 0x03 .ATTR_BLK = 0x04 .ATTR_LIN = 0x05 .ATTR_DIV = 0x06 .ATTR_CHR = 0x07 .SOUND = 0x08 .SOU_TRN = 0x09 .PAL_SET = 0x0A .PAL_TRN = 0x0B .ATRC_EN = 0x0C .TEST_EN = 0x0D .ICON_EN = 0x0E .DATA_SND = 0x0F .DATA_TRN = 0x10 .MLT_REQ = 0x11 .JUMP = 0x12 .CHR_TRN = 0x13 .PCT_TRN = 0x14 .ATTR_TRN = 0x15 .ATTR_SET = 0x16 .MASK_EN = 0x17 .OBJ_TRN = 0x18 .area _CODE ;; Check if running on SGB ;; Set A to 0xFF when running on SGB ;; Clear A when running on DMG .sgb_check:: _sgb_check:: ; Banked LD HL,#.MLT_REQ_2 CALL .sgb_transfer CALL .wait4 LDH A,(.P1) AND #0x03 CP #0x03 JR NZ,.sgb_mode LD A,#0x20 ; Controller read (dummy) LDH (.P1),A LDH A,(.P1) LDH A,(.P1) CPL AND #0x0F SWAP A LD B,A LD A,#0x30 LDH (.P1),A LD A,#0x10 LDH (.P1),A LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LDH A,(.P1) LD A,#0x30 LDH (.P1),A LDH A,(.P1) AND #0x03 CP #0x03 JR NZ,.sgb_mode .dmg_mode: ; LD HL,#.MLT_REQ_1 ; CALL .sgb_transfer ; CALL .wait4 XOR A RET .sgb_mode: LD HL,#.MLT_REQ_1 CALL .sgb_transfer CALL .wait4 LD A,#0xFF RET .sgb_transfer:: LD A,(HL) ; Top of command data AND #0x03 RET Z LD B,A ; Number of translated packet LD C,#0x00 ; Lower part of #FF00 1$: PUSH BC XOR A ; Start to write LDH (C),A LD A,#0x30 LDH (C),A LD B,#0x10 ; Set counter to transfer 16 byte 2$: LD E,#0x08 ; Set counter to transfer 8 bit LD A,(HL+) LD D,A 3$: BIT 0,D LD A,#0x10 ; P14 = high, P15 = low (output "1") JR NZ,4$ LD A,#0x20 ; P14 = low, P15 = high (output "0") 4$: LDH (C),A LD A,#0x30 ; P14 = high, P15 = high LDH (C),A RR D ; Shift 1 bit to right DEC E JR NZ,3$ DEC B JR NZ,2$ LD A,#0x20 ; 129th bit "0" output LDH (C),A LD A,#0x30 LDH (C),A POP BC DEC B RET Z CALL .wait4 ; Software wait for about 4 frames JR 1$ .wait4: LD DE,#7000 1$: NOP ; 1 + NOP ; 1 + NOP ; 1 + DEC DE ; 2 + LD A,D ; 1 + OR E ; 1 + JR NZ,1$ ; 3 = 10 cycles RET .MLT_REQ_1: .byte .MLT_REQ*8|1,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .MLT_REQ_2: .byte .MLT_REQ*8|1,0x01,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ================================================ FILE: libc/stubs.rasm ================================================ GLOBAL STACK GLOBAL OAM GLOBAL refresh_OAM SECTION "stubs_1", BSS[$C000] OAM: DS $A0 SECTION "stubs_2", HRAM[$FF80] refresh_OAM: SECTION "stubs_4", BSS[$E000] STACK: