From d2dd0b4d741eb503c670390737b621ed1dd9beee Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Mon, 23 Mar 2026 19:13:35 +0100 Subject: [PATCH 1/1] Initial commit --- .gitattributes | 1 + .gitignore | 79 ++++++++++++++++++++++++++++++ .gitmodules | 3 ++ BUGS.md | 2 + LICENSE | 18 +++++++ README.md | 32 +++++++++++++ TODO.md | 3 ++ gen/gen.s | 0 makefile | 27 +++++++++++ src/header.s | 22 +++++++++ src/hw.s | 122 +++++++++++++++++++++++++++++++++++++++++++++++ src/jmp.s | 46 ++++++++++++++++++ src/macros.s | 5 ++ src/main.s | 17 +++++++ tools/png2chr.py | 85 +++++++++++++++++++++++++++++++++ tools/tmx2map.py | 52 ++++++++++++++++++++ 16 files changed, 514 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 BUGS.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 TODO.md create mode 100644 gen/gen.s create mode 100644 makefile create mode 100644 src/header.s create mode 100644 src/hw.s create mode 100644 src/jmp.s create mode 100644 src/macros.s create mode 100644 src/main.s create mode 100755 tools/png2chr.py create mode 100755 tools/tmx2map.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cac7d12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# Build directory +bin/ +obj/ +tags + + Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb +vgcore.* + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +compile_commands.json +.cache/ +.clang_complete +.clangd +.session + +assets/ +*.pyc + +pj.gb +pj.mlb +pj.lst +testpj.gb +testrg.mlb +testrg.lst + +*.sav +*.patch +*.sym +debugrc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3566de2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "assets"] + path = assets + url = ssh://git@codeberg.org/unlink2/gbrg-assets.git diff --git a/BUGS.md b/BUGS.md new file mode 100644 index 0000000..97fed4b --- /dev/null +++ b/BUGS.md @@ -0,0 +1,2 @@ +# Known Bugs + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5e5b158 --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +Copyright 2025-2026 Lukas Krickl (lukas@krickl.dev) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, +including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", +WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f49103 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# picojump + +## Table of content + +- [Installation](#Installation) +- [Usage](#Usage) +- [License](#License) +- [Contributing](#Contributing) +- [TODO](#TODO) + +## Installation + +To compile this game you will need a copy of `ulas`. +Then simply run `make` to build the rom. + +## Usage + +This game is compatible with any gameboy emulator. + +### Building assets + +### Directory structure + +- src: all source files +- gen/gen.s: include file for all generated files +- gen: generated source files based on assets + +## License + +This program is distributed under the terms of the MIT License. + + diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..6bd48d0 --- /dev/null +++ b/TODO.md @@ -0,0 +1,3 @@ +# TODO + + diff --git a/gen/gen.s b/gen/gen.s new file mode 100644 index 0000000..e69de29 diff --git a/makefile b/makefile new file mode 100644 index 0000000..5b9affc --- /dev/null +++ b/makefile @@ -0,0 +1,27 @@ +NAME=pj +TEST_NAME=test$(NAME) +AS=ulas +FLAGS=-D DEBUG +#SYMTYPE=sym +SYMTYPE=mlb +INCS=-I ./src -I ./gen + +bin: + $(AS) $(FLAGS) -o $(NAME).gb -l ${NAME}.lst -s $(NAME).$(SYMTYPE) -S $(SYMTYPE) $(INCS) src/main.s + +.PHONY: tiles +tiles: + ./tools/png2chr.py assets/tiles/bank8000.png > gen/tiles/bank8000.inc + ./tools/png2chr.py assets/tiles/bank8800.png > gen/tiles/bank8800.inc + ./tools/png2chr.py assets/tiles/bank8C00.png > gen/tiles/bank8C00.inc + ./tools/png2chr.py assets/tiles/bank9000.png > gen/tiles/bank9000.inc + +.PHONY: maps +maps: + ./tools/tmx2map.py assets/maps/l1.tmx > gen/maps/l1.inc + +.PHONY: clean +clean: + rm -f ./gen/maps/*.inc + rm -f ./gen/tiles/*.inc + diff --git a/src/header.s b/src/header.s new file mode 100644 index 0000000..14bb7a3 --- /dev/null +++ b/src/header.s @@ -0,0 +1,22 @@ +; header + jp entry + nop +logo: +.db 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D +.db 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99 +.db 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E +logo_end: + +.str "tb" +.fill 0, 0x147 - $ + +; cartride type +; MBC1+RAM+Battery +.db 0x03 + ; rom size 32K +.db 0x00 + ; ram size 8k +.db 0x02 +.fill 0, 0x14B - $ +.chksm +.fill 0, 0x150 - $ diff --git a/src/hw.s b/src/hw.s new file mode 100644 index 0000000..4aa02f3 --- /dev/null +++ b/src/hw.s @@ -0,0 +1,122 @@ +; register defs + +#define SCRNW 159 +#define SCRNH 143 + +; lcd registers + +; lcd y +#define RLY 0xFF44 +#define RLYC 0xFF45 +#define RLCD 0xFF40 + +#define LCDCF_BGON 0b00000001 +#define LCDCF_ON 0b10000000 +#define LCDCF_OBJON 0b00000010 +#define LCDCF_TILE_BANK 0b00010000 +#define LCDF_WINDOWON 0b00100000 +#define LCDF_OBJ_SIZE 0b00000100 +#define LCDF_WINBANKSELECT 0b01000000 + +#define RSTAT 0xFF41 + +#define STATF_LYC_INT_SELECT 0b01000000 + +#define RBGP 0xFF47 +#define ROBP0 0xFF48 +#define ROBP1 0xFF49 + +; screen scroll y and x +#define RSCY 0xFF42 +#define RSCX 0xFF43 + +; window y and x +#define RWY 0xFF4A +#define RWX 0xFF4B + +; P1: joy pad register +#define RP1 0xFF00 +#define P1F5 0b00100000 ; get buttons +#define P1F4 0b00010000 ; get dpad + +; buttons +.def int BTNDOWN = 0x80 +.def int BTNUP = 0x40 +.def int BTNLEFT = 0x20 +.def int BTNRIGHT = 0x10 +.def int BTNSTART = 0x08 +.def int BTNSELECT = 0x04 +.def int BTNA = 0x01 +.def int BTNB = 0x02 + +; obj off-screen offsets +#define OBJ_OFF_X 8 +#define OBJ_OFF_Y 16 + +; interrupts +; interrupt flag +#define IF 0xFF0F +; interrupt enabled +#define IE 0xFFFF +#define IVBLANK 0b00000001 +#define ILCD 0b00000010 + +; location where code for dma needs to be memcyp'd to +.def int DMAFN = 0xFF80 +#define DMA 0xFF46 + +#define OBJSMAX 40 + +.def int P1FDPAD = P1F5 +.def int P1FBTN = P1F4 +.def int P1FNONE = P1F5 | P1F4 + +; memory map +.def int VRAM = 0x8000 +.def int VRAM8800 = VRAM+0x0800 +.def int VRAM9000 = VRAM+0x1000 + +.def int VIEW_W = 20 +.def int VIEW_H = 20 +.def int SCRN_W = 32 +.def int SCRN_H = 32 + +.def int SCRN0 = 0x9800 +.def int SCRN0_UI = SCRN0 + SCRN_W * 16 + +.def int SCRN1 = 0x9C00 +.def int OAMRAM = 0xFE00 +.def int OBJSIZE = 4 +.def int OAMRAM_SIZE = OBJSMAX * OBJSIZE + +.def int OAM_FPRIO = 0b10000000 +#define OAM_FYFLIP 0b01000000 +#define OAM_FXFLIP 0b00100000 +#define OAM_DMG_PAL 0b00010000 + +; MBC1 registers + +; write 0xA here to enable sram +#define MBC1_SRAM_ENABLE 0x0000 +#define MBC1_ROM_BANKSEL 0x2000 +#define MBC1_SRAM_BANKSEL 0x4000 + +; audio registers +#define AUDIO_CTRL 0xFF26 +#define MASTER_VOLUME 0xFF24 + +#define CH1_SWEEP 0xFF10 +#define CH1_LEN_DUTY 0xFF11 +#define CH1_VOL_ENV 0xFF12 +#define CH1_PERIOD_LO 0xFF13 +#define CH1_PERIOD_HI_CTRL 0xFF14 + +#define CH4_LENGTH 0xFF20 +#define CH4_VOLUME_ENV 0xFF21 +#define CH4_FREQ_RAND 0xFF22 +#define CH4_CTRL 0xFF23 + +#define AUDIO_ALL_ON 0b10000000 +#define AUDIO_ALL_OFF 0b00000000 + + diff --git a/src/jmp.s b/src/jmp.s new file mode 100644 index 0000000..a5ea738 --- /dev/null +++ b/src/jmp.s @@ -0,0 +1,46 @@ +; RST $00 +; panic exception handler +rst_panic: + di +@forever: + jp @forever +.fill 0, 0x08 - $ + + ; rst 0008 + ; simple call to hl +sys_call_hl: + jp hl + +.fill 0, 0x10 - $ + + ; rst 0010 + ; farcall + ; inputs: + ; a: bank + ; hl: routine ptr +sys_farcall: + ret + + +.fill 0, 0x40 - $ +; interrupt vectors + +;============= +; vblank 0x40 +;============= +vec_vblank: + reti + +.fill 0, 0x48 - $ +;============= +; STA 0x48 +;============= +vec_stat: + reti + ; disable objects + push af + ld a, [RLCD] + and a, ~LCDCF_OBJON & 0xFF + ld [RLCD], a + pop af + reti diff --git a/src/macros.s b/src/macros.s new file mode 100644 index 0000000..c33be9d --- /dev/null +++ b/src/macros.s @@ -0,0 +1,5 @@ + +#define BREAK ld b, b + +; relative jump: jr