Här är en bit assemblerkod, som efter kompilering blir ett litet men fungerande program för Gameboy.
INCLUDE "includes.inc"
pusha: MACRO
push AF
push BC
push DE
push HL
ENDM
popa: MACRO
pop HL
pop DE
pop BC
pop AF
ENDM
LCDSTAT equ $0048 ; Int vector
VBLANK equ $0040 ; Int vector
IE equ $ffff
SERIALINT equ $0058
STAT equ $FF41
LY equ $FF44
LCDC equ $FF40
BGP equ $FF47
SECTION "FILLER",HOME[0]
vmess:
db $F0,$00,$F0,$ee, $ee,$F0,$00,$0F
db $F0,$00,$F0,$e0, $00,$0F,$00,$F0
db $F0,$00,$F0,$e0, $00,$00,$FF,$00
db $FF,$FF,$F0,$ee, $ee,$00,$FF,$00
db $F0,$00,$F0,$e0, $00,$0F,$00,$F0
db $F0,$00,$F0,$ee, $ee,$F0,$00,$0F
db $00,$00,$00,$00, $00,$00,$00,$00
db $F0,$00,$F0,$10, $ee,$e5,$00,$05
db $F0,$00,$F0,$10, $e0,$05,$00,$05
db $F0,$00,$F0,$10, $ee,$05,$00,$05
db $0F,$0F,$00,$10, $e0,$05,$05,$05
db $00,$F0,$00,$10, $ee,$e0,$50,$50
vmessend:
rept $100-(vmessend-vmess)
db $00
endr
SECTION "ENTRY",HOME[$100]
jp ENTRY
SECTION "MAIN",HOME[$150]
ENTRY
di ; Disable'em
xor A ; Pattern
ld HL,$C000 ; Offset (WRAM)
ld BC,$2000 ; Size
call CLEARPROC
WAITVBL
ld A,0
ldio [LCDC],A
ld A,%11100100
ldio [BGP],A
xor A
ld HL,$8000 ; Offset (VRAM)
ld BC,$2000 ; Size
call CLEARPROC
ld HL,TileLabel ; Tileset
ld DE,$8010
ld BC,(TileLabelEnd-TileLabel)+32 ; Size
call COPYPROC
ld HL,offsetmessage ; Offset message
ld DE,$9c00
ld BC,6 ; Size
call COPYPROC
ld A,%10011001
ldio [LCDC],A
ld HL,mainloop2 ; ROM (source)
ld DE,MAINLOOPRAM ; RAM (Destination)
ld BC,(mainloopend-mainloop2) ; Size
call COPYPROC
jp MAINLOOPRAM
SECTION "OFFSETMESSAGE",HOME
;offsetmessage: DB $00,$0F,$0F,$05,$0E,$07
offsetmessage: DB $01,$10,$10,$06,$0F,$08
mainloop2:
;ld A,0
;ldio [$ff50],A ; Attempt to turn internal ROM on
jr mainloop
db 00
mainloop:
;push HL
;ld HL,MAINLOOPRAM+2
;inc [HL]
;ld A,[HL]
ld A,1
ldio [$ff50],A
;pop HL
;call READPAD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Reads off keypad and puts result in currentjoypad
;READPAD
; Out data
; 04 se st b a
; 02 08 01 40 80 20 10
; BREAK
ld a,$20 ; Load bit 5
ldio [$ff00],a ; Send to probe buttons (P15)
ldio a,[$ff00] ; Get return value...
ldio a,[$ff00] ; Wait for post-oscillation to go away...
ldio a,[$ff00]
ldio a,[$ff00] ; ... stabilized!
cpl ; Invert a to make pressed keys 1
and $0f ; Pass lower nibble
ld b,a ; Store in b
ld a,$10 ; Load bit 5
ldio [$ff00],a ; Send to probe +-pad (P15)
ldio a,[$ff00] ; Get return value...
ldio a,[$ff00] ; Wait for post-oscillation to go away...
ldio a,[$ff00]
ldio a,[$ff00] ; ... stabilized!
cpl ; Invert a to make pressed keys 1
and $0f ; Pass lower nibble
swap a ; swap nibbles, to give space in lowe nibble
or b ; Combine values
ld b,a ; Copy a to b
;BREAK
ld [currentjoypad],a ; Store new joypad info
ld a,[oldjoypad] ; Load old joypad value...
xor b ; Toggle
and b ;
ld [currentjoypad],a ; Store new joypad info
ld a,b ;
ld [oldjoypad],a ;
ld a,$30 ;
ld [$ff00],a ; De-activate
;BREAK
ld HL,OFFSET
ld E,[HL]
inc HL
ld D,[HL]
; push DE ; "ld hl,de"
; pop HL
ld H,D
ld L,E
;------- Row scroll
IFNKEY butb,.nofast
ld BC,$1000
IFNKEY butdn,.nodnf
add HL,BC
.nodnf
ld BC,-$1000
IFNKEY butup,.noupf
add HL,BC
.noupf
jr .fast
.nofast
ld BC,8
IFNKEY butdn,.nodn
add HL,BC
.nodn
ld BC,-8
IFNKEY butup,.noup
add HL,BC
.noup
.fast
;------- Screen scroll
ld BC,$80
IFNKEY butr,.nor
add HL,BC
.nor
ld BC,-$80
IFNKEY butl,.nol
add HL,BC
.nol
ld D,H
ld E,L
ld HL,OFFSET
ld [HL],E
inc HL
ld [HL],D
;-------
ld A,3
ld [VBLCOUNTER],A
WAITVBL
ld A,[OFFSET]
ld E,A
ld A,[OFFSET+1]
ld D,A
ld HL,$9c00+7 ; Map, (7,0)
ld A,D
and $f0 ; Extract higher nibble
swap A
add $11 ; Shift $10 indeces up for different tile.
;inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
ld A,D
and $0f ; Extract lower nibble
inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
ld A,E
and $f0 ; Extract higher nibble
swap A
add $11 ; Shift $10 indeces up for different tile.
;inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
ld A,E
and $0f ; Extract lower nibble
inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
;-------
ld HL,$9c00+$20+1 ; MAP, second row, Second char
ld BC,$1008 ; B=8 rows, C=8 cols (* 2 nibbles)
.writerow
push BC
.newrow
ld A,[DE]
ld B,A
and $f0 ; Extract higher nibble
swap A
add $11 ; Shift $10 indeces up for different tile.
;inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
ld A,B
and $0f ; Extract lower nibble
inc A ; Tile indeces are shifted 1 step up!
ld [HL+],A ; Write grafx
inc DE
pop BC
ld A,5
cp C
jr nz,.noinc
inc HL ; Have a space between every 4 bytes...
.noinc
dec C
jr nz,.writerow
; New row
;BREAK
;; Do a mark to the right??
ld [HL],0
dec E
bit 5,E
jr nz,.noline
ld [HL],$21
.noline
inc HL
ld [HL],0
;; Even a double one?
ld A,7
cp E
jr nz,.nodoublemark
ld [HL],$21
.nodoublemark
inc E
dec HL
ld A,[VBLCOUNTER]
dec A
jr nz,.stillinvbl
WAITVBL
ld A,3
.stillinvbl
ld [VBLCOUNTER],A
dec B
jp z,mainloop-mainloop+MAINLOOPRAM
ld C,8 ; Reset counter
push BC
ld BC,$000f ; New row ($20 - row width in tiles )
add HL,BC
; No POP here!! BC is spoilt in row printing routine anyway, and
; We save cycles for uneeded pop BC,push BC
jr .newrow
mainloopend:
INCLUDE "hextiles.z80"
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
SECTION "USERVARS",BSS
OFFSET DW
VBLCOUNTER DB
MAINLOOPRAM DS mainloopend-mainloop