Managed to make it print text xD
This commit is contained in:
parent
f7a7195a1b
commit
8a6794b54e
11 changed files with 402 additions and 59 deletions
BIN
assets/page1.chr
BIN
assets/page1.chr
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
@ECHO off
|
||||
|
||||
:begin
|
||||
|
||||
ECHO.
|
||||
ECHO Compiling main.asm
|
||||
ECHO rgbasm -o main.o main.asm
|
||||
|
@ -14,9 +16,9 @@ IF %ERRORLEVEL% NEQ 0 (
|
|||
|
||||
ECHO.
|
||||
ECHO Linking main.o
|
||||
ECHO rgblink -o test.gb main.o
|
||||
ECHO rgblink -o test.gb -m test.map -n test.sym main.o
|
||||
|
||||
C:\Users\jonatan.SAMSYN\Documents\gb\tools\compiler\rgblink -o test.gb main.o
|
||||
C:\Users\jonatan.SAMSYN\Documents\gb\tools\compiler\rgblink -o test.gb -m test.map -n test.sym main.o
|
||||
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
ECHO.
|
||||
|
@ -43,3 +45,5 @@ ECHO DONE
|
|||
:eof
|
||||
ECHO.
|
||||
PAUSE
|
||||
|
||||
GOTO begin
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
INCLUDE "game/string.asm"
|
||||
INCLUDE "game/text.asm"
|
||||
|
||||
SECTION "Game Loop", ROM0
|
||||
|
||||
GameLoop:
|
||||
ld b, 0
|
||||
ld c, 0
|
||||
ld hl, HelloWorldStr
|
||||
call PrintString
|
||||
.lockup
|
||||
.wait
|
||||
ld a, [rLY] ; Load the current vertical line being rendered
|
||||
cp 144 ; Check if we're past VBlank (1 to 144 = carry bit set)
|
||||
jr c, .lockup ; Jump back to waitVBlank if rLY is less than 144
|
||||
jr .lockup
|
||||
jr c, .wait ; Jump back to waitVBlank if rLY is less than 144
|
||||
|
||||
ld de, HelloWorldStr
|
||||
call StartText
|
||||
.mainloop
|
||||
; Start our game loop
|
||||
call DrawActiveText
|
||||
call WaitVBlank
|
||||
jr .mainloop
|
||||
|
||||
Section "Hello wrold string", ROM0
|
||||
|
||||
HelloWorldStr:
|
||||
db "Hello, Worl'd.!?", 0
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
SECTION "String code", ROM0
|
||||
; Print String on screen
|
||||
; @param b - PosX on where to draw text
|
||||
; @param c - PosY on where to draw text
|
||||
; @param hl - Address source string
|
||||
; @return a
|
||||
; @return b
|
||||
; @return c
|
||||
; @return de - Destination memory in map
|
||||
; @return hl = Address Target to the byte after the last byte on the target (garbage)
|
||||
PrintString:
|
||||
ld de, $9800
|
||||
.start
|
||||
ld a, [hl] ; Load the first byte in the string
|
||||
inc hl ; Increment immediately to next space
|
||||
ld [dei], a
|
||||
and a
|
||||
jr nz, .start
|
||||
ret
|
||||
.render
|
||||
.finish
|
||||
inc b
|
||||
cp b, 14
|
||||
|
||||
|
190
game/text.asm
Normal file
190
game/text.asm
Normal file
|
@ -0,0 +1,190 @@
|
|||
SECTION "ram_textwriter", WRAM0
|
||||
textwriter_curtext: ds 2
|
||||
textwriter_curletter: ds 1
|
||||
textwriter_posx: ds 1
|
||||
textwriter_posy: ds 1
|
||||
textwriter_curdelay: ds 1
|
||||
textwriter_active: ds 1
|
||||
|
||||
SECTION "ram_textmap", ROM0,ALIGN[8]
|
||||
textwriter_map:
|
||||
; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 0
|
||||
; 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 16
|
||||
; 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
|
||||
db $00,$41,$00,$00,$00,$00,$00,$43,$00,$00,$00,$00,$42,$00,$3F,$00 ; 32
|
||||
; 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
|
||||
db $35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$00,$00,$00,$00,$00,$40 ; 48
|
||||
; 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
|
||||
db $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F ; 64
|
||||
; 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
|
||||
db $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$00,$00,$00,$00,$00 ; 80
|
||||
; 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
|
||||
db $00,$1B,$1C,$1D,$1E,$1F,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29 ; 96
|
||||
; 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
|
||||
db $2A,$2B,$2C,$2D,$2E,$2F,$30,$31,$32,$33,$34,$00,$00,$00,$00,$00 ; 112
|
||||
|
||||
SECTION "TextWriter", ROM0
|
||||
|
||||
; Start to print a string on screen
|
||||
; @param b - PosX on where to draw text
|
||||
; @param c - PosY on where to draw text
|
||||
; @param de - Address source string
|
||||
; @return a - garbage
|
||||
; @return b - PosX on where to draw text
|
||||
; @return c - PosY on where to draw text
|
||||
; @return hl - Workram position for text pointer
|
||||
; @return de - Memory address to source string
|
||||
StartText:
|
||||
ld a, 0
|
||||
ld [textwriter_curletter], a
|
||||
ld [textwriter_curdelay], a
|
||||
ld a, 1
|
||||
ld [textwriter_active], a
|
||||
ld [textwriter_posx], a
|
||||
ld [textwriter_posy], a
|
||||
ld hl, textwriter_curtext
|
||||
ld a, d
|
||||
ld [hli], a
|
||||
ld a, e
|
||||
ld [hl], a
|
||||
dec hl
|
||||
ret
|
||||
|
||||
; Draw text if one is currently active
|
||||
; @return a - 0 if not active, 1 if active
|
||||
DrawActiveText:
|
||||
ld a, [textwriter_active] ; Check if text is currently active
|
||||
and a
|
||||
jr z, .exit
|
||||
|
||||
; Delay writing a letter by 10 frames
|
||||
ld a, [textwriter_curdelay]
|
||||
inc a
|
||||
ld [textwriter_curdelay], a
|
||||
cp 20
|
||||
jr c, .exit
|
||||
|
||||
; Reset the curdelay
|
||||
ld a, 0
|
||||
ld [textwriter_curdelay], a
|
||||
|
||||
; Get the memory address pointing to the text currently being
|
||||
; displayed. This is stored in textwriter_curtext
|
||||
ld hl, textwriter_curtext ; Get the memory address of the pointer
|
||||
ld d, [hl] ; Store the first byte address to d
|
||||
inc hl ; Move to next byte
|
||||
ld e, [hl] ; Store the next byte address to e
|
||||
; We now have the current letter being drawn at [de]
|
||||
|
||||
ld hl, _SCRN0 ; Load the top-left map position to our map
|
||||
ld a, [textwriter_posy]
|
||||
ld c, a
|
||||
ld a, [textwriter_posx]
|
||||
ld b, a
|
||||
.moveyaxis
|
||||
; Our first objective is to position the text to correct position
|
||||
; We do so shifting the position by $20 for each y axis
|
||||
; and position by $01 for each x axis that needs movement
|
||||
ld a, c ; Load the y position to our accumilator
|
||||
and a ; Check if it's zero
|
||||
jr z, .movexaxis ; Jump to x axis if it's zero and no moving necessary
|
||||
ld a, l ; Load the first half of the destination position
|
||||
add a, $20 ; Add $20 (one vertical line)
|
||||
ld l, a ; Store the position back
|
||||
ld a, h ; Grab the second part of the address
|
||||
adc a, $00 ; Add only the accumilator
|
||||
ld h, a ; Store the position back
|
||||
dec c ; Decrement our y parameter
|
||||
jr .moveyaxis ; Repeat
|
||||
.movexaxis
|
||||
; Now we check and move the position based on the x position
|
||||
ld a, b ; Load the x position to our accimulator
|
||||
and a ; Check if it's zero
|
||||
jr z, .drawletter ; Jump to drawletter if it's zero already
|
||||
inc hl ; Increment the map position by one since we need to move by x position
|
||||
dec b ; Decrement our x parameter
|
||||
jr .movexaxis ; Repeat
|
||||
.drawletter
|
||||
ld a, [de] ; Load the first byte in the string
|
||||
ld bc, textwriter_map
|
||||
ld c, a
|
||||
ld a, [bc]
|
||||
ld [hl], a ; Print the character byte directly onto the map
|
||||
|
||||
ld a, [de]
|
||||
and a ; Check if we reached the end
|
||||
jr nz, .continue
|
||||
; We have reached the end of the string, disable textwriter
|
||||
ld a, 0
|
||||
ld [textwriter_active], a
|
||||
.continue
|
||||
; Time to update our work ram
|
||||
; Load the position pointer of current text to next letter
|
||||
ld hl, textwriter_curtext
|
||||
inc de ; Increment to next letter in string
|
||||
ld a, d
|
||||
ld [hli], a
|
||||
ld a, e
|
||||
ld [hl], a
|
||||
; Update the x position in ram
|
||||
ld a, [textwriter_posx]
|
||||
inc a
|
||||
ld [textwriter_posx], a
|
||||
; Update the current letter being drawn in ram
|
||||
ld a, [textwriter_curletter]
|
||||
inc a
|
||||
ld [textwriter_curletter], a
|
||||
|
||||
.exit
|
||||
ld a, [textwriter_active]
|
||||
ret
|
||||
|
||||
|
||||
; Print String on screen
|
||||
; @param b - PosX on where to draw text
|
||||
; @param c - PosY on where to draw text
|
||||
; @param de - Address source string
|
||||
; @return a
|
||||
; @return b
|
||||
; @return c
|
||||
; @return hl - Destination memory in map
|
||||
; @return hl = Address Target to the byte after the last byte on the target (garbage)
|
||||
PrintString:
|
||||
ld hl, _SCRN0 ; Load the top-left map position to our map
|
||||
.moveyaxis2
|
||||
; Our first objective is to position the text to correct position
|
||||
; We do so shifting the position by $20 for each y axis
|
||||
; and position by $01 for each x axis that needs movement
|
||||
ld a, c ; Load the y position to our accumilator
|
||||
and a ; Check if it's zero
|
||||
jr z, .movexaxis2 ; Jump to x axis if it's zero and no moving necessary
|
||||
ld a, l ; Load the first half of the destination position
|
||||
add a, $20 ; Add $20 (one vertical line)
|
||||
ld l, a ; Store the position back
|
||||
ld a, b ; Grab the second part of the address
|
||||
adc a, $00 ; Add only the accumilator
|
||||
ld b, a ; Store the position back
|
||||
dec c ; Decrement our y parameter
|
||||
jr .moveyaxis2 ; Repeat
|
||||
.movexaxis2
|
||||
; Now we check and move the position based on the x position
|
||||
ld a, b ; Load the x position to our accimulator
|
||||
and a ; Check if it's zero
|
||||
jr z, .start2 ; Jump to start2 if it's zero already
|
||||
inc hl ; Increment the map position by one since we need to move by x position
|
||||
dec b ; Decrement our x parameter
|
||||
jr .movexaxis2 ; Repeat
|
||||
.start2
|
||||
ld a, [de] ; Load the first byte in the string
|
||||
ld [hl], a ; Write the byte from the accumilator to the destination address
|
||||
; Also increment destination by one.
|
||||
; This effectively prints the character byte in accumilator
|
||||
inc de ; Increment to next byte in string
|
||||
inc hl
|
||||
and a ; And together a with itself. This sets the flag
|
||||
jr nz, .start2 ; Go back to start if we didn't just copy a zero.
|
||||
ret
|
||||
|
||||
|
47
main.asm
47
main.asm
|
@ -2,10 +2,21 @@ INCLUDE "hardware.inc"
|
|||
INCLUDE "game/game.asm"
|
||||
INCLUDE "tools.asm"
|
||||
|
||||
SECTION "InterruptVblank", ROM0[$0040]
|
||||
reti
|
||||
SECTION "InterruptLCDC", ROM0[$0048]
|
||||
reti
|
||||
SECTION "InterruptTimer_Overflow", ROM0[$0050]
|
||||
reti
|
||||
SECTION "InterruptSerial", ROM0[$0058]
|
||||
reti
|
||||
SECTION "Interruptp1thru4", ROM0[$0060]
|
||||
reti
|
||||
|
||||
SECTION "Header", ROM0[$100]
|
||||
|
||||
EntryPoint: ;
|
||||
di ; Disable interrupts. That way we can avoid dealing with them, especially since we didn't talk about them yet
|
||||
ei ; Simple nop ; di ; Disable interrupts for now
|
||||
jp Start ; Leave this tiny space
|
||||
|
||||
REPT $150 - $104
|
||||
|
@ -21,9 +32,9 @@ Start:
|
|||
|
||||
; Turn off the LCD
|
||||
.waitVBlank
|
||||
ld a, [rLY] ; Load the current vertical line being rendered
|
||||
cp 144 ; Check if we're past VBlank (1 to 144 = carry bit set)
|
||||
jr c, .waitVBlank ; Jump back to waitVBlank if rLY is less than 144
|
||||
ld a, $01
|
||||
ld [$FFFF], a ; Force enable VBLANK Interrupt
|
||||
halt
|
||||
|
||||
xor a ; ld a, 0 ; Reset the accumilator register
|
||||
; Our target is to set bit 7 reset on the LDC to turn it off
|
||||
|
@ -31,21 +42,11 @@ Start:
|
|||
|
||||
; ----------- Font Begin copying to VRAM -----------
|
||||
; Start copying our font to vram
|
||||
ld de, FontTiles ; The start of the font tiles
|
||||
ld de, Page1 ; The start of the font tiles
|
||||
ld hl, $9000 ; Set registers hl to $9000 which is the beginning of vram
|
||||
ld bc, FontTilesEnd - FontTiles ; The total length of font tiles
|
||||
ld bc, Page1End - Page1 ; The total length of font tiles
|
||||
call Memcpy
|
||||
|
||||
; ----------- Begin copying string to palette -----------
|
||||
ld hl, $9800 ; This will print the string at the top-left corner of screen
|
||||
ld de, HelloWorldStr
|
||||
.copyString
|
||||
ld a, [de] ; Read the first byte in the string to accumilator
|
||||
ld [hli], a ; Write the byte from the accumilator to the destination while incrementing destination address
|
||||
inc de ; Move to next byte in string
|
||||
and a ; AND a with A, Checking if we copied a zero (end of string)
|
||||
jr nz, .copyString ; Continue copying while not zero
|
||||
|
||||
; ----------- Start the display -----------
|
||||
; Init the display register
|
||||
ld a, %11100100 ; Load the palette of white, light gray, dark gray, black
|
||||
|
@ -59,17 +60,15 @@ Start:
|
|||
ld [rNR52], a ; Turn off sound
|
||||
|
||||
; Turn the screen on, display background
|
||||
ld a, %10000001 ; screen on = 8th bit, background display = 1st bit
|
||||
ld a, LCDCF_ON|LCDCF_BGON
|
||||
; ld a, %10000001 ; screen on = 8th bit, background display = 1st bit
|
||||
ld [rLCDC], a ; Set the screen flags
|
||||
ei ; Enable interrupts again?
|
||||
jp GameLoop
|
||||
|
||||
SECTION "Font", ROM0
|
||||
|
||||
FontTiles:
|
||||
INCBIN "font.chr"
|
||||
FontTilesEnd:
|
||||
Page1:
|
||||
INCBIN "assets/page1.chr"
|
||||
Page1End:
|
||||
|
||||
Section "Hello wrold string", ROM0
|
||||
|
||||
HelloWorldStr:
|
||||
db "Hello World!", 0
|
||||
|
|
BIN
main.o
BIN
main.o
Binary file not shown.
BIN
test.gb
BIN
test.gb
Binary file not shown.
128
test.map
Normal file
128
test.map
Normal file
|
@ -0,0 +1,128 @@
|
|||
ROM Bank #0 (HOME):
|
||||
SECTION: $0200-$027F ($0080 bytes) ["ram_textmap"]
|
||||
$0200 = textwriter_map
|
||||
SECTION: $0150-$01F5 ($00A6 bytes) ["TextWriter"]
|
||||
$01D0 = DrawActiveText.exit
|
||||
$01A2 = DrawActiveText.movexaxis
|
||||
$0193 = DrawActiveText.moveyaxis
|
||||
$01AA = DrawActiveText.drawletter
|
||||
$01BA = DrawActiveText.continue
|
||||
$01E6 = PrintString.movexaxis2
|
||||
$01D7 = PrintString.moveyaxis2
|
||||
$01EE = PrintString.start2
|
||||
$0150 = StartText
|
||||
$016C = DrawActiveText
|
||||
SECTION: $0061-$0074 ($0014 bytes) ["Game Loop"]
|
||||
$0061 = GameLoop.wait
|
||||
$006D = GameLoop.mainloop
|
||||
$0061 = GameLoop
|
||||
SECTION: $0075-$0085 ($0011 bytes) ["Hello wrold string"]
|
||||
$0075 = HelloWorldStr
|
||||
SECTION: $0031-$003C ($000C bytes) ["Tools"]
|
||||
$003A = WaitVBlank
|
||||
$0031 = Memcpy
|
||||
SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"]
|
||||
SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"]
|
||||
SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"]
|
||||
SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"]
|
||||
SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"]
|
||||
SECTION: $0100-$014F ($0050 bytes) ["Header"]
|
||||
SECTION: $0000-$0030 ($0031 bytes) ["Intro code"]
|
||||
$0000 = Start
|
||||
$0000 = Start.waitVBlank
|
||||
SECTION: $0280-$127F ($1000 bytes) ["Font"]
|
||||
$0280 = Page1
|
||||
$1280 = Page1End
|
||||
SLACK: $2E23 bytes
|
||||
|
||||
WRAM Bank #0:
|
||||
SECTION: $C000-$C006 ($0007 bytes) ["ram_textwriter"]
|
||||
$C002 = textwriter_curletter
|
||||
$C005 = textwriter_curdelay
|
||||
$C006 = textwriter_active
|
||||
$C003 = textwriter_posx
|
||||
$C004 = textwriter_posy
|
||||
$C000 = textwriter_curtext
|
||||
SLACK: $0FF9 bytes
|
||||
|
||||
WRAM Bank #1:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #2:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #3:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #4:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #5:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #6:
|
||||
EMPTY
|
||||
|
||||
WRAM Bank #7:
|
||||
EMPTY
|
||||
|
||||
VRAM Bank #0:
|
||||
EMPTY
|
||||
|
||||
VRAM Bank #1:
|
||||
EMPTY
|
||||
|
||||
OAM:
|
||||
EMPTY
|
||||
|
||||
HRAM:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #0:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #1:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #2:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #3:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #4:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #5:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #6:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #7:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #8:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #9:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #10:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #11:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #12:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #13:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #14:
|
||||
EMPTY
|
||||
|
||||
SRAM Bank #15:
|
||||
EMPTY
|
||||
|
29
test.sym
Normal file
29
test.sym
Normal file
|
@ -0,0 +1,29 @@
|
|||
; File generated by rgblink
|
||||
|
||||
00:0200 textwriter_map
|
||||
00:01D0 DrawActiveText.exit
|
||||
00:01A2 DrawActiveText.movexaxis
|
||||
00:0193 DrawActiveText.moveyaxis
|
||||
00:01AA DrawActiveText.drawletter
|
||||
00:01BA DrawActiveText.continue
|
||||
00:01E6 PrintString.movexaxis2
|
||||
00:01D7 PrintString.moveyaxis2
|
||||
00:01EE PrintString.start2
|
||||
00:0150 StartText
|
||||
00:016C DrawActiveText
|
||||
00:0061 GameLoop.wait
|
||||
00:006D GameLoop.mainloop
|
||||
00:0061 GameLoop
|
||||
00:0075 HelloWorldStr
|
||||
00:003A WaitVBlank
|
||||
00:0031 Memcpy
|
||||
00:0000 Start
|
||||
00:0000 Start.waitVBlank
|
||||
00:0280 Page1
|
||||
00:1280 Page1End
|
||||
00:C002 textwriter_curletter
|
||||
00:C005 textwriter_curdelay
|
||||
00:C006 textwriter_active
|
||||
00:C003 textwriter_posx
|
||||
00:C004 textwriter_posy
|
||||
00:C000 textwriter_curtext
|
10
tools.asm
10
tools.asm
|
@ -17,3 +17,13 @@ Memcpy:
|
|||
or c ; OR together the second half of total amount with the first half
|
||||
jr nz, Memcpy ; Loop back to Memcpy if not zero
|
||||
ret
|
||||
|
||||
|
||||
;;
|
||||
; Waits for the vblank ISR to increment the count of vertical blanks.
|
||||
; Will lock up if DI, vblank IRQ off, or LCD off.
|
||||
; Clobbers A, HL
|
||||
WaitVBlank:
|
||||
.wait
|
||||
halt
|
||||
ret
|
||||
|
|
Loading…
Reference in a new issue