wip
[megadrive.git] / hexed / hexed.s
... / ...
CommitLineData
1##################################################
2# #
3# Assemble with gas #
4# --register-prefix-optional --bitwise-or #
5# #
6##################################################
7
8.text
9.globl main
10.globl VBL
11
12##################################################
13# #
14# Register and bitmask definitions #
15# #
16##################################################
17
18.equ GFXDATA, 0xc00000
19.equ GFXCNTL, 0xc00004
20
21.equ VDP0_E_HBI, 0x10
22.equ VDP0_E_DISPLAY, 0x02
23.equ VDP0_PLTT_FULL, 0x04
24
25.equ VDP1_SMS_MODE, 0x80
26.equ VDP1_E_DISPLAY, 0x40
27.equ VDP1_E_VBI, 0x20
28.equ VDP1_E_DMA, 0x10
29.equ VDP1_NTSC, 0x00
30.equ VDP1_PAL, 0x08
31.equ VDP1_RESERVED, 0x04
32
33.equ VDP12_SPR_SHADOWS, 0x08
34.equ VDP12_SCREEN_V224, 0x00
35.equ VDP12_SCREEN_V448, 0x04
36.equ VDP12_PROGRESSIVE, 0x00
37.equ VDP12_INTERLACED, 0x02
38.equ VDP12_SCREEN_H256, 0x00
39.equ VDP12_SCREEN_H320, 0x81
40
41.equ VDP16_MAP_V32, 0x00
42.equ VDP16_MAP_V64, 0x10
43.equ VDP16_MAP_V128, 0x30
44.equ VDP16_MAP_H32, 0x00
45.equ VDP16_MAP_H64, 0x01
46.equ VDP16_MAP_H128, 0x03
47
48
49
50##################################################
51# #
52# MACROS #
53# #
54##################################################
55
56
57/* Write val to VDP register reg */
58.macro write_vdp_reg reg val
59 move.w #((\reg << 8) + 0x8000 + \val),(a3)
60.endm
61
62
63/* For immediate addresses */
64.macro VRAM_ADDR reg adr
65 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
66.endm
67
68
69.macro CRAM_ADDR reg adr
70 move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
71.endm
72
73
74# make VDP word from address adr and store in d0
75.macro XRAM_ADDR_var adr
76 move.l \adr,d0
77 lsl.l #8,d0
78 lsl.l #8,d0
79 rol.l #2,d0
80 lsl.b #2,d0
81 lsr.l #2,d0
82.endm
83
84
85.macro VRAM_ADDR_var adr
86 XRAM_ADDR_var \adr
87 or.l #0x40000000,d0
88.endm
89
90
91.macro CRAM_ADDR_var adr
92 XRAM_ADDR_var \adr
93 or.l #0xc0000000,d0
94.endm
95
96
97.macro VSCROLL_ADDR reg adr
98 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
99.endm
100
101
102.macro HSCROLL_ADDR reg adr
103 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
104.endm
105
106
107# convert tile coords in d0, d1 to nametable addr to a0
108.macro XY2NT
109 lsl.w #6,d1
110 add.w d1,d0
111 lsl.w #1,d0
112 movea.l #0xe000,a0
113 add.w d0,a0
114.endm
115
116# check if some d-pad button (and modifier) is pressed
117.macro do_dpad bit op opq val modval
118 btst.b #\bit,d0
119 beq 1f
120 btst.b #4,d0 /* A pressed? */
121 bne 0f
122 \opq.l #\val,a6
123 bra input_end
1240:
125 \op.l #\modval,a6
126 bra input_end
1271:
128.endm
129
130#################################################
131# #
132# DATA #
133# #
134#################################################
135
136colors:
137 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
138 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
139 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
140 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
141 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
142 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
143colors_end:
144
145
146sprite_data:
147 /* Y size link attr X */
148 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
149sprite_data_end:
150
151##################################################
152# #
153# MAIN PROGRAM #
154# #
155##################################################
156
157.align 2
158
159main:
160 /* mask irqs during init */
161 move.w #0x2700,sr
162
163 movea.l #0,a6
164 moveq.l #0,d7
165
166 /* Init pads */
167 move.b #0x40,(0xa10009).l
168 move.b #0x40,(0xa10003).l
169
170 /* Initialize VDP */
171 jsr init_gfx
172
173 /* Load color data */
174 movea.l #0,a0
175 movea.l #colors,a1
176 moveq.l #(colors_end-colors)/2,d0
177 jsr load_colors
178
179 /* load patterns */
180 movea.l #0,a0
181 movea.l #font,a1
182 move.l #128,d0
183 jsr load_tiles
184
185 /* generate A layer map */
186 movea.l #0xe000,a1
187 move.l #28-1,d4
188lmaploop0:
189 movea.l a1,a0
190 jsr load_prepare
191
192 move.l #64/2-1,d3
1930: move.l #0x00000000,(a0)
194 dbra d3,0b
195
196 add.l #64*2,a1
197 dbra d4,lmaploop0
198
199 /* generate B layer map */
200 movea.l #0xc000,a0
201 jsr load_prepare
202
203 move.l #64*28/2-1,d3
2040: move.l #0x00000000,(a0)
205 dbra d3,0b
206
207 /* upload sprite data */
208 movea.l #0xfc00,a0
209 jsr load_prepare
210 movea.l #sprite_data,a1
211
212 move.l #(sprite_data_end-sprite_data)/2-1,d3
2130: move.l (a1)+,(a0)
214 dbra d3,0b
215
216 move.w #0x2000,sr
217
218##################################################
219# #
220# MAIN LOOP #
221# #
222##################################################
223
224# global regs:
225# a6 - page_start[31:8]|cursor_offs[7:0]
226# d7 - byte_mode[0]
227
228forever:
229
230
231 jsr wait_vsync
232 bra forever
233
234
235
236VBL:
237 addq.l #1,(vtimer).l
238 movem.l d0-d6/a0-a5,-(a7)
239
240 /* draw main stuff */
241 clr.l d1
242 move.l a6,d0
243 move.b d0,d1
244 lsr.l #8,d0
245 move.l d0,a1 /* current addr */
246 lsr.b #3,d1
247 neg.b d1
248 add.b #27-1,d1 /* line where the cursor sits */
249 swap d1
250
251 movea.l #0xe004,a2
252 move.l #27-1,d5 /* line counter for dbra */
253 or.l d1,d5
254
255draw_column:
256 move.l a2,a0
257 jsr load_prepare
258
259 /* addr */
260 move.l a1,d2
261 moveq.l #6,d3
262 jsr print_hex_preped
263
264 /* 4 shorts */
265 moveq.l #4,d3
266 moveq.l #4-1,d4
267draw_shorts:
268 move.w #' ',(a0)
269 move.w (a1)+,d2
270 jsr print_hex_preped
271 dbra d4,draw_shorts
272
273 move.l d5,d0
274 swap d0
275 cmp.w d5,d0
276 beq draw_cursor
277
278draw_chars_pre:
279 move.l #(' '<<16)|' ',(a0)
280
281 /* 8 chars */
282 subq.l #8,a1
283 moveq.l #8-1,d4
284draw_chars:
285 move.b (a1)+,d0
286 move.b d0,d1
287 sub.b #0x20,d1
288 cmp.b #0x60,d1
289 blo 0f
290 move.w #'.',d0
2910:
292 move.w d0,(a0)
293 dbra d4,draw_chars
294
295 add.w #0x80,a2
296 dbra d5,draw_column
297
298 /* status bar */
299 movea.l #0xe004+64*2*27,a0
300 jsr load_prepare
301 move.l a6,d2
302 moveq.l #0,d3
303 move.b d2,d3
304 lsr.l #8,d2
305 add.l d3,d2
306 move.l #0x4006,d3
307 jsr print_hex_preped
308
309 /* handle input */
310 jsr get_input /* x0cbrldu x1sa00du */
311
312 do_dpad 0, sub, subq, 0x0008, 0x0800
313 do_dpad 1, add, addq, 0x0008, 0x0800
314 do_dpad 10, sub, subq, 0x0001, 0xd800
315 do_dpad 11, add, addq, 0x0001, 0xd800
316input_end:
317
318 /* update addr */
319 move.l a6,d0
320 cmp.b #0xf0,d0
321 blo 0f
322 sub.l #0xd800,a6
323 add.w #0x00d8,a6
324 bra 1f
3250:
326 cmp.b #0xe0,d0
327 blo 1f
328 add.l #0xd800,a6
329 sub.w #0x00d8,a6
3301:
331
332end:
333 movem.l (a7)+,d0-d6/a0-a5
334 rte
335
336
337draw_cursor:
338 move.l a6,d0
339 and.l #7,d0 /* byte offs */
340 move.l d0,d1
341 lsr.b #1,d1 /* which word */
342 move.b d1,d2
343 lsl.b #2,d2
344 add.b d2,d1 /* num of chars to skip */
345 lsl.b #1,d1
346
347 /* FIXME */
348 move.w (-8,a1,d0),d2
349
350 lea (7*2,a2,d1),a0
351 jsr load_prepare
352
353 move.w #0x2004,d3
354 jsr print_hex_preped
355
356 move.l a2,a0
357 add.w #26*2,a0
358 jsr load_prepare /* restore a0 */
359
360 jmp draw_chars_pre
361
362
363#################################################
364# #
365# Initialize VDP registers #
366# #
367#################################################
368
369init_gfx:
370 move.l #GFXCNTL,a3
371 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
372 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
373 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
374 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
375 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
376 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
377 write_vdp_reg 6,0
378 write_vdp_reg 7,0 /* Backdrop color */
379 write_vdp_reg 10,1 /* Lines per hblank interrupt */
380 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
381 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
382 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
383 write_vdp_reg 15,2
384 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
385 write_vdp_reg 17,0
386 write_vdp_reg 18,0xff
387 rts
388
389
390# read single phase from controller
391# a0 - addr
392# d0 - result
393get_input:
394 move.b #0x40,(0xa10003)
395 nop
396 nop
397 nop
398 move.b (0xa10003),d0
399 move.b #0x00,(0xa10003)
400 lsl.w #8,d0
401 nop
402 move.b (0xa10003),d0
403 eor.w #0xffff,d0
404# move.b #0x40,(0xa10003)
405 rts
406
407# Load tile data from ROM
408# a0: VRAM base
409# a1: pattern address
410# d0: number of tiles to load
411# destroys d1
412
413load_tiles:
414 move.l d0,d1
415 VRAM_ADDR_var a0
416 move.l d0,(GFXCNTL).l
417
418 move.l #GFXDATA,a0
419 lsl.w #3,d1
420 subq.l #1,d1
4210:
422 move.l (a1)+,(a0)
423 dbra d1,0b
424
425 rts
426
427
428# Prepare to write to VDP RAM @a3
429# sets a0 to VDP data port for convenience
430# a0: VRAM base
431# destroys d0
432
433load_prepare:
434 VRAM_ADDR_var a0
435 move.l d0,(GFXCNTL).l
436 move.l #GFXDATA,a0
437 rts
438
439
440# Load color data from ROM
441# a0: CRAM base
442# a1: color list address
443# d0: number of colors to load
444# destroys d1
445
446load_colors:
447 move.l d0,d1
448 CRAM_ADDR_var a0
449 move.l d0,(GFXCNTL).l
450
451 move.l #GFXDATA,a0
452 subq.w #1,d1
4530:
454 move.w (a1)+,(a0)
455 dbra d1,0b
456
457 rts
458
459
460# print
461# a0 - string
462# d0 - x
463# d1 - y
464# destroys a1
465
466print:
467 move.l a0,a1
468 XY2NT
469 jsr load_prepare
470 moveq.l #0,d0
471
472_print_loop:
473 move.b (a1)+,d0
474 beq _print_end
475
476 move.w d0,(a0)
477 jmp _print_loop
478
479_print_end:
480 rts
481
482
483# print_hex
484# d0 - x
485# d1 - y
486# d2 - value
487# d3 - digit_cnt[0:7]|tile_bits[11:15]
488# destroys a0, preserves d3
489
490print_hex:
491 XY2NT
492 jsr load_prepare
493
494print_hex_preped:
495 moveq.l #0,d0
496 move.b d3,d0
497 move.l d0,d1
498 lsl.b #2,d0
499 ror.l d0,d2 /* prep value */
500 subq.l #1,d1 /* count */
501 move.w d3,d0
502 and.w #0xf800,d0 /* keep upper bits in d0 */
503
504_print_hex_loop:
505 rol.l #4,d2
506 move.b d2,d0
507 and.b #0xf,d0
508
509 add.b #'0',d0
510 cmp.b #'9',d0
511 ble 0f
512 addq.b #7,d0
5130:
514 move.w d0,(a0)
515 dbra d1,_print_hex_loop
516
517 rts
518
519
520#################################################
521# #
522# Wait for next VBlank interrupt #
523# #
524#################################################
525
526wait_vsync:
527 movea.l #vtimer,a0
528 move.l (a0),a1
529_wait_change:
530 stop #0x2000
531 cmp.l (a0),a1
532 beq _wait_change
533 rts
534
535
536#################################################
537# #
538# RAM DATA #
539# #
540#################################################
541
542.bss
543
544# used by sega_gcc.s
545.globl htimer
546.globl vtimer
547.globl rand_num
548htimer: .long 0
549vtimer: .long 0
550rand_num: .long 0
551
552#
553
554.end
555
556# vim:filetype=asmM68k