goto and 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[31:8]|edit_done[7]|edit_pos[6:4]|autorep_cnt[3:0]
248
249 forever:
250
251
252         jsr             wait_vsync
253         bra             forever
254         
255
256
257 VBL:
258         addq.b          #1,d7
259         movem.l         d0-d5/a0-a5,-(a7)
260
261         moveq.l         #0,d0
262         move.w          d7,d0
263         lsr.w           #6,d0
264         and.w           #0x1c,d0
265         move.l          (jumptab,pc,d0),a0
266         jmp             (a0)
267 jumptab:
268         dc.l            mode_main
269         dc.l            mode_val_input
270         dc.l            mode_edit_val   /* edit val in editor */
271         dc.l            mode_goto
272         dc.l            mode_main
273         dc.l            mode_main
274         dc.l            mode_main
275         dc.l            mode_main
276
277 ##################### main #######################
278
279 mode_main:
280         clr.l           d1
281         move.l          a6,d0
282         move.b          d0,d1
283         lsr.l           #8,d0
284         move.l          d0,a1           /* current addr */
285         lsr.b           #3,d1
286         neg.b           d1
287         add.b           #27-1,d1        /* line where the cursor sits */
288         swap            d1
289
290         movea.l         #0xe004,a2
291         move.l          #27-1,d5        /* line counter for dbra */
292         or.l            d1,d5
293
294 draw_column:
295         move.l          a2,a0
296         jsr             load_prepare
297
298         /* addr */
299         move.l          a1,d2
300         moveq.l         #6,d3
301         jsr             print_hex_preped
302
303         /* 4 shorts */
304         moveq.l         #4,d3
305         moveq.l         #4-1,d4
306 draw_shorts:
307         move.w          #' ',(a0)
308         move.w          (a1)+,d2
309         jsr             print_hex_preped
310         dbra            d4,draw_shorts
311
312         move.l          d5,d0
313         swap            d0
314         cmp.w           d5,d0
315         beq             draw_cursor
316
317 draw_chars_pre:
318         move.l          #(' '<<16)|' ',(a0)
319
320         /* 8 chars */
321         subq.l          #8,a1
322         moveq.l         #8-1,d4
323 draw_chars:
324         move.b          (a1)+,d0
325         move.b          d0,d1
326         sub.b           #0x20,d1
327         cmp.b           #0x60,d1
328         blo             0f
329         move.w          #'.',d0
330 0:
331         move.w          d0,(a0)
332         dbra            d4,draw_chars
333
334         add.w           #0x80,a2
335         dbra            d5,draw_column
336
337         /* status bar */
338         movea.l         #0xe004+64*2*27,a0
339         jsr             load_prepare
340         mk_a6_addr      d2
341         move.l          #0x4006,d3
342         jsr             print_hex_preped
343
344         /* handle input */
345         jsr             get_input               /* x0cbrldu x1sa00du */
346
347         btst.l          #16+4,d0                /* A - scroll modifier */
348         beq             input_noa
349
350         do_dpad         16+0,  sub, #0x0800
351         do_dpad         16+1,  add, #0x0800
352         do_dpad         16+10, sub, #0xd800
353         do_dpad         16+11, add, #0xd800
354 input_noa:
355         moveq.l         #0,d1
356         move.w          d7,d1
357         lsr.w           #7,d1
358         lsr.w           #7,d1
359
360         do_dpad         0,  subq, #0x0008
361         do_dpad         1,  addq, #0x0008
362         do_dpad         10, sub, d1
363         do_dpad         11, add, d1
364
365 dpad_end:
366         /* update addr */
367         move.l          a6,d1
368         cmp.b           #0xf0,d1
369         blo             0f
370         sub.l           #0xd800,a6
371         add.w           #0x00d8,a6
372         bra             1f
373 0:
374         cmp.b           #0xd8,d1
375         blo             1f
376         add.l           #0xd800,a6
377         sub.w           #0x00d8,a6
378 1:
379
380         /* other btns */
381         moveq.l         #0,d1
382         btst.l          #12,d0                  /* B - switch byte/word mode */
383         beq             input_nob
384         bclr.l          #15,d7
385         add.w           #0x4000,d7              /* changes between 01 10 */
386         move.l          a6,d1
387         and.l           #1,d1
388         sub.l           d1,a6                   /* make even, just in case */
389
390 input_nob:
391         btst.l          #13,d0                  /* C - edit selected byte */
392         beq             input_noc
393
394         change_mode     MMODE_EDIT_VAL, MMODE_MAIN
395         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
396
397 input_noc:
398         btst.l          #5,d0                   /* Start - goto */
399         beq             input_nos
400
401         change_mode     MMODE_GOTO, MMODE_MAIN
402         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
403
404 input_nos:
405 vbl_end:
406         movem.l         (a7)+,d0-d5/a0-a5
407         rte
408
409
410 draw_cursor:
411         move.l          a6,d0
412         and.l           #7,d0           /* byte offs */
413         move.l          d0,d1
414         lsr.b           #1,d1           /* which word */
415         move.b          d1,d2
416         lsl.b           #2,d2
417         add.b           d2,d1           /* num of chars to skip */
418         lsl.b           #1,d1
419         move.w          #0x2004,d3
420
421         btst.l          #15,d7
422         bne             draw_cursor_word
423
424 draw_cursor_byte:
425         move.b          (-8,a1,d0),d2
426         and.b           #1,d0
427         lsl.b           #2,d0
428         add.b           d0,d1
429         subq.b          #2,d3
430         bra             0f
431
432 draw_cursor_word:
433         move.w          (-8,a1,d0),d2
434 0:
435         lea             (7*2,a2,d1),a0
436         jsr             load_prepare
437         jsr             print_hex_preped
438
439         move.l          a2,a0
440         add.w           #26*2,a0
441         jsr             load_prepare    /* restore a0 */
442
443         jmp             draw_chars_pre
444
445
446 #################### hedit #######################
447
448 mode_edit_val:
449         btst.l          #7,d6
450         bne             mode_hedit_finish
451
452         /* read val to edit */
453         mk_a6_addr      d1
454         move.l          d1,a0
455         moveq.l         #0,d0
456         btst.l          #15,d7
457         bne             0f
458         move.b          (a0),d0
459         bra             1f
460 0:
461         move.w          (a0),d0
462 1:
463         lsl.l           #8,d0
464         and.l           #0xff,d6
465         or.l            d0,d6
466
467         and.b           #0x0f,d6        /* not done, reset pos */
468         change_mode     MMODE_VAL_INPUT, MMODE_EDIT_VAL
469         jmp             vbl_end
470
471 mode_hedit_finish:
472         /* write the val */
473         mk_a6_addr      d1
474         move.l          d1,a0
475         move.l          d6,d0
476         lsr.l           #8,d0
477
478         btst.l          #15,d7
479         bne             0f
480         move.b          d0,(a0)
481         bra             1f
482 0:
483         move.w          d0,(a0)
484 1:
485
486         and.l           #0xf,d6         /* forget val and pos */
487         bra             return_to_main
488
489 ##################### goto #######################
490
491 mode_goto:
492         btst.l          #7,d6
493         bne             mode_goto_finish
494
495         or.w            #0xc000,d7      /* 3 bytes */
496         bclr.l          #7,d6
497         change_mode     MMODE_VAL_INPUT, MMODE_GOTO
498         jmp             vbl_end
499
500 mode_goto_finish:
501         move.l          d6,d0
502         lsr.l           #8,d0
503         move.l          d0,d1
504         and.l           #7,d1
505         and.b           #0xf8,d0
506         lsl.l           #8,d0
507         or.l            d1,d0
508         move.l          d0,a6
509
510         and.w           #0x3fff,d7
511         or.w            #0x8000,d7      /* back to 2 bytes */
512         bra             return_to_main
513
514 ################### val edit #####################
515
516 mode_val_input:
517         /* frame */
518         movea.l         #0xe000+14*2+11*64*2,a1
519         moveq.l         #6-1,d1
520 0:
521         move.w          a1,a0
522         jsr             load_prepare
523         moveq.l         #11-1,d0
524 1:
525         move.w          #0,(a0)
526         dbra            d0,1b
527
528         add.w           #64*2,a1
529         dbra            d1,0b
530
531         /* text */
532         lea             txt_edit,a0
533         move.l          #15,d0
534         move.l          #11,d1
535         move.l          #0xc000,d2
536         jsr             print
537
538         lea             txt_a_confirm,a0
539         move.l          #15,d0
540         move.l          #15,d1
541         move.l          #0xc000,d2
542         jsr             print
543
544         /* edit field */
545         moveq.l         #0,d0
546         moveq.l         #0,d1
547         moveq.l         #0,d3
548         move.w          d7,d3
549         lsr.w           #7,d3
550         lsr.w           #7,d3
551
552         move.b          #19,d0
553         sub.b           d3,d0
554         move.b          #13,d1
555         move.l          d6,d2
556         lsr.l           #8,d2
557         add.b           d3,d3
558         or.w            #0x8000,d3
559         jsr             print_hex
560
561         /* current char */
562         moveq.l         #0,d0
563         moveq.l         #0,d1
564
565         and.w           #6,d3
566         move.b          #19,d0
567         move.b          d3,d1
568         lsr.b           #1,d1           /* length in bytes */
569         sub.b           d1,d0
570         move.b          d6,d1
571         lsr.b           #4,d1
572         and.b           #7,d1           /* nibble to edit */
573         add.b           d1,d0
574
575         sub.b           d1,d3
576         sub.b           #1,d3           /* chars to shift out */
577         lsl.b           #2,d3
578         add.b           #8,d3
579         move.l          d6,d2
580         lsr.l           d3,d2
581
582         move.b          #13,d1
583         move.w          #0xa001,d3
584         jsr             print_hex
585
586         /* handle input */
587         jsr             get_input       /* x0cbrldu x1sa00du */
588
589         move.w          d0,d1
590         and.w           #0x0f00,d1
591         beq             ai_no_dpad
592         move.w          d7,d1
593         lsr.w           #7,d1
594         lsr.w           #7,d1
595         add.b           d1,d1           /* nibble count */
596         sub.b           #1,d1           /* max n.t.e. val */
597         move.b          d6,d2
598         lsr.b           #4,d2
599         and.b           #7,d2           /* nibble to edit */
600
601         move.b          d0,d3
602         and.b           #3,d3
603         beq             ai_no_ud
604         moveq.l         #0,d3
605         moveq.l         #0,d4
606         move.b          #0xf,d3
607         move.b          #0x1,d4
608         sub.b           d2,d1
609         lsl.b           #2,d1
610         add.b           #8,d1
611         lsl.l           d1,d3           /* mask */
612         lsl.l           d1,d4           /* what to add/sub */
613         move.l          d6,d1
614         and.l           d3,d1
615         btst.l          #8,d0
616         beq             0f
617         add.l           d4,d1
618         bra             1f
619 0:
620         sub.l           d4,d1
621 1:
622         and.l           d3,d1
623         eor.l           #0xffffffff,d3
624         and.l           d3,d6
625         or.l            d1,d6
626         jmp             vbl_end
627
628 ai_no_ud:
629         btst.l          #10,d0
630         bne             0f
631         add.b           #1,d2
632         bra             1f
633 0:
634         sub.b           #1,d2
635 1:
636         cmp.b           #0,d2
637         bge             0f
638         move.b          d1,d2
639 0:
640         cmp.b           d1,d2
641         ble             0f
642         move.b          #0,d2
643 0:
644         and.b           #0x8f,d6
645         lsl.b           #4,d2
646         or.b            d2,d6
647         jmp             vbl_end
648
649 ai_no_dpad:
650         move.w          d0,d1
651         and.w           #0x1020,d1
652         beq             ai_no_sb
653
654         and.l           #0xf,d6         /* forget val and pos */
655         bra             return_to_main
656
657 ai_no_sb:
658         btst.l          #4,d0
659         beq             ai_no_input
660         bset.l          #7,d6
661         move.w          d7,d1
662         and.w           #0x3800,d1
663         lsr.w           #3,d1
664         and.w           #0xc0ff,d7
665         or.w            d1,d7
666
667 ai_no_input:
668         jmp             vbl_end
669
670
671 # go back to main mode
672 return_to_main:
673         bclr.l          #7,d6
674         change_mode     MMODE_MAIN, MMODE_MAIN
675         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
676         jmp             vbl_end
677
678
679 #################################################
680 #                                               #
681 #         Initialize VDP registers              #
682 #                                               #
683 #################################################
684
685 init_gfx:
686         move.l          #GFXCNTL,a3
687         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
688         write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
689         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
690         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
691         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
692         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
693         write_vdp_reg   6,0     
694         write_vdp_reg   7,0                     /* Backdrop color */
695         write_vdp_reg   10,1                    /* Lines per hblank interrupt */
696         write_vdp_reg   11,0                    /* 2-cell vertical scrolling */
697         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
698         write_vdp_reg   13,(0x8000 >> 10)       /* Horizontal scroll address */
699         write_vdp_reg   15,2
700         write_vdp_reg   16,(VDP16_MAP_V32 | VDP16_MAP_H64)      /* layer size */
701         write_vdp_reg   17,0
702         write_vdp_reg   18,0xff
703         rts
704
705
706 # read single phase from controller
707 #  #a0 - addr
708 #  d0 - result
709 #  destroys d1,d2
710 get_input:
711         move.b          #0x40,(0xa10003)
712         nop
713         nop
714         nop
715         move.b          (0xa10003),d0
716         move.b          #0x00,(0xa10003)
717         lsl.w           #8,d0
718         nop
719         move.b          (0xa10003),d0
720         eor.w           #0xffff,d0
721
722         swap            d7
723         move.w          d7,d1
724         eor.w           d0,d1           /* changed btns */
725         move.w          d0,d7           /* old val */
726         swap            d7
727         and.w           d0,d1           /* what changed now */
728         bne             0f
729
730         addq.b          #1,d6
731         move.b          d6,d2
732         and.b           #7,d2           /* do autorepeat every 8 frames */
733         cmp.b           #7,d2
734         bne             1f
735         move.w          d0,d1
736 0:
737         and.b           #0xf8,d6
738 1:
739         swap            d0
740         move.w          d1,d0
741         rts
742
743 # Load tile data from ROM
744 #  a0: VRAM base
745 #  a1: pattern address
746 #  d0: number of tiles to load
747 #  destroys d1
748
749 load_tiles:
750         move.l          d0,d1
751         VRAM_ADDR_var   a0
752         move.l          d0,(GFXCNTL).l
753         
754         move.l          #GFXDATA,a0
755         lsl.w           #3,d1
756         subq.l          #1,d1
757 0:
758         move.l          (a1)+,(a0)
759         dbra            d1,0b
760
761         rts
762
763
764 # Prepare to write to VDP RAM @a0
765 # sets a0 to VDP data port for convenience
766 #  a0: VRAM base
767 #  destroys d0
768
769 load_prepare:
770         VRAM_ADDR_var   a0
771         move.l          d0,(GFXCNTL).l
772         move.l          #GFXDATA,a0
773         rts
774
775
776 # Load color data from ROM
777 #  a0: CRAM base
778 #  a1: color list address
779 #  d0: number of colors to load
780 #  destroys d1
781
782 load_colors:
783         move.l          d0,d1
784         CRAM_ADDR_var   a0
785         move.l          d0,(GFXCNTL).l
786
787         move.l          #GFXDATA,a0
788         subq.w          #1,d1
789 0:
790         move.w          (a1)+,(a0)
791         dbra            d1,0b
792
793         rts
794
795
796 # print
797 #  a0 - string
798 #  d0 - x
799 #  d1 - y 
800 #  d2 - tile_bits[15:11]
801 #  destroys a1
802
803 print:
804         move.l          a0,a1
805         XY2NT
806         jsr             load_prepare
807         move.l          d2,d0
808         and.w           #0xf800,d0
809
810 _print_loop:
811         move.b          (a1)+,d0
812         beq             _print_end
813
814         move.w          d0,(a0)
815         jmp             _print_loop
816
817 _print_end:
818         rts
819
820
821 # print_hex
822 #  d0 - x
823 #  d1 - y 
824 #  d2 - value
825 #  d3 - digit_cnt[0:7]|tile_bits[11:15]
826 #  destroys a0, preserves d3
827
828 print_hex:
829         XY2NT
830         jsr             load_prepare
831
832 print_hex_preped:
833         moveq.l         #0,d0
834         move.b          d3,d0
835         move.l          d0,d1
836         lsl.b           #2,d0
837         ror.l           d0,d2           /* prep value */
838         subq.l          #1,d1           /* count */
839         move.w          d3,d0
840         and.w           #0xf800,d0      /* keep upper bits in d0 */
841
842 _print_hex_loop:
843         rol.l           #4,d2
844         move.b          d2,d0
845         and.b           #0xf,d0
846
847         add.b           #'0',d0
848         cmp.b           #'9',d0
849         ble             0f
850         addq.b          #7,d0
851 0:
852         move.w          d0,(a0)
853         dbra            d1,_print_hex_loop
854
855         rts
856
857
858 #################################################
859 #                                               #
860 #       Wait for next VBlank interrupt          #
861 #                                               #
862 #################################################
863
864 wait_vsync:
865         move.b          d7,d0
866 _wait_change:
867         stop            #0x2000
868         cmp.b           d7,d0
869         beq             _wait_change
870         rts
871
872
873 #################################################
874 #                                               #
875 #                 RAM DATA                      #
876 #                                               #
877 #################################################
878
879 .bss
880
881 # nothing :)
882
883 .end
884
885 # vim:filetype=asmM68k