CHARACTER_DATA EQU $8000 ; Area for 8 x 8 characters (tiles). BG_DISPLAY_DATA EQU $9800 ; Area for background display data (tilemap). SERIAL_DATA EQU $ff01 SERIAL_CONTROL EQU $ff02 LCD_STATUS EQU $ff41 ; Holds the current LCD controller status. INTERRUPT_ENABLE EQU $ffff LCD_BUSY EQU %00000010 ; LCD controller is busy, CPU has no access. INTERRUPT_ON_VBLANK EQU %00000001 INTERRUPT_ON_SERIAL EQU %00001000 CHARACTER_SIZE EQU (8 * 8 * 2)/8 ; 8 x 8 and 2 bits per pixel (16 bytes). NUMBER_OF_CHARACTERS EQU 2 SERIAL_USE_INT_CLOCK EQU 0 SERIAL_START_TRANSFER EQU 7 SECTION "Vertical blanking interrupt", ROM0[$40] reti SECTION "Serial transfer complete interrupt", ROM0[$58] reti SECTION "ROM Registration Data", ROM0[$100] nop jr enable_interrupts SECTION "Main", ROM0[$150] enable_interrupts: ei use_internal_clock: ld hl, SERIAL_CONTROL set SERIAL_USE_INT_CLOCK, [hl] copy_character_data_to_vram: ld hl, binary_0 ld bc, NUMBER_OF_CHARACTERS * CHARACTER_SIZE ld de, CHARACTER_DATA + CHARACTER_SIZE call copy_to_vram jr print_controller_status.halt_until_vertical_blanking latch_controller: ld a, %11111111 call transfer ld a, %10000000 call transfer print_controller_status: ld hl, BG_DISPLAY_DATA + (9 * $20 + 6) ; center of screen ld a, [SERIAL_DATA] rl a call print_bit rl a call print_bit rl a call print_bit rl a call print_bit rl a call print_bit rl a call print_bit rl a call print_bit rl a call print_bit .halt_until_vertical_blanking: ld a, INTERRUPT_ON_VBLANK ld [INTERRUPT_ENABLE], a halt jr latch_controller print_bit: jr nc, .zero .one: ld [hl], $02 jr .return .zero: ld [hl], $01 .return: inc hl ret transfer: ld [SERIAL_DATA], a ld hl, SERIAL_CONTROL set SERIAL_START_TRANSFER, [hl] .halt_until_serial_transfer_complete: ld a, INTERRUPT_ON_SERIAL ld [INTERRUPT_ENABLE], a halt ret ; ### `copy_to_vram` subroutine ; ; Copy `bc` bytes from `hl` to `de`, assuming destination is `$8000-$9FFF` and ; thus waits for VRAM to be accessible by the CPU. ; ; | Registers | Comments | ; | --------- | ------------------------------------- | ; | `hl` | **parameter** source address | ; | `de` | **parameter** destination address | ; | `bc` | **parameter** number of bytes to copy | ; | `a` | **scratched** used for comparison | ; copy_to_vram: .wait_for_vram: ld a, [LCD_STATUS] and LCD_BUSY jr nz, .wait_for_vram ld a, [hl+] ld [de], a inc de dec bc ld a, c or b jr nz, copy_to_vram ret SECTION "Character data (tiles)", ROM0 pusho opt g.123 binary_0: dw `.33333.. dw `33...33. dw `33..333. dw `33.3333. dw `3333.33. dw `333..33. dw `.33333.. dw `........ binary_1: dw `..33.... dw `.333.... dw `..33.... dw `..33.... dw `..33.... dw `..33.... dw `333333.. dw `........ popo