free some bits in global reg, use r5 for edit
[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_STE,         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 .equ MMODE_MAIN,        0
49 .equ MMODE_VAL_INPUT,   1
50 .equ MMODE_EDIT_VAL,    2
51 .equ MMODE_GOTO,        3
52
53
54 ##################################################
55 #                                                #
56 #                   MACROS                       #
57 #                                                #
58 ##################################################
59
60
61 /* Write val to VDP register reg */
62 .macro write_vdp_reg reg val
63         move.w #((\reg << 8) + 0x8000 + \val),(a3)
64 .endm
65
66
67 /* For immediate addresses */
68 .macro VRAM_ADDR reg adr
69         move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
70 .endm
71
72
73 .macro CRAM_ADDR reg adr
74         move.l  #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
75 .endm
76
77
78 # make VDP word from address adr and store in d0
79 .macro XRAM_ADDR_var adr
80         move.l \adr,d0
81         lsl.l #8,d0
82         lsl.l #8,d0
83         rol.l #2,d0
84         lsl.b #2,d0
85         lsr.l #2,d0
86 .endm
87
88
89 .macro VRAM_ADDR_var adr
90         XRAM_ADDR_var \adr
91         or.l #0x40000000,d0
92 .endm
93
94
95 .macro CRAM_ADDR_var adr
96         XRAM_ADDR_var \adr
97         or.l #0xc0000000,d0
98 .endm
99
100
101 .macro VSCROLL_ADDR reg adr
102         move.l  #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
103 .endm
104
105
106 .macro HSCROLL_ADDR reg adr
107         move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
108 .endm
109
110
111 # convert tile coords in d0, d1 to nametable addr to a0
112 .macro XY2NT
113         lsl.w           #6,d1
114         add.w           d1,d0
115         lsl.w           #1,d0
116         movea.l         #0xe000,a0
117         add.w           d0,a0
118 .endm
119
120 # check if some d-pad button (and modifier) is pressed
121 .macro do_dpad bit op val
122         btst.l          #\bit,d0
123         beq             0f
124         \op.l           \val,a6
125         bra             dpad_end
126 0:
127 .endm
128
129 # convert a6 to normal addr
130 #  destroys d0
131 .macro mk_a6_addr reg
132         move.l          a6,\reg
133         moveq.l         #0,d0
134         move.b          \reg,d0
135         lsr.l           #8,\reg
136         add.l           d0,\reg
137 .endm
138
139 .macro change_mode mode_new mode_back
140         and.w           #0xc0ff,d7
141         or.w            #(\mode_back<<11)|(\mode_new<<8),d7
142 .endm
143
144 #################################################
145 #                                               #
146 #                    DATA                       #
147 #                                               #
148 #################################################
149
150 colors:
151         dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
152         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
153         dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
154         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
155         dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
156         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
157 colors_end:
158
159
160 sprite_data:
161         /*         Y        size     link          attr        X */
162         dc.w       0;  dc.b 0x05;  dc.b 0;  dc.w 0x6002;  dc.w 0
163 sprite_data_end:
164
165 txt_edit:
166         .ascii  "- edit -\0"
167 txt_a_confirm:
168         .ascii  "A-confirm\0"
169
170 ##################################################
171 #                                                #
172 #               MAIN PROGRAM                     #
173 #                                                #
174 ##################################################
175  
176 .align 2
177
178 main:
179         /* mask irqs during init */
180         move.w          #0x2700,sr
181
182         movea.l         #0,a6
183         move.l          #0x8000,d7
184         moveq.l         #0,d6
185
186         /* Init pads */
187         move.b          #0x40,(0xa10009).l
188         move.b          #0x40,(0xa10003).l
189
190         /* Initialize VDP */
191         jsr             init_gfx
192
193         /* Load color data */
194         movea.l         #0,a0
195         movea.l         #colors,a1
196         moveq.l         #(colors_end-colors)/2,d0
197         jsr             load_colors
198
199         /* load patterns */
200         movea.l         #0,a0
201         movea.l         #font,a1
202         move.l          #128,d0
203         jsr             load_tiles
204
205         /* generate A layer map */
206         movea.l         #0xe000,a1
207         move.l          #28-1,d4
208 lmaploop0:
209         movea.l         a1,a0
210         jsr             load_prepare
211
212         move.l          #64/2-1,d3
213 0:      move.l          #0x00000000,(a0)
214         dbra            d3,0b
215
216         add.l           #64*2,a1
217         dbra            d4,lmaploop0
218
219         /* generate B layer map */
220         movea.l         #0xc000,a0
221         jsr             load_prepare
222
223         move.l          #64*28/2-1,d3
224 0:      move.l          #0x00000000,(a0)
225         dbra            d3,0b
226
227         /* upload sprite data */
228         movea.l         #0xfc00,a0
229         jsr             load_prepare
230         movea.l         #sprite_data,a1
231
232         move.l          #(sprite_data_end-sprite_data)/2-1,d3
233 0:      move.l          (a1)+,(a0)
234         dbra            d3,0b
235
236         move.w          #0x2000,sr
237
238 ##################################################
239 #                                                #
240 #                 MAIN LOOP                      #
241 #                                                #
242 ##################################################
243
244 # global regs:
245 # a6 = page_start[31:8]|cursor_offs[7:0]
246 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
247 # d6 = edit_word_save[31:15]|edit_done[7]|autorep_cnt[3:0]
248 # d5 = edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]; tmp in main mode
249
250 forever:
251         jsr             wait_vsync
252         bra             forever
253         
254
255
256 VBL:
257         addq.b          #1,d7
258         movem.l         d0-d4/a0-a5,-(a7)
259
260         moveq.l         #0,d0
261         move.w          d7,d0
262         lsr.w           #6,d0
263         and.w           #0x1c,d0
264         move.l          (jumptab,pc,d0),a0
265         jmp             (a0)
266 jumptab:
267         dc.l            mode_main
268         dc.l            mode_val_input
269         dc.l            mode_edit_val   /* edit val in editor */
270         dc.l            mode_goto
271         dc.l            mode_main
272         dc.l            mode_main
273         dc.l            mode_main
274         dc.l            mode_main
275
276 ##################### main #######################
277
278 mode_main:
279         clr.l           d1
280         move.l          a6,d0
281         move.b          d0,d1
282         lsr.l           #8,d0
283         move.l          d0,a1           /* current addr */
284         lsr.b           #3,d1
285         neg.b           d1
286         add.b           #27-1,d1        /* line where the cursor sits */
287         swap            d1
288
289         movea.l         #0xe004,a2
290         move.l          #27-1,d5        /* line counter for dbra */
291         or.l            d1,d5
292
293 draw_column:
294         move.l          a2,a0
295         jsr             load_prepare
296
297         /* addr */
298         move.l          a1,d2
299         moveq.l         #6,d3
300         jsr             print_hex_preped
301
302         /* 4 shorts */
303         moveq.l         #4,d3
304         moveq.l         #4-1,d4
305 draw_shorts:
306         move.w          #' ',(a0)
307         move.w          (a1)+,d2
308         jsr             print_hex_preped
309         dbra            d4,draw_shorts
310
311         move.l          d5,d0
312         swap            d0
313         cmp.w           d5,d0
314         beq             draw_cursor
315
316 draw_chars_pre:
317         move.l          #(' '<<16)|' ',(a0)
318
319         /* 8 chars */
320         subq.l          #8,a1
321         moveq.l         #8-1,d4
322 draw_chars:
323         move.b          (a1)+,d0
324         move.b          d0,d1
325         sub.b           #0x20,d1
326         cmp.b           #0x60,d1
327         blo             0f
328         move.w          #'.',d0
329 0:
330         move.w          d0,(a0)
331         dbra            d4,draw_chars
332
333         add.w           #0x80,a2
334         dbra            d5,draw_column
335
336         /* status bar */
337         movea.l         #0xe004+64*2*27,a0
338         jsr             load_prepare
339         mk_a6_addr      d2
340         move.l          #0x4006,d3
341         jsr             print_hex_preped
342
343         /* handle input */
344         jsr             get_input               /* x0cbrldu x1sa00du */
345
346         btst.l          #16+4,d0                /* A - scroll modifier */
347         beq             input_noa
348
349         do_dpad         16+0,  sub, #0x0800
350         do_dpad         16+1,  add, #0x0800
351         do_dpad         16+10, sub, #0xd800
352         do_dpad         16+11, add, #0xd800
353 input_noa:
354         moveq.l         #0,d1
355         move.w          d7,d1
356         lsr.w           #7,d1
357         lsr.w           #7,d1
358
359         do_dpad         0,  subq, #0x0008
360         do_dpad         1,  addq, #0x0008
361         do_dpad         10, sub, d1
362         do_dpad         11, add, d1
363
364 dpad_end:
365         /* update addr */
366         move.l          a6,d1
367         cmp.b           #0xf0,d1
368         blo             0f
369         sub.l           #0xd800,a6
370         add.w           #0x00d8,a6
371         bra             1f
372 0:
373         cmp.b           #0xd8,d1
374         blo             1f
375         add.l           #0xd800,a6
376         sub.w           #0x00d8,a6
377 1:
378
379         /* other btns */
380         moveq.l         #0,d1
381         btst.l          #12,d0                  /* B - switch byte/word mode */
382         beq             input_nob
383         bclr.l          #15,d7
384         add.w           #0x4000,d7              /* changes between 01 10 */
385         move.l          a6,d1
386         and.l           #1,d1
387         sub.l           d1,a6                   /* make even, just in case */
388
389 input_nob:
390         btst.l          #13,d0                  /* C - edit selected byte */
391         beq             input_noc
392
393         change_mode     MMODE_EDIT_VAL, MMODE_MAIN
394         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
395
396 input_noc:
397         btst.l          #5,d0                   /* Start - goto */
398         beq             input_nos
399
400         change_mode     MMODE_GOTO, MMODE_MAIN
401         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
402
403 input_nos:
404 vbl_end:
405         movem.l         (a7)+,d0-d4/a0-a5
406         rte
407
408
409 draw_cursor:
410         move.l          a6,d0
411         and.l           #7,d0           /* byte offs */
412         move.l          d0,d1
413         lsr.b           #1,d1           /* which word */
414         move.b          d1,d2
415         lsl.b           #2,d2
416         add.b           d2,d1           /* num of chars to skip */
417         lsl.b           #1,d1
418         move.w          #0x2004,d3
419
420         btst.l          #15,d7
421         bne             draw_cursor_word
422
423 draw_cursor_byte:
424         move.b          (-8,a1,d0),d2
425         and.b           #1,d0
426         lsl.b           #2,d0
427         add.b           d0,d1
428         subq.b          #2,d3
429         bra             0f
430
431 draw_cursor_word:
432         move.w          (-8,a1,d0),d2
433 0:
434         lea             (7*2,a2,d1),a0
435         jsr             load_prepare
436         jsr             print_hex_preped
437
438         move.l          a2,a0
439         add.w           #26*2,a0
440         jsr             load_prepare    /* restore a0 */
441
442         jmp             draw_chars_pre
443
444
445 #################### hedit #######################
446
447 mode_edit_val:
448         btst.l          #7,d6
449         bne             mode_hedit_finish
450
451         /* read val to edit */
452         moveq.l         #0,d5
453         mk_a6_addr      d1
454         move.l          d1,a0
455         btst.l          #15,d7
456         bne             0f
457         move.b          (a0),d5
458         lsl.l           #8,d5
459         or.b            #1,d5
460         bra             1f
461 0:
462         move.w          (a0),d5
463         lsl.l           #8,d5
464         or.b            #2,d5
465 1:
466
467         change_mode     MMODE_VAL_INPUT, MMODE_EDIT_VAL
468         jmp             vbl_end
469
470 mode_hedit_finish:
471         /* write the val */
472         mk_a6_addr      d1
473         move.l          d1,a0
474         lsr.l           #8,d5
475
476         btst.l          #15,d7
477         bne             0f
478         move.b          d5,(a0)
479         bra             1f
480 0:
481         move.w          d5,(a0)
482 1:
483
484         bra             return_to_main
485
486 ##################### goto #######################
487
488 mode_goto:
489         btst.l          #7,d6
490         bne             mode_goto_finish
491
492         moveq.l         #0,d5
493         swap            d6
494         move.w          d6,d5
495         swap            d6
496         swap            d5
497         or.b            #3,d5           /* 3 bytes */
498         bclr.l          #7,d6
499         change_mode     MMODE_VAL_INPUT, MMODE_GOTO
500         jmp             vbl_end
501
502 mode_goto_finish:
503         lsr.l           #8,d5
504         move.l          d5,d0
505         move.l          d0,d1
506         and.l           #7,d1
507         and.b           #0xf8,d0
508         lsl.l           #8,d0
509         or.l            d1,d0
510         move.l          d0,a6
511
512         lsr.l           #8,d5
513         swap            d6
514         move.w          d5,d6
515         swap            d6
516
517         bra             return_to_main
518
519 ################### val edit #####################
520
521 mode_val_input:
522         /* frame */
523         movea.l         #0xe000+14*2+11*64*2,a1
524         moveq.l         #6-1,d1
525 0:
526         move.w          a1,a0
527         jsr             load_prepare
528         moveq.l         #11-1,d0
529 1:
530         move.w          #0,(a0)
531         dbra            d0,1b
532
533         add.w           #64*2,a1
534         dbra            d1,0b
535
536         /* text */
537         lea             txt_edit,a0
538         move.l          #15,d0
539         move.l          #11,d1
540         move.l          #0xc000,d2
541         jsr             print
542
543         lea             txt_a_confirm,a0
544         move.l          #15,d0
545         move.l          #15,d1
546         move.l          #0xc000,d2
547         jsr             print
548
549         /* edit field */
550         moveq.l         #0,d0
551         moveq.l         #0,d1
552         moveq.l         #0,d3
553         move.b          d5,d3
554         and.b           #3,d3           /* edit field bytes */
555
556         move.b          #19,d0
557         sub.b           d3,d0
558         move.b          #13,d1
559         move.l          d5,d2
560         lsr.l           #8,d2
561         add.b           d3,d3
562         or.w            #0x8000,d3
563         jsr             print_hex
564
565         /* current char */
566         moveq.l         #0,d0
567         moveq.l         #0,d1
568
569         and.w           #6,d3
570         move.b          #19,d0
571         move.b          d3,d1
572         lsr.b           #1,d1           /* length in bytes */
573         sub.b           d1,d0
574         move.b          d5,d1
575         lsr.b           #2,d1
576         and.b           #7,d1           /* nibble to edit */
577         add.b           d1,d0
578
579         sub.b           d1,d3
580         sub.b           #1,d3           /* chars to shift out */
581         lsl.b           #2,d3
582         add.b           #8,d3
583         move.l          d5,d2
584         lsr.l           d3,d2
585
586         move.b          #13,d1
587         move.w          #0xa001,d3
588         jsr             print_hex
589
590         /* handle input */
591         jsr             get_input       /* x0cbrldu x1sa00du */
592
593         move.w          d0,d1
594         and.w           #0x0f00,d1
595         beq             ai_no_dpad
596         move.b          d5,d1
597         and.b           #3,d1
598         add.b           d1,d1           /* nibble count */
599         sub.b           #1,d1           /* max n.t.e. val */
600         move.b          d5,d2
601         lsr.b           #2,d2
602         and.b           #7,d2           /* nibble to edit */
603
604         move.b          d0,d3
605         and.b           #3,d3
606         beq             ai_no_ud
607         moveq.l         #0,d3
608         moveq.l         #0,d4
609         move.b          #0xf,d3
610         move.b          #0x1,d4
611         sub.b           d2,d1
612         lsl.b           #2,d1
613         add.b           #8,d1
614         lsl.l           d1,d3           /* mask */
615         lsl.l           d1,d4           /* what to add/sub */
616         move.l          d5,d1
617         and.l           d3,d1
618         btst.l          #8,d0
619         beq             0f
620         add.l           d4,d1
621         bra             1f
622 0:
623         sub.l           d4,d1
624 1:
625         and.l           d3,d1
626         eor.l           #0xffffffff,d3
627         and.l           d3,d5
628         or.l            d1,d5
629         jmp             vbl_end
630
631 ai_no_ud:
632         btst.l          #10,d0
633         bne             0f
634         add.b           #1,d2
635         bra             1f
636 0:
637         sub.b           #1,d2
638 1:
639         cmp.b           #0,d2
640         bge             0f
641         move.b          d1,d2
642 0:
643         cmp.b           d1,d2
644         ble             0f
645         move.b          #0,d2
646 0:
647         and.b           #0xe3,d5
648         lsl.b           #2,d2
649         or.b            d2,d5
650         jmp             vbl_end
651
652 ai_no_dpad:
653         move.w          d0,d1
654         and.w           #0x1020,d1
655         beq             ai_no_sb
656
657         bra             return_to_main
658
659 ai_no_sb:
660         btst.l          #4,d0           /* A - confirm */
661         beq             ai_no_input
662         bset.l          #7,d6
663         move.w          d7,d1           /* back to prev mode */
664         and.w           #0x3800,d1
665         lsr.w           #3,d1
666         and.w           #0xc0ff,d7
667         or.w            d1,d7
668
669 ai_no_input:
670         jmp             vbl_end
671
672
673 # go back to main mode
674 return_to_main:
675         bclr.l          #7,d6           /* not edited */
676         change_mode     MMODE_MAIN, MMODE_MAIN
677         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
678         jmp             vbl_end
679
680
681 #################################################
682 #                                               #
683 #         Initialize VDP registers              #
684 #                                               #
685 #################################################
686
687 init_gfx:
688         move.l          #GFXCNTL,a3
689         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
690         write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
691         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
692         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
693         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
694         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
695         write_vdp_reg   6,0     
696         write_vdp_reg   7,0                     /* Backdrop color */
697         write_vdp_reg   10,1                    /* Lines per hblank interrupt */
698         write_vdp_reg   11,0                    /* 2-cell vertical scrolling */
699         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
700         write_vdp_reg   13,(0x8000 >> 10)       /* Horizontal scroll address */
701         write_vdp_reg   15,2
702         write_vdp_reg   16,(VDP16_MAP_V32 | VDP16_MAP_H64)      /* layer size */
703         write_vdp_reg   17,0
704         write_vdp_reg   18,0xff
705         rts
706
707
708 # read single phase from controller
709 #  #a0 - addr
710 #  d0 - result
711 #  destroys d1,d2
712 get_input:
713         move.b          #0x40,(0xa10003)
714         nop
715         nop
716         nop
717         move.b          (0xa10003),d0
718         move.b          #0x00,(0xa10003)
719         lsl.w           #8,d0
720         nop
721         move.b          (0xa10003),d0
722         eor.w           #0xffff,d0
723
724         swap            d7
725         move.w          d7,d1
726         eor.w           d0,d1           /* changed btns */
727         move.w          d0,d7           /* old val */
728         swap            d7
729         and.w           d0,d1           /* what changed now */
730         bne             0f
731
732         addq.b          #1,d6
733         move.b          d6,d2
734         and.b           #7,d2           /* do autorepeat every 8 frames */
735         cmp.b           #7,d2
736         bne             1f
737         move.w          d0,d1
738 0:
739         and.b           #0xf8,d6
740 1:
741         swap            d0
742         move.w          d1,d0
743         rts
744
745 # Load tile data from ROM
746 #  a0: VRAM base
747 #  a1: pattern address
748 #  d0: number of tiles to load
749 #  destroys d1
750
751 load_tiles:
752         move.l          d0,d1
753         VRAM_ADDR_var   a0
754         move.l          d0,(GFXCNTL).l
755         
756         move.l          #GFXDATA,a0
757         lsl.w           #3,d1
758         subq.l          #1,d1
759 0:
760         move.l          (a1)+,(a0)
761         dbra            d1,0b
762
763         rts
764
765
766 # Prepare to write to VDP RAM @a0
767 # sets a0 to VDP data port for convenience
768 #  a0: VRAM base
769 #  destroys d0
770
771 load_prepare:
772         VRAM_ADDR_var   a0
773         move.l          d0,(GFXCNTL).l
774         move.l          #GFXDATA,a0
775         rts
776
777
778 # Load color data from ROM
779 #  a0: CRAM base
780 #  a1: color list address
781 #  d0: number of colors to load
782 #  destroys d1
783
784 load_colors:
785         move.l          d0,d1
786         CRAM_ADDR_var   a0
787         move.l          d0,(GFXCNTL).l
788
789         move.l          #GFXDATA,a0
790         subq.w          #1,d1
791 0:
792         move.w          (a1)+,(a0)
793         dbra            d1,0b
794
795         rts
796
797
798 # print
799 #  a0 - string
800 #  d0 - x
801 #  d1 - y 
802 #  d2 - tile_bits[15:11]
803 #  destroys a1
804
805 print:
806         move.l          a0,a1
807         XY2NT
808         jsr             load_prepare
809         move.l          d2,d0
810         and.w           #0xf800,d0
811
812 _print_loop:
813         move.b          (a1)+,d0
814         beq             _print_end
815
816         move.w          d0,(a0)
817         jmp             _print_loop
818
819 _print_end:
820         rts
821
822
823 # print_hex
824 #  d0 - x
825 #  d1 - y 
826 #  d2 - value
827 #  d3 - digit_cnt[0:7]|tile_bits[11:15]
828 #  destroys a0, preserves d3
829
830 print_hex:
831         XY2NT
832         jsr             load_prepare
833
834 print_hex_preped:
835         moveq.l         #0,d0
836         move.b          d3,d0
837         move.l          d0,d1
838         lsl.b           #2,d0
839         ror.l           d0,d2           /* prep value */
840         subq.l          #1,d1           /* count */
841         move.w          d3,d0
842         and.w           #0xf800,d0      /* keep upper bits in d0 */
843
844 _print_hex_loop:
845         rol.l           #4,d2
846         move.b          d2,d0
847         and.b           #0xf,d0
848
849         add.b           #'0',d0
850         cmp.b           #'9',d0
851         ble             0f
852         addq.b          #7,d0
853 0:
854         move.w          d0,(a0)
855         dbra            d1,_print_hex_loop
856
857         rts
858
859
860 #################################################
861 #                                               #
862 #       Wait for next VBlank interrupt          #
863 #                                               #
864 #################################################
865
866 wait_vsync:
867         move.b          d7,d0
868 _wait_change:
869         stop            #0x2000
870         cmp.b           d7,d0
871         beq             _wait_change
872         rts
873
874
875 #################################################
876 #                                               #
877 #                 RAM DATA                      #
878 #                                               #
879 #################################################
880
881 .bss
882
883 # nothing :)
884
885 .end
886
887 # vim:filetype=asmM68k