Skip to content

Instantly share code, notes, and snippets.

@rkachowski
Created February 29, 2016 21:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkachowski/1d20dee5c51528392ecd to your computer and use it in GitHub Desktop.
Save rkachowski/1d20dee5c51528392ecd to your computer and use it in GitHub Desktop.
a gb rom to show an image
; Hello Sprite No Interrupts1.0
; February 19, 2007
; John Harrison
; using sprites without interrupts
; Look at this sprite example first, then look at the example with interrupts
; An extension of Hello World, based mostly from GALP
INCLUDE "gbhw.inc" ; standard hardware definitions from devrs.com
INCLUDE "ibmpc1.inc" ; ASCII character set from devrs.com
INCLUDE "hello-sprite.inc" ; specific defs
; create variables
; LoByteVar xpos ; these are examples of how variables
; LoByteVar spry ; can be created. They are based on a
; LoByteVar sprx ; macro in hello-sprite.inc
SpriteAttr Sprite0 ; this is a structure of 4 variables. See hello-sprite.inc
; IRQs
SECTION "Vblank",HOME[$0040]
reti
SECTION "LCDC",HOME[$0048]
reti
SECTION "Timer_Overflow",HOME[$0050]
reti
SECTION "Serial",HOME[$0058]
reti
SECTION "p1thru4",HOME[$0060]
reti
; ****************************************************************************************
; boot loader jumps to here.
; ****************************************************************************************
SECTION "start",HOME[$0100]
nop
jp begin
; ****************************************************************************************
; ROM HEADER and ASCII character set
; ****************************************************************************************
; ROM header
ROM_HEADER ROM_NOMBC, ROM_SIZE_32KBYTE, RAM_SIZE_0KBYTE
INCLUDE "memory.asm"
toastymofo1_tile_map_size EQU $0400
toastymofo1_tile_map_width EQU $20
toastymofo1_tile_map_height EQU $20
toastymofo1_tile_data_size EQU $02F0
toastymofo1_tile_count EQU $50
; ////////////////
; // //
; // Map Data //
; // //
; ////////////////
toastymofo1_map_data:
DB $00,$01,$02,$02,$02,$03,$04,$02,$02,$02,$02,$02,$05,$02,$02,$02
DB $02,$02,$02,$06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F,$10,$11,$12,$13,$14,$15,$16
DB $17,$18,$19,$1A,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $1B,$1C,$1D,$1E,$1F,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A
DB $2B,$2C,$2D,$2E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
DB $02,$02,$02,$02,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
; /////////////////
; // //
; // Tile Data //
; // //
; /////////////////
toastymofo1_tile_data:
DB $00,$00,$00,$00,$00,$00,$08,$0C,$0C,$08,$0C,$08,$0C,$08,$7F,$3F
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00,$01,$01,$01
DB $00,$00,$00,$00,$00,$00,$00,$C0,$C0,$C0,$C0,$80,$80,$80,$00,$80
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$C0,$00
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$00,$30,$18
DB $2B,$1C,$0C,$08,$1C,$08,$18,$08,$1C,$08,$0C,$08,$08,$0C,$04,$0C
DB $00,$00,$00,$01,$03,$01,$03,$03,$03,$02,$03,$02,$03,$02,$1B,$03
DB $70,$00,$F8,$F0,$7E,$9C,$0C,$06,$02,$06,$04,$06,$0E,$04,$86,$0C
DB $00,$00,$00,$00,$2A,$1C,$74,$3E,$26,$64,$4E,$64,$5E,$6C,$7F,$7E
DB $01,$00,$0B,$07,$0D,$0E,$0E,$0C,$06,$0F,$07,$03,$01,$00,$01,$00
DB $CB,$05,$EF,$C7,$03,$01,$03,$01,$03,$01,$83,$81,$C3,$81,$C3,$81
DB $A0,$C0,$C1,$E0,$83,$01,$01,$03,$02,$03,$02,$03,$03,$03,$83,$01
DB $00,$00,$00,$00,$86,$0C,$06,$0E,$0E,$0E,$0F,$1E,$17,$BA,$F3,$F2
DB $00,$00,$00,$00,$0C,$07,$0F,$07,$0D,$06,$04,$0C,$00,$0C,$08,$0C
DB $00,$00,$1E,$0E,$9B,$9E,$FA,$93,$F1,$F3,$73,$E1,$E3,$61,$61,$60
DB $00,$00,$01,$00,$03,$07,$07,$0F,$1C,$0C,$1C,$08,$1C,$08,$1D,$0F
DB $03,$01,$87,$03,$C3,$E6,$32,$E6,$62,$26,$27,$62,$4F,$EF,$CA,$C7
DB $E0,$E0,$E0,$00,$01,$00,$05,$03,$07,$0F,$8F,$0C,$CC,$88,$88,$0C
DB $00,$00,$00,$00,$80,$00,$C0,$E0,$F0,$E0,$F0,$A0,$70,$20,$60,$60
DB $00,$00,$00,$00,$00,$00,$02,$01,$03,$01,$01,$03,$01,$03,$01,$03
DB $00,$00,$00,$00,$58,$30,$7C,$F8,$88,$CC,$84,$8C,$0C,$84,$8C,$04
DB $00,$00,$00,$00,$00,$00,$0F,$1F,$15,$3B,$7F,$33,$3F,$7E,$4C,$60
DB $01,$00,$01,$03,$06,$03,$26,$1F,$BF,$3F,$18,$0C,$18,$08,$18,$08
DB $00,$00,$80,$80,$80,$00,$80,$00,$C0,$80,$00,$00,$00,$00,$00,$00
DB $18,$30,$20,$30,$70,$20,$60,$60,$E0,$40,$60,$C0,$C0,$C0,$C0,$80
DB $0E,$04,$06,$07,$05,$03,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $33,$19,$79,$F0,$A0,$C0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $A8,$DC,$70,$F8,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $37,$03,$02,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $C3,$E1,$BF,$DF,$1E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $C1,$81,$81,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $B0,$E0,$F0,$E0,$00,$00,$00,$00,$06,$02,$07,$03,$02,$01,$00,$00
DB $E3,$02,$03,$02,$03,$06,$06,$0E,$0C,$1C,$30,$F8,$D0,$E0,$00,$00
DB $08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $60,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $0B,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $83,$02,$03,$02,$07,$02,$0E,$1E,$08,$1C,$00,$00,$00,$00,$00,$00
DB $07,$0E,$03,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $40,$E0,$80,$C0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $43,$83,$C1,$82,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $0C,$04,$08,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $40,$60,$32,$7F,$01,$3E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $1C,$08,$0C,$0E,$0F,$07,$03,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $00,$00,$41,$00,$C1,$C0,$C1,$00,$00,$00,$00,$00,$00,$00,$00,$00
DB $00,$00,$80,$00,$C0,$80,$C0,$80,$00,$00,$00,$00,$00,$00,$00,$00
; ****************************************************************************************
; Main code Initialization:
; set the stack pointer, enable interrupts, set the palette, set the screen relative to the window
; copy the ASCII character table, clear the screen
; ****************************************************************************************
begin:
nop
di
ld sp, $ffff ; set the stack pointer to highest mem location + 1
; NEXT FOUR LINES FOR SETTING UP SPRITES *hs*
call initdma ; move routine to HRAM
init:
ld a, %11100100 ; Window palette colors, from darkest to lightest
ld [rBGP], a ; set background and window pallette
ldh [rOBP0],a ; set sprite pallette 0 (choose palette 0 or 1 when describing the sprite)
ldh [rOBP1],a ; set sprite pallette 1
ld a,0 ; SET SCREEN TO TO UPPER RIGHT HAND CORNER
ld [rSCX], a
ld [rSCY], a
call StopLCD ; YOU CAN NOT LOAD $8000 WITH LCD ON
; *hs* erase sprite table
ld a,0
ld hl,OAMDATALOC
ld bc,OAMDATALENGTH
call mem_Set
ld a, LCDCF_ON|LCDCF_BG8000|LCDCF_BG9800|LCDCF_BGON|LCDCF_OBJ8|LCDCF_OBJON ; *hs* see gbspec.txt lines 1525-1565 and gbhw.inc lines 70-86
ld [rLCDC], a
ld a, 77
ld hl, _SCRN0
ld bc, SCRN_VX_B * SCRN_VY_B
call mem_SetVRAM
ld hl, toastymofo1_tile_data
ld de, _VRAM ; $8000
ld bc, toastymofo1_tile_data_size ; the ASCII character set: 256 characters, each with 8 bytes of display data
call mem_CopyVRAM ; load tile data
ld hl, toastymofo1_map_data
ld de, _SCRN0
ld bc, toastymofo1_tile_map_size
call mem_CopyVRAM ; load tile data
; ****************************************************************************************
; Main code:
; Print a character string in the middle of the screen
; ****************************************************************************************
sprsetup:
PutSpriteYAddr Sprite0,0 ; set Sprite0 location to 0,0
PutSpriteXAddr Sprite0,0
ld a,1 ; ; ibmpc1.inc ASCII character 1 is happy face :-)
ld [Sprite0TileNum],a ;sprite 1's tile address
ld a,%00000000 ;set flags (see gbhw.inc lines 33-42)
ld [Sprite0Flags],a ;save flags
call DMACODELOC ;update sprite
MainLoop:
ld bc,SPEED
call simpleDelay
call GetKeys
push af
and PADF_RIGHT
call nz,right
pop af
push af
and PADF_LEFT
call nz,left
pop af
push af
and PADF_UP
call nz,up
pop af
push af
and PADF_DOWN
call nz,down
pop af
push af
and PADF_START
call nz,Yflip
pop af
call DMACODELOC ; update sprite
jr MainLoop
; ****************************************************************************************
; Prologue
; Wait patiently 'til somebody kills you
; ****************************************************************************************
wait:
halt
nop
jr wait
; ****************************************************************************************
; hard-coded data
; ****************************************************************************************
right:
GetSpriteXAddr Sprite0
cp SCRN_X-8 ; already on RHS of screen?
ret z
inc a
PutSpriteXAddr Sprite0,a
ret
left: GetSpriteXAddr Sprite0
cp 0 ; already on LHS of screen?
ret z
dec a
PutSpriteXAddr Sprite0,a
ret
up: GetSpriteYAddr Sprite0
cp 0 ; already at top of screen?
ret z
dec a
PutSpriteYAddr Sprite0,a
ret
down: GetSpriteYAddr Sprite0
cp SCRN_Y-8 ; already at bottom of screen?
ret z
inc a
PutSpriteYAddr Sprite0,a
ret
Yflip: ld a,[Sprite0Flags]
xor OAMF_YFLIP ; toggle flip of sprite vertically
ld [Sprite0Flags],a
ret
simpleDelay:
dec bc
ld a,b
or c
jr nz, simpleDelay
ret
; GetKeys: adapted from APOCNOW.ASM and gbspec.txt
GetKeys: ;gets keypress
ld a,P1F_5 ; set bit 5
ld [rP1],a ; select P14 by setting it low. See gbspec.txt lines 1019-1095
ld a,[rP1]
ld a,[rP1] ; wait a few cycles
cpl ; complement A. "You are a very very nice Accumulator..."
and $0f ; look at only the first 4 bits
swap a ; move bits 3-0 into 7-4
ld b,a ; and store in b
ld a,P1F_4 ; select P15
ld [rP1],a
ld a,[rP1]
ld a,[rP1]
ld a,[rP1]
ld a,[rP1]
ld a,[rP1]
ld a,[rP1] ; wait for the bouncing to stop
cpl ; as before, complement...
and $0f ; and look only for the last 4 bits
or b ; combine with the previous result
ret ; do we need to reset joypad? (gbspec line 1082)
; *hs* START
initdma:
ld de, DMACODELOC
ld hl, dmacode
ld bc, dmaend-dmacode
call mem_CopyVRAM ; copy when VRAM is available
ret
dmacode:
push af
ld a, OAMDATALOCBANK ; bank where OAM DATA is stored
ldh [rDMA], a ; Start DMA
ld a, $28 ; 160ns
dma_wait:
dec a
jr nz, dma_wait
pop af
ret
dmaend:
; *hs* END
; ****************************************************************************************
; StopLCD:
; turn off LCD if it is on
; and wait until the LCD is off
; ****************************************************************************************
StopLCD:
ld a,[rLCDC]
rlca ; Put the high bit of LCDC into the Carry flag
ret nc ; Screen is off already. Exit.
; Loop until we are in VBlank
.wait:
ld a,[rLY]
cp 145 ; Is display on scan line 145 yet?
jr nz,.wait ; no, keep waiting
; Turn off the LCD
ld a,[rLCDC]
res 7,a ; Reset bit 7 of LCDC
ld [rLCDC],a
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment