wip, draws hex
[megadrive.git] / hexed / hexed.s
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 #################################################
117 #                                               #
118 #                    DATA                       #
119 #                                               #
120 #################################################
121
122 colors:
123         dc.w 0x0000,0x0eee
124 colors_end:
125
126 # pattern:
127
128
129 sprite_data:
130         /*         Y        size     link          attr        X */
131         dc.w       0;  dc.b 0x05;  dc.b 0;  dc.w 0x6002;  dc.w 0
132 sprite_data_end:
133
134 hello:
135         .ascii  "hello world"
136
137 ##################################################
138 #                                                #
139 #               MAIN PROGRAM                     #
140 #                                                #
141 ##################################################
142  
143 .align 2
144
145 main:
146         /* mask irqs durinf init */
147         move.w          #0x2700,sr
148
149         movea.l         #0,a6
150
151         /* Init pads */
152         move.b          #0x40,(0xa10009).l
153         move.b          #0x40,(0xa10003).l
154
155         /* Initialize VDP */
156         jsr             init_gfx
157
158         /* Load color data */
159         movea.l         #0,a0
160         movea.l         #colors,a1
161         moveq.l         #(colors_end-colors)/2,d0
162         jsr             load_colors
163
164         /* load patterns */
165         movea.l         #0,a0
166         movea.l         #font,a1
167         move.l          #128,d0
168         jsr             load_tiles
169
170         /* generate A layer map */
171         movea.l         #0xe000,a1
172         move.l          #28-1,d4
173 lmaploop0:
174         movea.l         a1,a0
175         jsr             load_prepare
176
177         move.l          #64/2-1,d3
178 0:      move.l          #0x00000000,(a0)
179         dbra            d3,0b
180
181         add.l           #64*2,a1
182         dbra            d4,lmaploop0
183
184         /* generate B layer map */
185         movea.l         #0xc000,a0
186         jsr             load_prepare
187
188         move.l          #64*28/2-1,d3
189 0:      move.l          #0x00000000,(a0)
190         dbra            d3,0b
191
192         /* upload sprite data */
193         movea.l         #0xfc00,a0
194         jsr             load_prepare
195         movea.l         #sprite_data,a1
196
197         move.l          #(sprite_data_end-sprite_data)/2-1,d3
198 0:      move.l          (a1)+,(a0)
199         dbra            d3,0b
200
201         move.w          #0x2000,sr
202
203 ##################################################
204 #                                                #
205 #                 MAIN LOOP                      #
206 #                                                #
207 ##################################################
208
209 # global regs:
210 # a6 - page[31:8],cursor_offs[7:0]
211
212 forever:
213
214
215         jsr             wait_vsync
216         bra             forever
217         
218
219
220 VBL:
221         addq.l          #1,(vtimer).l
222         movem.l         d0-d7/a0-a5,-(a7)
223
224         /* draw main stuff */
225         clr.l           d7
226         move.l          a6,d0
227         lsr.l           #8,d0
228         move.l          d0,a1           /* current addr */
229
230         movea.l         #0xe004,a2
231         move.l          #27-1,d5
232
233 draw_column:
234         move.l          a2,a0
235         jsr             load_prepare
236
237         /* addr */
238         move.l          a1,d2
239         moveq.l         #6,d3
240         jsr             print_hex_preped
241
242         /* 4 shorts */
243         moveq.l         #4-1,d4
244 draw_shorts:
245         move.w          #' ',(a0)
246         move.w          (a1)+,d2
247         moveq.l         #4,d3
248         jsr             print_hex_preped
249         dbra            d4,draw_shorts
250
251         move.w          #' ',(a0)
252         move.w          #' ',(a0)
253
254         /* 8 chars */
255         subq.l          #8,a1
256         moveq.l         #8-1,d4
257 draw_chars:
258         move.b          (a1)+,d0
259         move.b          d0,d1
260         sub.b           #0x20,d1
261         cmp.b           #0x60,d1
262         blo             0f
263         move.w          #'.',d0
264 0:
265         move.w          d0,(a0)
266         dbra            d4,draw_chars
267
268         add.w           #0x80,a2
269         dbra            d5,draw_column
270
271         /* handle input */
272         jsr             get_input               /* x0cbrldu x1sa00du */
273         btst.b          #0,d0
274         beq             _in_nup
275         sub.l           #0x0800,a6
276
277 _in_nup:
278         btst.b          #1,d0
279         beq             _in_ndn
280         add.l           #0x0800,a6
281
282 _in_ndn:
283         btst.l          #10,d0
284         beq             _in_nleft
285         sub.l           #0xd800,a6
286
287 _in_nleft:
288         btst.b          #11,d0
289         beq             _in_nright
290         add.l           #0xd800,a6
291
292 _in_nright:
293
294 end:
295         movem.l         (a7)+,d0-d7/a0-a5
296         rte
297
298
299 #################################################
300 #                                               #
301 #         Initialize VDP registers              #
302 #                                               #
303 #################################################
304
305 init_gfx:
306         move.l          #GFXCNTL,a3
307         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
308         write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
309         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
310         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
311         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
312         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
313         write_vdp_reg   6,0     
314         write_vdp_reg   7,0                     /* Backdrop color */
315         write_vdp_reg   10,1                    /* Lines per hblank interrupt */
316         write_vdp_reg   11,0                    /* 2-cell vertical scrolling */
317         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
318         write_vdp_reg   13,(0x8000 >> 10)       /* Horizontal scroll address */
319         write_vdp_reg   15,2
320         write_vdp_reg   16,(VDP16_MAP_V32 | VDP16_MAP_H64)      /* layer size */
321         write_vdp_reg   17,0
322         write_vdp_reg   18,0xff
323         rts
324
325
326 # read single phase from controller
327 #  a0 - addr
328 #  d0 - result
329 get_input:
330         move.b          #0x40,(0xa10003)
331         nop
332         nop
333         nop
334         move.b          (0xa10003),d0
335         move.b          #0x00,(0xa10003)
336         lsl.w           #8,d0
337         nop
338         move.b          (0xa10003),d0
339         eor.w           #0xffff,d0
340 #       move.b          #0x40,(0xa10003)
341         rts
342
343 # Load tile data from ROM
344 #  a0: VRAM base
345 #  a1: pattern address
346 #  d0: number of tiles to load
347 #  destroys d1
348
349 load_tiles:
350         move.l          d0,d1
351         VRAM_ADDR_var   a0
352         move.l          d0,(GFXCNTL).l
353         
354         move.l          #GFXDATA,a0
355         lsl.w           #3,d1
356         subq.l          #1,d1
357 0:
358         move.l          (a1)+,(a0)
359         dbra            d1,0b
360
361         rts
362
363
364 # Prepare to write to VDP RAM @a3
365 # sets a0 to VDP data port for convenience
366 #  a0: VRAM base
367 #  destroys d0
368
369 load_prepare:
370         VRAM_ADDR_var   a0
371         move.l          d0,(GFXCNTL).l
372         move.l          #GFXDATA,a0
373         rts
374
375
376 # Load color data from ROM
377 #  a0: CRAM base
378 #  a1: color list address
379 #  d0: number of colors to load
380 #  destroys d1
381
382 load_colors:
383         move.l          d0,d1
384         CRAM_ADDR_var   a0
385         move.l          d0,(GFXCNTL).l
386
387         move.l          #GFXDATA,a0
388         subq.w          #1,d1
389 0:
390         move.w          (a1)+,(a0)
391         dbra            d1,0b
392
393         rts
394
395
396 # print
397 #  a0 - string
398 #  d0 - x
399 #  d1 - y 
400 #  destroys a1
401
402 print:
403         move.l          a0,a1
404         XY2NT
405         jsr             load_prepare
406         moveq.l         #0,d0
407
408 _print_loop:
409         move.b          (a1)+,d0
410         beq             _print_end
411
412         move.w          d0,(a0)
413         jmp             _print_loop
414
415 _print_end:
416         rts
417
418
419 # print_hex
420 #  d0 - x
421 #  d1 - y 
422 #  d2 - value
423 #  d3 - digit cnt
424 #  destroys a0
425
426 print_hex:
427         XY2NT
428         jsr             load_prepare
429
430 print_hex_preped:
431         move.l          d3,d0
432         lsl.b           #2,d0
433         ror.l           d0,d2           /* prep value */
434         moveq.l         #0,d0
435         subq.l          #1,d3           /* count */
436
437 _print_hex_loop:
438         rol.l           #4,d2
439         move.b          d2,d0
440         and.b           #0xf,d0
441         cmp.b           #0xa,d0
442         bge             1f
443
444         add.b           #'0',d0
445         jmp             2f
446 1:
447         add.b           #0x37,d0
448 2:
449         move.w          d0,(a0)
450         dbra            d3,_print_hex_loop
451
452         rts
453
454
455 #################################################
456 #                                               #
457 #       Wait for next VBlank interrupt          #
458 #                                               #
459 #################################################
460
461 wait_vsync:
462         movea.l         #vtimer,a0
463         move.l          (a0),a1
464 _wait_change:
465         stop            #0x2000
466         cmp.l           (a0),a1
467         beq             _wait_change
468         rts
469
470
471 #################################################
472 #                                               #
473 #                 RAM DATA                      #
474 #                                               #
475 #################################################
476
477 .bss
478
479 # used by sega_gcc.s
480 .globl htimer
481 .globl vtimer
482 .globl rand_num
483 htimer:         .long 0
484 vtimer:         .long 0
485 rand_num:       .long 0
486
487 #
488
489 .end
490
491 # vim:filetype=asmM68k