Monorepo for Aesthetic.Computer aesthetic.computer
at main 83 lines 4.7 kB view raw
1; Background Tilemap Example for the Nintendo Game Boy 2; by Dave VanEe 2022 3; Tested with RGBDS 1.0.0 4; License: CC0 (https://creativecommons.org/publicdomain/zero/1.0/) 5 6include "hardware.inc" ; Include hardware definitions so we can use nice names for things 7 8; Define a section that starts at the point the bootrom execution ends 9SECTION "Start", ROM0[$0100] 10 jp EntryPoint ; Jump past the header space to our actual code 11 12 ds $150-@, 0 ; Allocate space for RGBFIX to insert our ROM header by allocating 13 ; the number of bytes from our current location (@) to the end of the 14 ; header ($150) 15 16EntryPoint: 17 di ; Disable interrupts as we won't be using them 18 ld sp, $e000 ; Set the stack pointer to the end of WRAM 19 20 ; Turn off the LCD when it's safe to do so (during VBlank) 21.waitVBlank 22 ldh a, [rLY] ; Read the LY register to check the current scanline 23 cp SCREEN_HEIGHT_PX ; Compare the current scanline to the first scanline of VBlank 24 jr c, .waitVBlank ; Loop as long as the carry flag is set 25 ld a, 0 ; Once we exit the loop we're safely in VBlank 26 ldh [rLCDC], a ; Disable the LCD (must be done during VBlank to protect the LCD) 27 28 ; Copy our tiles to VRAM 29 ld hl, TileData ; Load the source address of our tiles into HL 30 ld de, STARTOF(VRAM); Load the destination address in VRAM into DE 31 ld bc, TileData.end - TileData ; Load the number of bytes to copy into BC 32.copyLoop 33 ld a, [hl] ; Load a byte from the address HL points to into the A register 34 ld [de], a ; Load the byte in the A register to the address DE points to 35 inc hl ; Increment the source pointer in HL 36 inc de ; Increment the destination pointer in DE 37 dec bc ; Decrement the loop counter in BC 38 ld a, b ; Load the value in B into A 39 or c ; Logical OR the value in A (from B) with C 40 jr nz, .copyLoop ; If B and C are both zero, OR B will be zero, otherwise keep looping 41 42 ; Copy our 20x18 tilemap to VRAM 43 ld de, TilemapData ; Load the source address of our tilemap into DE 44 ld hl, TILEMAP0 ; Point HL to the first byte of the tilemap ($9800) 45 ld b, SCREEN_HEIGHT ; Load the height of the screen in tiles into B (18 tiles) 46.tilemapLoop 47 ld c, SCREEN_WIDTH ; Load the width of the screen in tiles into C (20 tiles) 48.rowLoop 49 ld a, [de] ; Load a byte from the address DE points to into the A register 50 ld [hli], a ; Load the byte in the A register to the address HL points to and increment HL 51 inc de ; Increment the source pointer in DE 52 dec c ; Decrement the loop counter in C (tiles per row) 53 jr nz, .rowLoop ; If C isn't zero, continue copying bytes for this row 54 push de ; Push the contents of the register pair DE to the stack 55 ld de, TILEMAP_WIDTH - SCREEN_WIDTH ; Load the number of tiles remaining in the row into DE 56 add hl, de ; Add the remaining row length to HL, advancing the destination pointer to the next row 57 pop de ; Recover the former contents of the the register pair DE 58 dec b ; Decrement the loop counter in B (total rows) 59 jr nz, .tilemapLoop ; If B isn't zero, continue copying rows 60 61 ; Setup palettes and scrolling 62 ld a, %11100100 ; Define a 4-shade palette from darkest (11) to lightest (00) 63 ldh [rBGP], a ; Set the background palette 64 65 ld a, 0 ; Load zero into the register A 66 ldh [rSCX], a ; Set the background scroll registers to show the top-left 67 ldh [rSCY], a ; corner of the background in the top-left corner of the screen 68 69 ; Combine flag constants defined in hardware.inc into a single value with logical ORs and load it into A 70 ; Note that some of these constants (LCDC_OBJ_OFF, LCDC_WIN_OFF) are zero, but are included for clarity 71 ld a, LCDC_ON | LCDC_BLOCK01 | LCDC_BG_ON | LCDC_OBJ_OFF | LCDC_WIN_OFF 72 ldh [rLCDC], a ; Enable and configure the LCD to show the background 73 74LoopForever: 75 jr LoopForever ; Loop forever 76 77; Tiles from public domain "Abandonauts" tileset by Adam Atomic (http://adamatomic.com/abandonauts/) 78TileData: 79 incbin "abandonauts-tilemap.2bpp" ; Include binary tile data inline using incbin 80.end ; The .end label is used to let the assembler calculate the length of the data 81 82TilemapData: 83 incbin "abandonauts-tilemap.tilemap" ; Both the tiles and tilemap are generated using RGBGFX in the build script