1 ##################################################
4 # --register-prefix-optional --bitwise-or #
6 ##################################################
12 ##################################################
14 # Register and bitmask definitions #
16 ##################################################
18 .equ GFXDATA, 0xc00000
19 .equ GFXCNTL, 0xc00004
22 .equ VDP0_E_DISPLAY, 0x02
23 .equ VDP0_PLTT_FULL, 0x04
25 .equ VDP1_SMS_MODE, 0x80
26 .equ VDP1_E_DISPLAY, 0x40
31 .equ VDP1_RESERVED, 0x04
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
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
50 ##################################################
54 ##################################################
57 /* Write val to VDP register reg */
58 .macro write_vdp_reg reg val
59 move.w #((\reg << 8) + 0x8000 + \val),(a3)
63 /* For immediate addresses */
64 .macro VRAM_ADDR reg adr
65 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
69 .macro CRAM_ADDR reg adr
70 move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
74 # make VDP word from address adr and store in d0
75 .macro XRAM_ADDR_var adr
85 .macro VRAM_ADDR_var adr
91 .macro CRAM_ADDR_var adr
97 .macro VSCROLL_ADDR reg adr
98 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
102 .macro HSCROLL_ADDR reg adr
103 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
107 # convert tile coords in d0, d1 to nametable addr to a0
116 # check if some d-pad button (and modifier) is pressed
117 .macro do_dpad bit op opq val modval
120 btst.b #4,d0 /* A pressed? */
130 #################################################
134 #################################################
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
147 /* Y size link attr X */
148 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
151 ##################################################
155 ##################################################
160 /* mask irqs during init */
167 move.b #0x40,(0xa10009).l
168 move.b #0x40,(0xa10003).l
173 /* Load color data */
176 moveq.l #(colors_end-colors)/2,d0
185 /* generate A layer map */
193 0: move.l #0x00000000,(a0)
199 /* generate B layer map */
204 0: move.l #0x00000000,(a0)
207 /* upload sprite data */
210 movea.l #sprite_data,a1
212 move.l #(sprite_data_end-sprite_data)/2-1,d3
218 ##################################################
222 ##################################################
225 # a6 - page_start[31:8]|cursor_offs[7:0]
238 movem.l d0-d6/a0-a5,-(a7)
240 /* draw main stuff */
245 move.l d0,a1 /* current addr */
248 add.b #27-1,d1 /* line where the cursor sits */
252 move.l #27-1,d5 /* line counter for dbra */
279 move.l #(' '<<16)|' ',(a0)
299 movea.l #0xe004+64*2*27,a0
310 jsr get_input /* x0cbrldu x1sa00du */
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
333 movem.l (a7)+,d0-d6/a0-a5
339 and.l #7,d0 /* byte offs */
341 lsr.b #1,d1 /* which word */
344 add.b d2,d1 /* num of chars to skip */
358 jsr load_prepare /* restore a0 */
363 #################################################
365 # Initialize VDP registers #
367 #################################################
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 */
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 */
384 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
386 write_vdp_reg 18,0xff
390 # read single phase from controller
394 move.b #0x40,(0xa10003)
399 move.b #0x00,(0xa10003)
404 # move.b #0x40,(0xa10003)
407 # Load tile data from ROM
409 # a1: pattern address
410 # d0: number of tiles to load
416 move.l d0,(GFXCNTL).l
428 # Prepare to write to VDP RAM @a3
429 # sets a0 to VDP data port for convenience
435 move.l d0,(GFXCNTL).l
440 # Load color data from ROM
442 # a1: color list address
443 # d0: number of colors to load
449 move.l d0,(GFXCNTL).l
487 # d3 - digit_cnt[0:7]|tile_bits[11:15]
488 # destroys a0, preserves d3
499 ror.l d0,d2 /* prep value */
500 subq.l #1,d1 /* count */
502 and.w #0xf800,d0 /* keep upper bits in d0 */
515 dbra d1,_print_hex_loop
520 #################################################
522 # Wait for next VBlank interrupt #
524 #################################################
536 #################################################
540 #################################################
556 # vim:filetype=asmM68k