-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhw.asm
169 lines (130 loc) · 3.65 KB
/
hw.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
.include "spg2xx.inc"
.define color(r,g,b) ((r << 10) | (g << 5) | (b << 0))
.unsp
.low_address 0
.high_address 0x1ffff
.org 0x10
; allocate space for the tilemap, which is stored in standard RAM
; put the tilemap somewhere other than 0 for test purposes
tilemap:
.resw (512/8)*(256/8) ; 8x8 sized tiles = 64*32 sized tilemap
tilemap_end:
; put the program code in suitable ROM area
.org 0x8000
start:
int off ; turn off interrupts as soon as possible
ld r1, #0
; initialize system ctrl
st r1, [SYSTEM_CTRL]
; clear watchdog just to be safe
ld r2, #0x55aa
st r2, [WATCHDOG_CLEAR]
; set background scroll values for bg 1
st r1, [PPU_BG1_SCROLL_X] ; scroll X offset of bg 1 = 0
st r1, [PPU_BG1_SCROLL_Y] ; scroll Y offset of bg 1 = 0
; set attribute config for bg 1
; bit 0-1: color depth (0 = 2-bit)
; bit 2: horizontal flip (0 = no flip)
; bit 3: vertical flip (0 = no flip)
; bit 4-5: X size (0 = 8 pixels)
; bit 6-7: Y size (0 = 8 pixels)
; bit 8-11: palette (0 = palette 0, colors 0-3 for 2-bit)
; bit 12-13: depth (0 = bottom layer)
st r1, [PPU_BG1_ATTR] ; set attribute of bg 1
; set control config for bg 1
; bit 0: bitmap mode (0 = disable)
; bit 1: attribute map mode or register mode (1 = register mode)
; bit 2: wallpaper mode (0 = disable)
; bit 3: enable bg (1 = enable)
; bit 4: horizontal line-specific movement (0 = disable)
; bit 5: horizontal compression (0 = disable)
; bit 6: vertical compression (0 = disable)
; bit 7: 16-bit color mode (0 = disable)
; bit 8: blend (0 = disable)
ld r2, #0x0a
st r2, [PPU_BG1_CTRL]
st r1, [PPU_BG2_CTRL] ; disable bg 2 since bit 3 = 0
st r1, [PPU_FADE_CTRL] ; clear fade control
st r1, [PPU_SPRITE_CTRL] ; disable sprites
; clear tilemap
ld r2, #' ' ; ASCII space
ld r3, #tilemap
ld r4, #tilemap_end
clear_tilemap_loop:
st r2, [r3++]
cmp r3, r4
jb clear_tilemap_loop
;set address of bg 1 tilemap
ld r2, #tilemap
st r2, [PPU_BG1_TILE_ADDR]
; set address of tile graphics data
; the register only stores the 16 most significant bits of a 22-bit address
; lowest 6 bits are expected to be zero, graphics therefore need to be 64-word aligned.
ld r2, #(font >> 6)
st r2, [PPU_BG1_SEGMENT_ADDR]
; set color 0 of palette
ld r2, #color(29,26,15)
st r2, [PPU_COLOR(0)]
; set color 1 of palette
ld r2, #color(0,8,16)
st r2, [PPU_COLOR(1)]
; current palette also uses color 2 and 3
; though our graphics only use color 0-1
; write string into tilemap
; the position of a specific tile can be calculated by:
; tilemap start address + (row * number of columns) + column
; where row and column values are 0-indexed
; number of columns is 512 / horizontal size
; number of rows is 256 / vertical size
; start string in row 2, column 3
ld r3, #(tilemap + 64*2 + 3)
; the start address of the sprite to draw is determined by
; graphics start address + sprite size in words * tile ID
; where sprite size in words is calculated by:
; (vertical size * horizontal size * color depth in bits) / 16
ld r2, #'H' ; write some characters
st r2, [r3++]
ld r2, #'e'
st r2, [r3++]
ld r2, #'y'
st r2, [r3++]
ld r2, #'!'
st r2, [r3++]
ld r2, #' '
st r2, [r3++]
ld r2, #'V'
st r2, [r3++]
ld r2, #'.'
st r2, [r3++]
ld r2, #'S'
st r2, [r3++]
ld r2, #'m'
st r2, [r3++]
ld r2, #'i'
st r2, [r3++]
ld r2, #'l'
st r2, [r3++]
ld r2, #'e'
st r2, [r3++]
ld r2, #'!'
st r2, [r3++]
; now done, run infinite loop
loop: jmp loop
; configure interrupt vector
; we disabled interrupts, but still need to set the start address
.org 0xfff5
.dw 0 ;break
.dw 0 ;fiq
.dw start ;reset
.dw 0 ;irq 0
.dw 0 ;irq 1
.dw 0 ;irq 2
.dw 0 ;irq 3
.dw 0 ;irq 4
.dw 0 ;irq 5
.dw 0 ;irq 6
.dw 0 ;irq 7
; the graphics data needs to be 64-word aligned as mentioned earlier
.align_bits 64*16
font:
.binfile "font.bin"