Monorepo for Aesthetic.Computer
aesthetic.computer
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