hexed: use bin size for reloc; minor updates
[megadrive.git] / hexed / hexed.s
1 ###############################################################################
2 #
3 # Copyright (c) 2009,2011 GraÅžvydas Ignotas
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 #     * Redistributions of source code must retain the above copyright
9 #       notice, this list of conditions and the following disclaimer.
10 #     * Redistributions in binary form must reproduce the above copyright
11 #       notice, this list of conditions and the following disclaimer in the
12 #       documentation and/or other materials provided with the distribution.
13 #     * Neither the name of the organization nor the
14 #       names of its contributors may be used to endorse or promote products
15 #       derived from this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND ANY
18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 # DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
21 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #
28 # Assemble with gas
29 #   --register-prefix-optional --bitwise-or
30 #
31
32 .equ USE_VINT,        0
33 .equ COPY_TO_EXP,     1
34 .equ RELOCATE_TO_RAM, 1
35
36 .text
37 .globl main
38 .globl INT
39 .globl VBL
40 .globl return_to_main
41
42 ##################################################
43 #                                                #
44 #        Register and bitmask definitions        #
45 #                                                #
46 ##################################################
47
48 .equ GFXDATA,           0xc00000
49 .equ GFXCNTL,           0xc00004
50
51 .equ VDP0_E_HBI,        0x10
52 .equ VDP0_E_DISPLAY,    0x02 
53 .equ VDP0_PLTT_FULL,    0x04 
54
55 .equ VDP1_SMS_MODE,     0x80
56 .equ VDP1_E_DISPLAY,    0x40
57 .equ VDP1_E_VBI,        0x20
58 .equ VDP1_E_DMA,        0x10
59 .equ VDP1_NTSC,         0x00
60 .equ VDP1_PAL,          0x08
61 .equ VDP1_MODE5,        0x04
62
63 .equ VDP12_STE,         0x08
64 .equ VDP12_SCREEN_V224, 0x00
65 .equ VDP12_SCREEN_V448, 0x04
66 .equ VDP12_PROGRESSIVE, 0x00
67 .equ VDP12_INTERLACED,  0x02
68 .equ VDP12_SCREEN_H256, 0x00
69 .equ VDP12_SCREEN_H320, 0x81
70
71 .equ VDP16_MAP_V32,     0x00
72 .equ VDP16_MAP_V64,     0x10
73 .equ VDP16_MAP_V128,    0x30
74 .equ VDP16_MAP_H32,     0x00
75 .equ VDP16_MAP_H64,     0x01
76 .equ VDP16_MAP_H128,    0x03
77
78 .equ MMODE_MAIN,        0
79 .equ MMODE_VAL_INPUT,   1
80 .equ MMODE_EDIT_VAL,    2
81 .equ MMODE_GOTO,        3
82 .equ MMODE_START_MENU,  4
83 .equ MMODE_GOTO_PREDEF, 5
84 .equ MMODE_JMP_ADDR,    6
85 .equ MMODE_PC,          7
86
87 .equ predef_addr_cnt,   ((predef_addrs_end-predef_addrs)/4)
88
89 ##################################################
90 #                                                #
91 #                   MACROS                       #
92 #                                                #
93 ##################################################
94
95
96 # Write val to VDP register reg
97 .macro write_vdp_r_dst reg val dst
98         move.w #((\reg << 8) + 0x8000 + \val),\dst
99 .endm
100
101 # Write val to VDP register reg, vdp addr in a3
102 .macro write_vdp_reg reg val
103         write_vdp_r_dst \reg, \val, (a3)
104 .endm
105
106 # Set up address in VDP, control port in dst
107 .macro VRAM_ADDR adr dst
108         move.l #(0x40000000 | ((\adr & 0x3fff) << 16) | (\adr >> 14)),\dst
109 .endm
110
111 .macro VSRAM_ADDR adr dst
112         move.l #(0x40000010 | ((\adr & 0x3fff) << 16) | (\adr >> 14)),\dst
113 .endm
114
115
116 # make VDP word from address adr and store in d0
117 .macro XRAM_ADDR_var adr
118         move.l \adr,d0
119         lsl.l #8,d0
120         lsl.l #8,d0
121         rol.l #2,d0
122         lsl.b #2,d0
123         lsr.l #2,d0
124 .endm
125
126
127 .macro VRAM_ADDR_var adr
128         XRAM_ADDR_var \adr
129         or.l #0x40000000,d0
130 .endm
131
132
133 .macro CRAM_ADDR_var adr
134         XRAM_ADDR_var \adr
135         or.l #0xc0000000,d0
136 .endm
137
138
139 # convert tile coords in d0, d1 to nametable addr to a0
140 .macro XY2NT
141         lsl.w           #6,d1
142         add.w           d1,d0
143         lsl.w           #1,d0
144         movea.l         #0xe000,a0
145         add.w           d0,a0
146 .endm
147
148 # check if some d-pad button (and modifier) is pressed
149 .macro do_dpad bit op val
150         btst.l          #\bit,d0
151         beq             0f
152         \op.l           \val,a6
153         bra             dpad_end
154 0:
155 .endm
156
157 # convert a6 to normal addr
158 #  destroys d0
159 .macro mk_a6_addr reg
160         move.l          a6,\reg
161         moveq.l         #0,d0
162         move.b          \reg,d0
163         lsr.l           #8,\reg
164         add.l           d0,\reg
165 .endm
166
167 .macro change_mode mode_new mode_back
168         and.w           #0xc0ff,d7
169         or.w            #(\mode_back<<11)|(\mode_new<<8),d7
170 .endm
171
172 #  destroys a0,d0-d2
173 .macro menu_text str x y pal
174         lea             (\str,pc),a0
175         move.l          #\x,d0
176         move.l          #\y,d1
177         move.l          #0x8000|(\pal<<13),d2
178         jsr             print
179 .endm
180
181 #################################################
182 #                                               #
183 #                    DATA                       #
184 #                                               #
185 #################################################
186
187 colors:
188         dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
189         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
190         dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
191         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
192         dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
193         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
194         dc.w 0x0000,0x044e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
195         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
196 colors_end:
197
198
199 sprite_data:
200         /*         Y        size     link          attr        X */
201         dc.w       0;  dc.b 0x05;  dc.b 0;  dc.w 0x6002;  dc.w 0
202 sprite_data_end:
203
204 predef_addrs:
205         dc.l 0x000000, 0x200000, 0x400000, 0xa00000, 0xa10000
206         dc.l 0xa11100, 0xa12000, 0xa13000, 0xa14000, 0xc00000
207 predef_addrs_end:
208
209 safe_addrs:
210         dc.l 0x000000, 0x7fffff
211         dc.l 0xe00000, 0xffffff
212         dc.l 0xa00000, 0xa100ff
213         dc.l 0xa11000, 0xa113ff
214         dc.l 0xa12000, 0xa120ff
215         dc.l 0xa13000, 0xa130ff
216 safe_addrs_end:
217
218 sizeof_bin:
219         dc.l _edata
220
221 txt_edit:
222         .ascii  "- edit -\0"
223 txt_a_confirm:
224         .ascii  "A-confirm\0"
225 txt_about:
226         .ascii  "hexed r2\0"
227 txt_goto:
228         .ascii  "Go to address\0"
229 txt_goto_predef:
230         .ascii  "Go to (predef)\0"
231 txt_jmp_addr:
232         .ascii  "Jump to address\0"
233 txt_dump:
234         .ascii  "PC Transfer\0"
235 txt_dtack:
236         .ascii  "DTACK safety\0"
237 txt_transfer_ready:
238         .ascii  "Transfer Ready\0"
239 txt_working:
240         .ascii  "PC mode       \0"
241 txt_dtack_err:
242         .ascii  "DTACK err?\0"
243 txt_exc:
244         .ascii  "Exception \0"
245
246 ##################################################
247 #                                                #
248 #               MAIN PROGRAM                     #
249 #                                                #
250 ##################################################
251
252 # global regs:
253 # a6 = page_start[31:8]|cursor_offs[7:0]
254 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
255 # d6 = edit_word_save[31:15]|edit_done[7]|no_dtack_detect[4]|autorep_cnt[3:0]
256 # d5 = main: tmp
257 #      edit: edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]
258 #      menu: sel
259
260 .align 2
261
262 main:
263         /* make sure io port 2 is doing inputs */
264         move.b          #0,(0xa1000b).l
265         /* mask irqs during init */
266         move.w          #0x2700,sr
267
268 .if COPY_TO_EXP
269         /* copy to expansion device if magic number is set */
270         move.l          #0x400000,a1
271         cmp.w           #0x1234,(a1)
272         bne             0f
273
274         move.l          #0,a0
275         move.l          (sizeof_bin,pc),d0
276         lsr.l           #3,d0
277 1:
278         move.l          (a0)+,(a1)+
279         move.l          (a0)+,(a1)+
280         dbra            d0,1b
281 0:
282 .endif
283
284 .if RELOCATE_TO_RAM
285         /* we could be relocated by 32x or something else, adjust start addr */
286         lea             (pc),a0
287         move.l          a0,d0
288         and.l           #0xff0000,d0
289         move.l          d0,a0
290
291         /* copy, assume 8K size */
292         move.l          #0xFF0100,a1
293         move.l          (sizeof_bin,pc),d0
294         lsr.l           #3,d0
295 1:
296         move.l          (a0)+,(a1)+
297         move.l          (a0)+,(a1)+
298         dbra            d0,1b
299
300         /* copy test code */
301         lea             (test_code,pc),a0
302         move.l          #0xffc000,a1
303         move.w          #(test_code_end - test_code)/2-1,d0
304 1:
305         move.w          (a0)+,(a1)+
306         dbra            d0,1b
307
308         lea             (0f,pc),a0
309         move.l          a0,d0
310         and.l           #0x00ffff,d0
311         add.l           #0xFF0100,d0
312         move.l          d0,a0
313
314         /* patch test code */
315         move.l          #0xffc000,a1
316         add.w           #(test_code_ret_op-test_code+2),a1
317         move.l          a0,(a1)
318
319         jmp             (a0)
320 0:
321 .endif
322
323         movea.l         #0,a6
324         move.l          #0x8000,d7
325         moveq.l         #0,d6
326
327         /* Init pads */
328         move.b          #0x40,(0xa10009).l
329         move.b          #0x40,(0xa10003).l
330
331         /* Initialize VDP */
332         jsr             init_gfx
333
334         /* Clear h/v scroll */
335         movea.l         #GFXDATA,a0
336         VRAM_ADDR       0x8000,(GFXCNTL)
337         move.l          #0,(a0)
338         VSRAM_ADDR      0,(GFXCNTL)
339         move.l          #0,(a0)
340
341         /* Load color data */
342         movea.l         #0,a0
343         lea             (colors,pc),a1
344         moveq.l         #(colors_end-colors)/2,d0
345         jsr             load_colors
346
347         /* load font patterns */
348         movea.l         #GFXDATA,a0
349         lea             (font,pc),a1
350         VRAM_ADDR       0,(GFXCNTL)
351         move.w          #128*8,d3
352 font_loop:
353         moveq.l         #8-1,d2
354         moveq.l         #0,d1
355         move.b          (a1)+,d0
356 0:
357         lsr.b           #1,d0
358         roxl.l          #1,d1
359         ror.l           #5,d1
360         dbra            d2,0b
361
362         rol.l           #1,d1           /* fixup */
363         move.l          d1,(a0)
364         dbra            d3,font_loop
365
366         /* generate A layer map */
367         movea.l         #0xe000,a1
368         move.l          #28-1,d4
369 lmaploop0:
370         movea.l         a1,a0
371         jsr             load_prepare
372
373         move.l          #64/2-1,d3
374 0:      move.l          #0x00000000,(a0)
375         dbra            d3,0b
376
377         add.l           #64*2,a1
378         dbra            d4,lmaploop0
379
380         /* generate B layer map */
381         movea.l         #0xc000,a0
382         jsr             load_prepare
383
384         move.l          #64*28/2-1,d3
385 0:      move.l          #0x00000000,(a0)
386         dbra            d3,0b
387
388         /* upload sprite data */
389         movea.l         #0xfc00,a0
390         jsr             load_prepare
391         lea             (sprite_data,pc),a1
392
393         move.l          #(sprite_data_end-sprite_data)/2-1,d3
394 0:      move.l          (a1)+,(a0)
395         dbra            d3,0b
396
397 .if USE_VINT
398         /* wait for vsync before unmask */
399         jsr             wait_vsync_poll
400
401         /* wait a bit to avoid nested vint */
402         move.w          #20,d0
403 0:
404         dbra            d0,0b           /* 10 cycles to go back */
405
406         /* enable and unmask vint */
407         write_vdp_r_dst 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)
408         move.w          #0x2000,sr
409 .endif
410
411 ##################################################
412
413 forever:
414 .if USE_VINT
415         jsr             wait_vsync
416 .else
417         jsr             wait_vsync_poll
418         jsr             VBL
419 .endif
420         bra             forever
421
422
423 INT:
424         /* let's hope VRAM is already set up.. */
425         lea             (txt_exc,pc),a0
426         move.l          #9,d0
427         move.l          #27,d1
428         move.l          #0xe000,d2
429         jsr             print
430         bra             forever
431
432 ##################################################
433
434 VBL:
435         addq.b          #1,d7
436 #       movem.l         d0-d4/a0-a5,-(a7)
437
438         btst.b          #5,(0xa10005).l
439         bne             no_auto_transfer
440         change_mode     MMODE_PC, MMODE_MAIN
441         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
442
443 no_auto_transfer:
444         moveq.l         #0,d0
445         move.w          d7,d0
446         lsr.w           #6,d0
447         and.w           #0x1c,d0
448         lea             (jumptab,pc,d0),a0
449         jmp             (a0)
450 jumptab:
451         /* branch insns here because we want to be position independent */
452         bra             mode_main
453         bra             mode_val_input
454         bra             mode_edit_val   /* edit val in editor */
455         bra             mode_goto
456         bra             mode_start_menu
457         bra             mode_goto_predef
458         bra             mode_jmp_addr
459         bra             mode_transfer
460
461 ##################### main #######################
462
463 mode_main:
464         /* assume we will hang */
465         lea             (txt_dtack_err,pc),a0
466         move.l          #9,d0
467         move.l          #27,d1
468         move.l          #0xe000,d2
469         jsr             print
470
471         moveq.l         #0,d1
472         move.l          a6,d0
473         move.b          d0,d1
474         lsr.l           #8,d0
475         move.l          d0,a1           /* current addr */
476         lsr.b           #3,d1
477         neg.b           d1
478         add.b           #27-1,d1        /* line where the cursor sits */
479         swap            d1
480
481         movea.l         #0xe002,a2
482         move.l          #27-1,d5        /* line counter for dbra */
483         or.l            d1,d5
484
485 draw_row:
486         move.l          a2,a0
487         jsr             load_prepare
488
489         btst.l          #15,d7
490         beq             0f
491         move.w          #' ',(a0)
492 0:
493         /* addr */
494         move.l          a1,d2
495         moveq.l         #6,d3
496         jsr             print_hex_preped
497
498         btst.l          #4,d6
499         bne             draw_row_safe
500
501         bsr             get_safety_mask
502         cmp.b           #0xf,d0
503         beq             draw_row_safe
504
505 # unsafe or partially safe
506 draw_row_hsafe:
507         move.l          d0,d4
508         swap            d4              /* mask in upper word */
509         btst.l          #15,d7
510         bne             draw_row_hsafe_words_pre
511
512 draw_row_hsafe_bytes_pre:
513         /* 8 bytes */
514         moveq.l         #2,d3
515         move.w          #3,d4
516
517 draw_row_hsafe_bytes:
518         move.w          #' ',(a0)
519         move.b          d4,d0
520         add.b           #16,d0
521         btst.l          d0,d4
522         bne             0f
523         move.l          #'?'|('?'<<16),(a0)
524         move.w          #' ',(a0)
525         move.l          #'?'|('?'<<16),(a0)
526         bra             1f
527 0:
528         move.b          (0,a1),d2
529         jsr             print_hex_preped
530         move.w          #' ',(a0)
531         move.b          (1,a1),d2
532         jsr             print_hex_preped
533 1:
534         addq.l          #2,a1
535         dbra            d4,draw_row_hsafe_bytes
536
537         move.w          #' ',(a0)
538
539         move.l          d5,d0
540         swap            d0
541         cmp.w           d5,d0
542         beq             draw_cursor_unsafe_byte
543         bra             draw_chars_hsafe_pre
544
545 draw_row_hsafe_words_pre:
546         /* 4 shorts */
547         moveq.l         #4,d3
548         move.w          #3,d4
549
550 draw_row_hsafe_words:
551         move.w          #' ',(a0)
552         move.b          d4,d0
553         add.b           #16,d0
554         btst.l          d0,d4
555         bne             0f
556         move.l          #'?'|('?'<<16),(a0)
557         move.l          #'?'|('?'<<16),(a0)
558         bra             1f
559 0:
560         move.w          (a1),d2
561         jsr             print_hex_preped
562 1:
563         addq.l          #2,a1
564         dbra            d4,draw_row_hsafe_words
565
566         move.l          #(' '<<16)|' ',(a0)
567
568         move.l          d5,d0
569         swap            d0
570         cmp.w           d5,d0
571         beq             draw_cursor_unsafe_word
572
573 draw_chars_hsafe_pre:
574         subq.l          #8,a1
575         move.w          #3,d4
576         moveq.l         #0,d0
577
578 draw_chars_hsafe:
579         move.b          d4,d0
580         add.b           #16,d0
581         btst.l          d0,d4
582         bne             0f
583         move.l          #'?'|('?'<<16),(a0)
584         bra             draw_chars_hsafe_next
585 0:
586         btst.l          #15,d7          /* must perform correct read type */
587         bne             0f              /* doing byte reads on security reg hangs */
588         move.b          (0,a1),d0
589         lsl.l           #8,d0
590         move.b          (1,a1),d0
591         bra             1f
592 0:
593         move.w          (a1),d0
594 1:
595         ror.l           #8,d0
596         move.b          d0,d1
597         sub.b           #0x20,d1
598         cmp.b           #0x60,d1
599         blo             0f
600         move.b          #'.',d0
601 0:
602         move.w          d0,(a0)
603
604         move.b          #0,d0
605         rol.l           #8,d0
606         move.b          d0,d1
607         sub.b           #0x20,d1
608         cmp.b           #0x60,d1
609         blo             0f
610         move.b          #'.',d0
611 0:
612         move.w          d0,(a0)
613
614 draw_chars_hsafe_next:
615         addq.l          #2,a1
616         dbra            d4,draw_chars_hsafe
617
618         move.l          #(' '<<16)|' ',(a0)
619         add.w           #0x80,a2
620         dbra            d5,draw_row
621         bra             draw_status_bar
622
623
624 # normal draw
625 draw_row_safe:
626         btst.l          #15,d7
627         bne             draw_row_words
628
629 draw_row_bytes:
630         /* 8 bytes */
631         moveq.l         #2,d3
632         moveq.l         #8-1,d4
633 draw_bytes:
634         move.w          #' ',(a0)
635         move.b          (a1)+,d2
636         jsr             print_hex_preped
637         dbra            d4,draw_bytes
638
639         move.w          #' ',(a0)
640
641         move.l          d5,d0
642         swap            d0
643         cmp.w           d5,d0
644         beq             draw_cursor_byte
645         bra             draw_chars_pre
646
647 draw_row_words:
648         /* 4 shorts */
649         moveq.l         #4,d3
650         moveq.l         #4-1,d4
651 draw_words:
652         move.w          #' ',(a0)
653         move.w          (a1)+,d2
654         jsr             print_hex_preped
655         dbra            d4,draw_words
656
657         move.l          #(' '<<16)|' ',(a0)
658
659         move.l          d5,d0
660         swap            d0
661         cmp.w           d5,d0
662         beq             draw_cursor_word
663
664 draw_chars_pre:
665         /* 8 chars */
666         subq.l          #8,a1
667         moveq.l         #8-1,d4
668 draw_chars:
669         move.b          (a1)+,d0
670         move.b          d0,d1
671         sub.b           #0x20,d1
672         cmp.b           #0x60,d1
673         blo             0f
674         move.w          #'.',d0
675 0:
676         move.w          d0,(a0)
677         dbra            d4,draw_chars
678
679         move.l          #(' '<<16)|' ',(a0)
680
681         add.w           #0x80,a2
682         dbra            d5,draw_row
683
684
685 draw_status_bar:
686         /* status bar */
687         move.l          a2,a0
688         jsr             load_prepare
689
690         btst.l          #15,d7
691         beq             0f
692         move.w          #' ',(a0)
693 0:
694         mk_a6_addr      d2
695         move.l          #0x4006,d3
696         jsr             print_hex_preped
697
698         /* clear error */
699         moveq.l         #5-1,d0
700 0:
701         move.l          #' '|(' '<<16),(a0)
702         move.l          #' '|(' '<<16),(a0)
703         dbra            d0,0b
704
705
706         /* handle input */
707         jsr             get_input               /* x0cbrldu x1sa00du */
708
709         btst.l          #16+4,d0                /* A - scroll modifier */
710         beq             input_noa
711
712         do_dpad         16+0,  sub, #0x0800
713         do_dpad         16+1,  add, #0x0800
714         do_dpad         16+10, sub, #0xd800
715         do_dpad         16+11, add, #0xd800
716 input_noa:
717         moveq.l         #0,d1
718         move.w          d7,d1
719         lsr.w           #7,d1
720         lsr.w           #7,d1
721
722         do_dpad         0,  subq, #0x0008
723         do_dpad         1,  addq, #0x0008
724         do_dpad         10, sub, d1
725         do_dpad         11, add, d1
726
727 dpad_end:
728         /* update addr */
729         move.l          a6,d1
730         cmp.b           #0xf0,d1
731         blo             0f
732         sub.l           #0xd800,a6
733         add.w           #0x00d8,a6
734         bra             1f
735 0:
736         cmp.b           #0xd8,d1
737         blo             1f
738         add.l           #0xd800,a6
739         sub.w           #0x00d8,a6
740 1:
741
742         /* other btns */
743         moveq.l         #0,d1
744         btst.l          #12,d0                  /* B - switch byte/word mode */
745         beq             input_nob
746         bclr.l          #15,d7
747         add.w           #0x4000,d7              /* changes between 01 10 */
748         move.l          a6,d1
749         and.l           #1,d1
750         sub.l           d1,a6                   /* make even, just in case */
751
752 input_nob:
753         btst.l          #13,d0                  /* C - edit selected byte */
754         beq             input_noc
755
756         change_mode     MMODE_EDIT_VAL, MMODE_MAIN
757         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
758
759 input_noc:
760         btst.l          #5,d0                   /* Start - menu */
761         beq             input_nos
762
763         moveq.l         #0,d5
764         change_mode     MMODE_START_MENU, MMODE_MAIN
765         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
766
767 input_nos:
768 vbl_end:
769 #       movem.l         (a7)+,d0-d4/a0-a5
770 .if USE_VINT
771         rte
772 .else
773         rts
774 .endif
775
776
777 draw_cursor_unsafe_byte:
778         move.l          a6,d0
779         and.l           #7,d0           /* byte offs */
780         move.b          d0,d1
781         add.b           d0,d0
782         add.b           d1,d0           /* d0 *= 3 (chars) */
783         add.b           d0,d0
784         lea             (7*2,a2,d0),a0
785         jsr             load_prepare
786         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),(a0)
787
788         move.l          a2,a0
789         add.w           #31*2,a0
790         jsr             load_prepare    /* restore a0 */
791         bra             draw_chars_hsafe_pre
792
793 draw_cursor_unsafe_word:
794         move.l          a6,d0
795         and.l           #7,d0           /* byte offs */
796         move.l          d0,d1
797         lsr.b           #1,d1           /* which word */
798         move.b          d1,d2
799         lsl.b           #2,d2
800         add.b           d2,d1           /* num of chars to skip */
801         add.b           d1,d1
802
803         lea             (8*2,a2,d1),a0
804         jsr             load_prepare
805         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),d0
806         move.l          d0,(a0)
807         move.l          d0,(a0)
808
809         move.l          a2,a0
810         add.w           #29*2,a0
811         jsr             load_prepare    /* restore a0 */
812         bra             draw_chars_hsafe_pre
813
814
815 draw_cursor_byte:
816         move.l          a6,d0
817         and.l           #7,d0           /* byte offs */
818         move.w          #0x2002,d3
819
820         move.b          (-8,a1,d0),d2
821         move.b          d0,d1
822         add.b           d0,d0
823         add.b           d1,d0           /* d0 *= 3 (chars) */
824         add.b           d0,d0
825         lea             (7*2,a2,d0),a0
826         jsr             load_prepare
827         jsr             print_hex_preped
828
829         move.l          a2,a0
830         add.w           #31*2,a0
831         jsr             load_prepare    /* restore a0 */
832
833         bra             draw_chars_pre
834
835 draw_cursor_word:
836         move.l          a6,d0
837         and.l           #7,d0           /* byte offs */
838         move.l          d0,d1
839         lsr.b           #1,d1           /* which word */
840         move.b          d1,d2
841         lsl.b           #2,d2
842         add.b           d2,d1           /* num of chars to skip */
843         add.b           d1,d1
844         move.w          #0x2004,d3
845
846         move.w          (-8,a1,d0),d2
847         lea             (8*2,a2,d1),a0
848         jsr             load_prepare
849         jsr             print_hex_preped
850
851         move.l          a2,a0
852         add.w           #29*2,a0
853         jsr             load_prepare    /* restore a0 */
854
855         bra             draw_chars_pre
856
857
858 #################### hedit #######################
859
860 mode_edit_val:
861         btst.l          #7,d6
862         bne             mode_hedit_finish
863
864         /* read val to edit */
865         moveq.l         #0,d5
866         mk_a6_addr      d1
867         move.l          d1,a0
868         btst.l          #15,d7
869         bne             0f
870         move.b          (a0),d5
871         lsl.l           #8,d5
872         or.b            #1,d5
873         bra             1f
874 0:
875         move.w          (a0),d5
876         lsl.l           #8,d5
877         or.b            #2,d5
878 1:
879
880         change_mode     MMODE_VAL_INPUT, MMODE_EDIT_VAL
881         bra             vbl_end
882
883 mode_hedit_finish:
884         /* write the val */
885         mk_a6_addr      d1
886         move.l          d1,a0
887         lsr.l           #8,d5
888
889         btst.l          #15,d7
890         bne             0f
891         move.b          d5,(a0)
892         bra             1f
893 0:
894         move.w          d5,(a0)
895 1:
896
897         bra             return_to_main
898
899 ##################### goto #######################
900
901 mode_goto:
902         btst.l          #7,d6
903         bne             mode_goto_finish
904
905         moveq.l         #0,d5
906         swap            d6
907         move.w          d6,d5
908         swap            d6
909         swap            d5
910         or.b            #3,d5           /* 3 bytes */
911         bclr.l          #7,d6
912         change_mode     MMODE_VAL_INPUT, MMODE_GOTO
913         bra             vbl_end
914
915 mode_goto_finish:
916         lsr.l           #8,d5
917         move.l          d5,d0
918         move.l          d0,d1
919         and.l           #7,d1
920         and.b           #0xf8,d0
921         lsl.l           #8,d0
922         or.l            d1,d0
923         move.l          d0,a6
924
925         lsr.l           #8,d5
926         swap            d6
927         move.w          d5,d6
928         swap            d6
929
930         bra             return_to_main
931
932 ################### val edit #####################
933
934 mode_val_input:
935         /* frame */
936         movea.l         #0xe000+14*2+11*64*2,a1
937         moveq.l         #6-1,d1
938 0:
939         move.w          a1,a0
940         jsr             load_prepare
941         moveq.l         #11-1,d0
942 1:
943         move.w          #0,(a0)
944         dbra            d0,1b
945
946         add.w           #64*2,a1
947         dbra            d1,0b
948
949         /* text */
950         lea             (txt_edit,pc),a0
951         move.l          #15,d0
952         move.l          #11,d1
953         move.l          #0xc000,d2
954         jsr             print
955
956         lea             (txt_a_confirm,pc),a0
957         move.l          #15,d0
958         move.l          #15,d1
959         move.l          #0xc000,d2
960         jsr             print
961
962         /* edit field */
963         moveq.l         #0,d0
964         moveq.l         #0,d1
965         moveq.l         #0,d3
966         move.b          d5,d3
967         and.b           #3,d3           /* edit field bytes */
968
969         move.b          #19,d0
970         sub.b           d3,d0
971         move.b          #13,d1
972         move.l          d5,d2
973         lsr.l           #8,d2
974         add.b           d3,d3
975         or.w            #0x8000,d3
976         jsr             print_hex
977
978         /* current char */
979         moveq.l         #0,d0
980         moveq.l         #0,d1
981
982         and.w           #6,d3
983         move.b          #19,d0
984         move.b          d3,d1
985         lsr.b           #1,d1           /* length in bytes */
986         sub.b           d1,d0
987         move.b          d5,d1
988         lsr.b           #2,d1
989         and.b           #7,d1           /* nibble to edit */
990         add.b           d1,d0
991
992         sub.b           d1,d3
993         sub.b           #1,d3           /* chars to shift out */
994         lsl.b           #2,d3
995         add.b           #8,d3
996         move.l          d5,d2
997         lsr.l           d3,d2
998
999         move.b          #13,d1
1000         move.w          #0xa001,d3
1001         jsr             print_hex
1002
1003         /* handle input */
1004         jsr             get_input       /* x0cbrldu x1sa00du */
1005
1006         move.w          d0,d1
1007         and.w           #0x0f00,d1
1008         beq             ai_no_dpad
1009         move.b          d5,d1
1010         and.b           #3,d1
1011         add.b           d1,d1           /* nibble count */
1012         sub.b           #1,d1           /* max n.t.e. val */
1013         move.b          d5,d2
1014         lsr.b           #2,d2
1015         and.b           #7,d2           /* nibble to edit */
1016
1017         move.b          d0,d3
1018         and.b           #3,d3
1019         beq             ai_no_ud
1020         moveq.l         #0,d3
1021         moveq.l         #0,d4
1022         move.b          #0xf,d3
1023         move.b          #0x1,d4
1024         sub.b           d2,d1
1025         lsl.b           #2,d1
1026         add.b           #8,d1
1027         lsl.l           d1,d3           /* mask */
1028         lsl.l           d1,d4           /* what to add/sub */
1029         move.l          d5,d1
1030         and.l           d3,d1
1031         btst.l          #8,d0
1032         beq             0f
1033         add.l           d4,d1
1034         bra             1f
1035 0:
1036         sub.l           d4,d1
1037 1:
1038         and.l           d3,d1
1039         eor.l           #0xffffffff,d3
1040         and.l           d3,d5
1041         or.l            d1,d5
1042         bra             vbl_end
1043
1044 ai_no_ud:
1045         btst.l          #10,d0
1046         bne             0f
1047         add.b           #1,d2
1048         bra             1f
1049 0:
1050         sub.b           #1,d2
1051 1:
1052         cmp.b           #0,d2
1053         bge             0f
1054         move.b          d1,d2
1055 0:
1056         cmp.b           d1,d2
1057         ble             0f
1058         move.b          #0,d2
1059 0:
1060         and.b           #0xe3,d5
1061         lsl.b           #2,d2
1062         or.b            d2,d5
1063         bra             vbl_end
1064
1065 ai_no_dpad:
1066         move.w          d0,d1
1067         and.w           #0x1020,d1
1068         beq             ai_no_sb
1069
1070         bra             return_to_main
1071
1072 ai_no_sb:
1073         btst.l          #4,d0           /* A - confirm */
1074         beq             ai_no_input
1075         bset.l          #7,d6
1076         move.w          d7,d1           /* back to prev mode */
1077         and.w           #0x3800,d1
1078         lsr.w           #3,d1
1079         and.w           #0xc0ff,d7
1080         or.w            d1,d7
1081
1082 ai_no_input:
1083         bra             vbl_end
1084
1085
1086 ################### start menu ###################
1087
1088 mode_start_menu:
1089         /* frame */
1090         bsr             start_menu_box
1091
1092         /* text */
1093         menu_text       txt_about,       13,  9, 1
1094         menu_text       txt_goto,        13, 11, 0
1095         menu_text       txt_goto_predef, 13, 12, 0
1096         menu_text       txt_jmp_addr,    13, 13, 0
1097         menu_text       txt_dump,        13, 14, 0
1098         menu_text       txt_dtack,       13, 15, 0
1099         menu_text       txt_a_confirm,   13, 17, 2
1100
1101         /* dtack safety on/off */
1102         movea.l         #0xe000+26*2+15*64*2,a0
1103         jsr             load_prepare
1104         move.w          #0x8000|'O',(a0)
1105         btst.l          #4,d6
1106         bne             0f
1107         move.w          #0x8000|'N',(a0)
1108         bra             1f
1109 0:
1110         move.w          #0x8000|'F',(a0)
1111         move.w          #0x8000|'F',(a0)
1112 1:
1113
1114         /* cursor */
1115         movea.l         #0xe000+11*2+11*64*2,a0
1116         moveq.l         #0,d0
1117         move.b          d5,d0
1118         and.b           #7,d0
1119         lsl.w           #7,d0
1120         add.w           d0,a0
1121         jsr             load_prepare
1122         move.w          #'>',(a0)
1123
1124         /* input */
1125         jsr             get_input       /* x0cbrldu x1sa00du */
1126
1127         move.w          d0,d1
1128         and.w           #3,d1
1129         beq             msm_no_ud
1130         move.b          d5,d1
1131         and.b           #7,d1
1132         btst.l          #0,d0
1133         sne             d2
1134         or.b            #1,d2           /* up -1, down 1 */
1135         add.b           d2,d1
1136         cmp.b           #0,d1
1137         bge             0f
1138         move.b          #4,d1
1139 0:
1140         cmp.b           #4,d1
1141         ble             0f
1142         move.b          #0,d1
1143 0:
1144         and.b           #0xf8,d5
1145         or.b            d1,d5
1146         bra             vbl_end
1147
1148 msm_no_ud:
1149         btst.l          #4,d0           /* A - confirm */
1150         beq             msm_no_a
1151         move.b          d5,d1
1152         and.b           #7,d1
1153         bne             0f
1154         change_mode     MMODE_GOTO, MMODE_MAIN
1155         bsr             start_menu_box
1156         bra             vbl_end
1157 0:
1158         cmp.b           #1,d1
1159         bne             0f
1160         moveq.l         #0,d5
1161         change_mode     MMODE_GOTO_PREDEF, MMODE_MAIN
1162         bsr             start_menu_box
1163         bra             vbl_end
1164 0:
1165         cmp.b           #2,d1
1166         bne             0f
1167         change_mode     MMODE_JMP_ADDR, MMODE_MAIN
1168         bsr             start_menu_box
1169         bra             vbl_end
1170 0:
1171         cmp.b           #3,d1
1172         bne             0f
1173         change_mode     MMODE_PC, MMODE_MAIN
1174         bsr             start_menu_box
1175         bra             vbl_end
1176 0:
1177         cmp.b           #4,d1
1178         bne             0f
1179         bchg.l          #4,d6
1180         bra             vbl_end
1181 0:
1182
1183 msm_no_a:
1184         move.w          d0,d1
1185         and.w           #0x3000,d1
1186         beq             msm_no_bc
1187         bra             return_to_main
1188
1189 msm_no_bc:
1190         bra             vbl_end
1191
1192 start_menu_box:
1193         movea.l         #0xe000+10*2+8*64*2,a1
1194         move.w          #11-1,d1
1195 0:
1196         move.w          a1,a0
1197         jsr             load_prepare
1198         move.w          #20-1,d0
1199 1:
1200         move.w          #0,(a0)
1201         dbra            d0,1b
1202
1203         add.w           #64*2,a1
1204         dbra            d1,0b
1205         rts
1206
1207 ################### goto predef ##################
1208
1209 mode_goto_predef:
1210         /* frame */
1211         movea.l         #0xe000+14*2+8*64*2,a1
1212         move.l          #predef_addr_cnt+2-1,d1
1213 0:
1214         move.w          a1,a0
1215         jsr             load_prepare
1216         moveq.l         #10-1,d0
1217 1:
1218         move.w          #0,(a0)
1219         dbra            d0,1b
1220
1221         add.w           #64*2,a1
1222         dbra            d1,0b
1223
1224         /* draw addresses */
1225         movea.l         #0xe000+17*2+9*64*2,a1
1226         lea             (predef_addrs,pc),a2
1227         move.w          #predef_addr_cnt-1,d4
1228         move.l          #0x8006,d3
1229 mgp_da_loop:
1230         move.w          a1,a0
1231         jsr             load_prepare
1232         move.l          (a2)+,d2
1233         jsr             print_hex_preped
1234         add.w           #64*2,a1
1235         dbra            d4,mgp_da_loop
1236
1237         /* cursor */
1238         movea.l         #0xe000+15*2+9*64*2,a0
1239         moveq.l         #0,d0
1240         move.b          d5,d0
1241         lsl.w           #7,d0
1242         add.w           d0,a0
1243         jsr             load_prepare
1244         move.w          #'>',(a0)
1245
1246         /* input */
1247         jsr             get_input       /* x0cbrldu x1sa00du */
1248
1249         move.w          d0,d1
1250         and.w           #3,d1
1251         beq             mgp_no_ud
1252         btst.l          #0,d0
1253         sne             d2
1254         or.b            #1,d2           /* up -1, down 1 */
1255         add.b           d2,d5
1256         cmp.b           #0,d5
1257         bge             0f
1258         move.b          #predef_addr_cnt-1,d5
1259 0:
1260         cmp.b           #predef_addr_cnt-1,d5
1261         ble             0f
1262         move.b          #0,d5
1263 0:
1264         bra             vbl_end
1265
1266 mgp_no_ud:
1267         btst.l          #4,d0           /* A - confirm */
1268         beq             mgp_no_a
1269         moveq.l         #0,d0
1270         move.b          d5,d0
1271         lsl.w           #2,d0
1272         lea             (predef_addrs,pc),a0
1273         move.l          (a0,d0),d5
1274         lsl.l           #8,d5
1275         bra             mode_goto_finish
1276
1277 mgp_no_a:
1278         move.w          d0,d1
1279         and.w           #0x3000,d1
1280         beq             mgp_no_bc
1281         bra             return_to_main
1282
1283 mgp_no_bc:
1284         bra             vbl_end
1285
1286 ##################### jmp ########################
1287
1288 mode_jmp_addr:
1289         btst.l          #7,d6
1290         bne             mode_jmp_finish
1291
1292         moveq.l         #0,d5
1293         or.b            #3,d5           /* 3 bytes */
1294         bclr.l          #7,d6
1295         change_mode     MMODE_VAL_INPUT, MMODE_JMP_ADDR
1296         bra             vbl_end
1297
1298 mode_jmp_finish:
1299         lsr.l           #8,d5
1300         write_vdp_r_dst 1,(VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)       /* disable vint */
1301         move.l          d5,a0
1302         jmp             (a0)
1303
1304 mode_transfer:
1305         move.b          #0x40,(0xa1000b).l      /* port 2 ctrl */
1306         move.b          #0x00,(0xa10005).l      /* port 2 data - start with TH low */
1307
1308         lea             (txt_transfer_ready,pc),a0
1309         move.l          #13,d0
1310         move.l          #13,d1
1311         move.l          #0x8000,d2
1312         jsr             print
1313
1314 wait_tl_low0:
1315         move.b          (0xa10005),d0
1316         btst.b          #4,d0
1317         bne             wait_tl_low0
1318
1319         menu_text       txt_working, 13, 13, 0
1320         bra             do_transfer
1321
1322 # go back to main mode
1323 return_to_main:
1324         bclr.l          #7,d6           /* not edited */
1325         change_mode     MMODE_MAIN, MMODE_MAIN
1326         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320),(GFXCNTL)
1327         bra             vbl_end
1328
1329
1330 #################################################
1331 #                                               #
1332 #         Initialize VDP registers              #
1333 #                                               #
1334 #################################################
1335
1336 init_gfx:
1337         move.l          #GFXCNTL,a3
1338         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
1339         write_vdp_reg   1,(VDP1_E_DISPLAY | VDP1_MODE5)
1340         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
1341         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
1342         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
1343         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
1344         write_vdp_reg   6,0     
1345         write_vdp_reg   7,0                     /* Backdrop color */
1346         write_vdp_reg   0x0a,1                  /* Lines per hblank interrupt */
1347         write_vdp_reg   0x0b,0                  /* 2-cell vertical scrolling */
1348         write_vdp_reg   0x0c,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
1349         write_vdp_reg   0x0d,(0x8000 >> 10)     /* Horizontal scroll address */
1350         write_vdp_reg   0x0e,0
1351         write_vdp_reg   0x0f,2
1352         write_vdp_reg   0x10,(VDP16_MAP_V32 | VDP16_MAP_H64)    /* layer size */
1353         write_vdp_reg   0x11,0
1354         write_vdp_reg   0x12,0
1355         rts
1356
1357
1358 # get mask of bits representing safe words
1359 #  a1 - address to check
1360 #  destroys d0-d2, strips upper bits from a1
1361 get_safety_mask:
1362         move.l          a1,d1
1363         lsl.l           #8,d1
1364         lsr.l           #8,d1
1365         lea             (safe_addrs,pc),a1
1366         move.w          #(safe_addrs_end - safe_addrs)/8-1,d2
1367 0:
1368         move.l          (a1)+,d0
1369         cmp.l           d0,d1
1370         blt             1f
1371         move.l          (a1),d0
1372         cmp.l           d0,d1
1373         ble             addr_safe
1374 1:
1375         addq.l          #4,a1
1376         dbra            d2,0b
1377
1378         move.l          d1,a1
1379
1380         moveq.l         #0x0c,d0
1381         cmp.l           #0xa14000,d1
1382         beq             gsm_rts
1383
1384         moveq.l         #0x08,d0
1385         cmp.l           #0xa14100,d1
1386         beq             gsm_rts
1387
1388         /* check for VDP address */
1389         move.l          d1,d0
1390         swap            d0
1391         and.b           #0xe0,d0
1392         cmp.b           #0xc0,d0
1393         bne             addr_unsafe     /* not vdp */
1394
1395         move.l          d1,d0
1396         and.l           #0x0700e0,d0
1397         bne             addr_unsafe
1398
1399         move.l          d1,d0
1400         and.b           #0x1f,d0
1401         cmp.b           #0x04,d0
1402         blt             addr_hsafe_3    /* data port */
1403         cmp.b           #0x10,d0
1404         blt             addr_safe       /* below PSG */
1405         cmp.b           #0x18,d0
1406         bge             addr_safe       /* above PSG */
1407
1408 addr_unsafe:
1409         moveq.l         #0,d0           /* skip line */
1410         rts
1411
1412 addr_hsafe_3:
1413         moveq.l         #3,d0           /* skip 2 words */
1414         rts
1415
1416 addr_safe:
1417         move.l          d1,a1
1418         moveq.l         #0xf,d0
1419 gsm_rts:
1420         rts
1421
1422
1423 # read single phase from controller
1424 #  #a0 - addr
1425 #  d0 - result
1426 #  destroys d1,d2
1427 get_input:
1428         move.b          #0x40,(0xa10003)
1429         nop
1430         nop
1431         nop
1432         move.b          (0xa10003),d0
1433         move.b          #0x00,(0xa10003)
1434         lsl.w           #8,d0
1435         nop
1436         move.b          (0xa10003),d0
1437         eor.w           #0xffff,d0
1438
1439         swap            d7
1440         move.w          d7,d1
1441         eor.w           d0,d1           /* changed btns */
1442         move.w          d0,d7           /* old val */
1443         swap            d7
1444         and.w           d0,d1           /* what changed now */
1445         bne             0f
1446
1447         addq.b          #1,d6
1448         move.b          d6,d2
1449         and.b           #0x0f,d2        /* do autorepeat */
1450         cmp.b           #9,d2
1451         bne             1f
1452         move.w          d0,d1
1453 0:
1454         and.b           #0xf0,d6
1455 1:
1456         swap            d0
1457         move.w          d1,d0
1458         rts
1459
1460 # Prepare to write to VDP RAM @a0
1461 # sets a0 to VDP data port for convenience
1462 #  a0: VRAM base
1463 #  destroys d0
1464
1465 load_prepare:
1466         VRAM_ADDR_var   a0
1467         move.l          d0,(GFXCNTL).l
1468         move.l          #GFXDATA,a0
1469         rts
1470
1471
1472 # Load color data from ROM
1473 #  a0: CRAM base
1474 #  a1: color list address
1475 #  d0: number of colors to load
1476 #  destroys d1
1477
1478 load_colors:
1479         move.l          d0,d1
1480         CRAM_ADDR_var   a0
1481         move.l          d0,(GFXCNTL).l
1482
1483         move.l          #GFXDATA,a0
1484         subq.w          #1,d1
1485 0:
1486         move.w          (a1)+,(a0)
1487         dbra            d1,0b
1488
1489         rts
1490
1491
1492 # print
1493 #  a0 - string
1494 #  d0 - x
1495 #  d1 - y 
1496 #  d2 - tile_bits[15:11]
1497 #  destroys a1
1498
1499 print:
1500         move.l          a0,a1
1501         XY2NT
1502         jsr             load_prepare
1503         move.l          d2,d0
1504         and.w           #0xf800,d0
1505
1506 _print_loop:
1507         move.b          (a1)+,d0
1508         beq             _print_end
1509
1510         move.w          d0,(a0)
1511         bra             _print_loop
1512
1513 _print_end:
1514         rts
1515
1516
1517 # print_hex
1518 #  d0 - x
1519 #  d1 - y 
1520 #  d2 - value
1521 #  d3 - tile_bits[15:11]|digit_cnt[7:0]
1522 #  destroys a0, preserves d3
1523
1524 print_hex:
1525         XY2NT
1526         jsr             load_prepare
1527
1528 print_hex_preped:
1529         moveq.l         #0,d0
1530         move.b          d3,d0
1531         move.l          d0,d1
1532         lsl.b           #2,d0
1533         ror.l           d0,d2           /* prep value */
1534         subq.l          #1,d1           /* count */
1535         move.w          d3,d0
1536         and.w           #0xf800,d0      /* keep upper bits in d0 */
1537
1538 _print_hex_loop:
1539         rol.l           #4,d2
1540         move.b          d2,d0
1541         and.b           #0xf,d0
1542
1543         add.b           #'0',d0
1544         cmp.b           #'9',d0
1545         ble             0f
1546         addq.b          #7,d0
1547 0:
1548         move.w          d0,(a0)
1549         dbra            d1,_print_hex_loop
1550
1551         rts
1552
1553
1554 # wait vertical sync interrupt
1555
1556 wait_vsync:
1557         move.b          d7,d0
1558 _wait_change:
1559         stop            #0x2000
1560         cmp.b           d7,d0
1561         beq             _wait_change
1562         rts
1563
1564
1565 # wait vsync start (polling)
1566 #  destroys a0,d0
1567
1568 wait_vsync_poll:
1569         move.l          #GFXCNTL,a0
1570 0:
1571         move.w          (a0),d0
1572         and.b           #8,d0
1573         nop
1574         nop
1575         bne             0b
1576 0:
1577         move.w          (a0),d0
1578         and.b           #8,d0
1579         nop
1580         nop
1581         beq             0b
1582         rts
1583
1584
1585 test_code:
1586         nop
1587
1588 test_code_ret_op:
1589         jmp     0x123456        /* will be patched */
1590 test_code_end:
1591
1592 #################################################
1593 #                                               #
1594 #                 RAM DATA                      #
1595 #                                               #
1596 #################################################
1597
1598 .bss
1599
1600 # nothing :)
1601
1602 .end
1603
1604 # vim:filetype=asmM68k