99d1c084e39c9e66d3e453546c15246a453d3198
[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         /* make sure irqs are masked */
266         move.w          #0x2700,sr
267         /* take care of TMSS */
268         move.b          (0xa10000).l,d0
269         andi.b          #0x0f,d0
270         beq             no_tmss
271         move.l          #0x53454741,(0xa14000).l
272         /* want cart, not OS rom if cart pops in */
273         move.w          #1,(0xa14100).l
274         /* touch VDP after TMSS setup? */
275         tst.w           (0xc00004).l
276 no_tmss:
277
278         /* want to do early PC transfer (with RAM/VRAM intact and such)?
279          * also give time PC to see start condition */
280         move.l          #0x2000,d0
281 0:      dbra            d0,0b
282
283         move.l          #0xa10005,a0
284         btst.b          #5,(a0)
285         bne             no_early_transfer
286 move.b #1,(0)
287         move.b          #0x40,(0xa1000b).l      /* port 2 ctrl */
288         move.b          #0x00,(a0)              /* port 2 data - start with TH low */
289         move.l          #0x2000,d0
290 0:
291         btst.b          #4,(a0)
292         beq             do_early_transfer
293         dbra            d0,0b
294
295 move.b #2,(0)
296         move.b          #0,(0xa1000b).l
297         bra             no_early_transfer       /* timeout */
298
299 do_early_transfer:
300 move.b #9,(0)
301         bsr             do_transfer
302
303 no_early_transfer:
304
305 .if COPY_TO_EXP
306         /* copy to expansion device if magic number is set */
307         move.l          #0x400000,a1
308         cmp.w           #0x1234,(a1)
309         bne             0f
310
311         move.l          #0,a0
312         move.l          (sizeof_bin,pc),d0
313         lsr.l           #3,d0
314 1:
315         move.l          (a0)+,(a1)+
316         move.l          (a0)+,(a1)+
317         dbra            d0,1b
318 0:
319 .endif
320
321 .if RELOCATE_TO_RAM
322         /* we could be relocated by 32x or something else, adjust start addr */
323         lea             (pc),a0
324         move.l          a0,d0
325         and.l           #0xff0000,d0
326         move.l          d0,a0
327
328         /* copy, assume 8K size */
329         move.l          #0xFF0100,a1
330         move.l          (sizeof_bin,pc),d0
331         lsr.l           #3,d0
332 1:
333         move.l          (a0)+,(a1)+
334         move.l          (a0)+,(a1)+
335         dbra            d0,1b
336
337         /* copy test code */
338         lea             (test_code,pc),a0
339         move.l          #0xffc000,a1
340         move.w          #(test_code_end - test_code)/2-1,d0
341 1:
342         move.w          (a0)+,(a1)+
343         dbra            d0,1b
344
345         lea             (0f,pc),a0
346         move.l          a0,d0
347         and.l           #0x00ffff,d0
348         add.l           #0xFF0100,d0
349         move.l          d0,a0
350
351         /* patch test code */
352         move.l          #0xffc000,a1
353         add.w           #(test_code_ret_op-test_code+2),a1
354         move.l          a0,(a1)
355
356         jmp             (a0)
357 0:
358 .endif
359
360         movea.l         #0,a6
361         move.l          #0x8000,d7
362         moveq.l         #0,d6
363
364         /* Init pads */
365         move.b          #0x40,(0xa10009).l
366         move.b          #0x40,(0xa10003).l
367
368         /* Initialize VDP */
369         jsr             init_gfx
370
371         /* Clear h/v scroll */
372         movea.l         #GFXDATA,a0
373         VRAM_ADDR       0x8000,(GFXCNTL)
374         move.l          #0,(a0)
375         VSRAM_ADDR      0,(GFXCNTL)
376         move.l          #0,(a0)
377
378         /* Load color data */
379         movea.l         #0,a0
380         lea             (colors,pc),a1
381         moveq.l         #(colors_end-colors)/2,d0
382         jsr             load_colors
383
384         /* load font patterns */
385         movea.l         #GFXDATA,a0
386         lea             (font,pc),a1
387         VRAM_ADDR       0,(GFXCNTL)
388         move.w          #128*8,d3
389 font_loop:
390         moveq.l         #8-1,d2
391         moveq.l         #0,d1
392         move.b          (a1)+,d0
393 0:
394         lsr.b           #1,d0
395         roxl.l          #1,d1
396         ror.l           #5,d1
397         dbra            d2,0b
398
399         rol.l           #1,d1           /* fixup */
400         move.l          d1,(a0)
401         dbra            d3,font_loop
402
403         /* generate A layer map */
404         movea.l         #0xe000,a1
405         move.l          #28-1,d4
406 lmaploop0:
407         movea.l         a1,a0
408         jsr             load_prepare
409
410         move.l          #64/2-1,d3
411 0:      move.l          #0x00000000,(a0)
412         dbra            d3,0b
413
414         add.l           #64*2,a1
415         dbra            d4,lmaploop0
416
417         /* generate B layer map */
418         movea.l         #0xc000,a0
419         jsr             load_prepare
420
421         move.l          #64*28/2-1,d3
422 0:      move.l          #0x00000000,(a0)
423         dbra            d3,0b
424
425         /* upload sprite data */
426         movea.l         #0xfc00,a0
427         jsr             load_prepare
428         lea             (sprite_data,pc),a1
429
430         move.l          #(sprite_data_end-sprite_data)/2-1,d3
431 0:      move.l          (a1)+,(a0)
432         dbra            d3,0b
433
434 .if USE_VINT
435         /* wait for vsync before unmask */
436         jsr             wait_vsync_poll
437
438         /* wait a bit to avoid nested vint */
439         move.w          #20,d0
440 0:
441         dbra            d0,0b           /* 10 cycles to go back */
442
443         /* enable and unmask vint */
444         write_vdp_r_dst 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)
445         move.w          #0x2000,sr
446 .endif
447
448 ##################################################
449
450 forever:
451 .if USE_VINT
452         jsr             wait_vsync
453 .else
454         jsr             wait_vsync_poll
455         jsr             VBL
456 .endif
457         bra             forever
458
459
460 INT:
461         /* let's hope VRAM is already set up.. */
462         lea             (txt_exc,pc),a0
463         move.l          #9,d0
464         move.l          #27,d1
465         move.l          #0xe000,d2
466         jsr             print
467         bra             forever
468
469 ##################################################
470
471 VBL:
472         addq.b          #1,d7
473 #       movem.l         d0-d4/a0-a5,-(a7)
474
475         btst.b          #5,(0xa10005).l
476         bne             no_auto_transfer
477         change_mode     MMODE_PC, MMODE_MAIN
478         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
479
480 no_auto_transfer:
481         moveq.l         #0,d0
482         move.w          d7,d0
483         lsr.w           #6,d0
484         and.w           #0x1c,d0
485         lea             (jumptab,pc,d0),a0
486         jmp             (a0)
487 jumptab:
488         /* branch insns here because we want to be position independent */
489         bra             mode_main
490         bra             mode_val_input
491         bra             mode_edit_val   /* edit val in editor */
492         bra             mode_goto
493         bra             mode_start_menu
494         bra             mode_goto_predef
495         bra             mode_jmp_addr
496         bra             mode_transfer
497
498 ##################### main #######################
499
500 mode_main:
501         /* assume we will hang */
502         lea             (txt_dtack_err,pc),a0
503         move.l          #9,d0
504         move.l          #27,d1
505         move.l          #0xe000,d2
506         jsr             print
507
508         moveq.l         #0,d1
509         move.l          a6,d0
510         move.b          d0,d1
511         lsr.l           #8,d0
512         move.l          d0,a1           /* current addr */
513         lsr.b           #3,d1
514         neg.b           d1
515         add.b           #27-1,d1        /* line where the cursor sits */
516         swap            d1
517
518         movea.l         #0xe002,a2
519         move.l          #27-1,d5        /* line counter for dbra */
520         or.l            d1,d5
521
522 draw_row:
523         move.l          a2,a0
524         jsr             load_prepare
525
526         btst.l          #15,d7
527         beq             0f
528         move.w          #' ',(a0)
529 0:
530         /* addr */
531         move.l          a1,d2
532         moveq.l         #6,d3
533         jsr             print_hex_preped
534
535         btst.l          #4,d6
536         bne             draw_row_safe
537
538         bsr             get_safety_mask
539         cmp.b           #0xf,d0
540         beq             draw_row_safe
541
542 # unsafe or partially safe
543 draw_row_hsafe:
544         move.l          d0,d4
545         swap            d4              /* mask in upper word */
546         btst.l          #15,d7
547         bne             draw_row_hsafe_words_pre
548
549 draw_row_hsafe_bytes_pre:
550         /* 8 bytes */
551         moveq.l         #2,d3
552         move.w          #3,d4
553
554 draw_row_hsafe_bytes:
555         move.w          #' ',(a0)
556         move.b          d4,d0
557         add.b           #16,d0
558         btst.l          d0,d4
559         bne             0f
560         move.l          #'?'|('?'<<16),(a0)
561         move.w          #' ',(a0)
562         move.l          #'?'|('?'<<16),(a0)
563         bra             1f
564 0:
565         move.b          (0,a1),d2
566         jsr             print_hex_preped
567         move.w          #' ',(a0)
568         move.b          (1,a1),d2
569         jsr             print_hex_preped
570 1:
571         addq.l          #2,a1
572         dbra            d4,draw_row_hsafe_bytes
573
574         move.w          #' ',(a0)
575
576         move.l          d5,d0
577         swap            d0
578         cmp.w           d5,d0
579         beq             draw_cursor_unsafe_byte
580         bra             draw_chars_hsafe_pre
581
582 draw_row_hsafe_words_pre:
583         /* 4 shorts */
584         moveq.l         #4,d3
585         move.w          #3,d4
586
587 draw_row_hsafe_words:
588         move.w          #' ',(a0)
589         move.b          d4,d0
590         add.b           #16,d0
591         btst.l          d0,d4
592         bne             0f
593         move.l          #'?'|('?'<<16),(a0)
594         move.l          #'?'|('?'<<16),(a0)
595         bra             1f
596 0:
597         move.w          (a1),d2
598         jsr             print_hex_preped
599 1:
600         addq.l          #2,a1
601         dbra            d4,draw_row_hsafe_words
602
603         move.l          #(' '<<16)|' ',(a0)
604
605         move.l          d5,d0
606         swap            d0
607         cmp.w           d5,d0
608         beq             draw_cursor_unsafe_word
609
610 draw_chars_hsafe_pre:
611         subq.l          #8,a1
612         move.w          #3,d4
613         moveq.l         #0,d0
614
615 draw_chars_hsafe:
616         move.b          d4,d0
617         add.b           #16,d0
618         btst.l          d0,d4
619         bne             0f
620         move.l          #'?'|('?'<<16),(a0)
621         bra             draw_chars_hsafe_next
622 0:
623         btst.l          #15,d7          /* must perform correct read type */
624         bne             0f              /* doing byte reads on security reg hangs */
625         move.b          (0,a1),d0
626         lsl.l           #8,d0
627         move.b          (1,a1),d0
628         bra             1f
629 0:
630         move.w          (a1),d0
631 1:
632         ror.l           #8,d0
633         move.b          d0,d1
634         sub.b           #0x20,d1
635         cmp.b           #0x60,d1
636         blo             0f
637         move.b          #'.',d0
638 0:
639         move.w          d0,(a0)
640
641         move.b          #0,d0
642         rol.l           #8,d0
643         move.b          d0,d1
644         sub.b           #0x20,d1
645         cmp.b           #0x60,d1
646         blo             0f
647         move.b          #'.',d0
648 0:
649         move.w          d0,(a0)
650
651 draw_chars_hsafe_next:
652         addq.l          #2,a1
653         dbra            d4,draw_chars_hsafe
654
655         move.l          #(' '<<16)|' ',(a0)
656         add.w           #0x80,a2
657         dbra            d5,draw_row
658         bra             draw_status_bar
659
660
661 # normal draw
662 draw_row_safe:
663         btst.l          #15,d7
664         bne             draw_row_words
665
666 draw_row_bytes:
667         /* 8 bytes */
668         moveq.l         #2,d3
669         moveq.l         #8-1,d4
670 draw_bytes:
671         move.w          #' ',(a0)
672         move.b          (a1)+,d2
673         jsr             print_hex_preped
674         dbra            d4,draw_bytes
675
676         move.w          #' ',(a0)
677
678         move.l          d5,d0
679         swap            d0
680         cmp.w           d5,d0
681         beq             draw_cursor_byte
682         bra             draw_chars_pre
683
684 draw_row_words:
685         /* 4 shorts */
686         moveq.l         #4,d3
687         moveq.l         #4-1,d4
688 draw_words:
689         move.w          #' ',(a0)
690         move.w          (a1)+,d2
691         jsr             print_hex_preped
692         dbra            d4,draw_words
693
694         move.l          #(' '<<16)|' ',(a0)
695
696         move.l          d5,d0
697         swap            d0
698         cmp.w           d5,d0
699         beq             draw_cursor_word
700
701 draw_chars_pre:
702         /* 8 chars */
703         subq.l          #8,a1
704         moveq.l         #8-1,d4
705 draw_chars:
706         move.b          (a1)+,d0
707         move.b          d0,d1
708         sub.b           #0x20,d1
709         cmp.b           #0x60,d1
710         blo             0f
711         move.w          #'.',d0
712 0:
713         move.w          d0,(a0)
714         dbra            d4,draw_chars
715
716         move.l          #(' '<<16)|' ',(a0)
717
718         add.w           #0x80,a2
719         dbra            d5,draw_row
720
721
722 draw_status_bar:
723         /* status bar */
724         move.l          a2,a0
725         jsr             load_prepare
726
727         btst.l          #15,d7
728         beq             0f
729         move.w          #' ',(a0)
730 0:
731         mk_a6_addr      d2
732         move.l          #0x4006,d3
733         jsr             print_hex_preped
734
735         /* clear error */
736         moveq.l         #5-1,d0
737 0:
738         move.l          #' '|(' '<<16),(a0)
739         move.l          #' '|(' '<<16),(a0)
740         dbra            d0,0b
741
742
743         /* handle input */
744         jsr             get_input               /* x0cbrldu x1sa00du */
745
746         btst.l          #16+4,d0                /* A - scroll modifier */
747         beq             input_noa
748
749         do_dpad         16+0,  sub, #0x0800
750         do_dpad         16+1,  add, #0x0800
751         do_dpad         16+10, sub, #0xd800
752         do_dpad         16+11, add, #0xd800
753 input_noa:
754         moveq.l         #0,d1
755         move.w          d7,d1
756         lsr.w           #7,d1
757         lsr.w           #7,d1
758
759         do_dpad         0,  subq, #0x0008
760         do_dpad         1,  addq, #0x0008
761         do_dpad         10, sub, d1
762         do_dpad         11, add, d1
763
764 dpad_end:
765         /* update addr */
766         move.l          a6,d1
767         cmp.b           #0xf0,d1
768         blo             0f
769         sub.l           #0xd800,a6
770         add.w           #0x00d8,a6
771         bra             1f
772 0:
773         cmp.b           #0xd8,d1
774         blo             1f
775         add.l           #0xd800,a6
776         sub.w           #0x00d8,a6
777 1:
778
779         /* other btns */
780         moveq.l         #0,d1
781         btst.l          #12,d0                  /* B - switch byte/word mode */
782         beq             input_nob
783         bclr.l          #15,d7
784         add.w           #0x4000,d7              /* changes between 01 10 */
785         move.l          a6,d1
786         and.l           #1,d1
787         sub.l           d1,a6                   /* make even, just in case */
788
789 input_nob:
790         btst.l          #13,d0                  /* C - edit selected byte */
791         beq             input_noc
792
793         change_mode     MMODE_EDIT_VAL, MMODE_MAIN
794         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
795
796 input_noc:
797         btst.l          #5,d0                   /* Start - menu */
798         beq             input_nos
799
800         moveq.l         #0,d5
801         change_mode     MMODE_START_MENU, MMODE_MAIN
802         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
803
804 input_nos:
805 vbl_end:
806 #       movem.l         (a7)+,d0-d4/a0-a5
807 .if USE_VINT
808         rte
809 .else
810         rts
811 .endif
812
813
814 draw_cursor_unsafe_byte:
815         move.l          a6,d0
816         and.l           #7,d0           /* byte offs */
817         move.b          d0,d1
818         add.b           d0,d0
819         add.b           d1,d0           /* d0 *= 3 (chars) */
820         add.b           d0,d0
821         lea             (7*2,a2,d0),a0
822         jsr             load_prepare
823         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),(a0)
824
825         move.l          a2,a0
826         add.w           #31*2,a0
827         jsr             load_prepare    /* restore a0 */
828         bra             draw_chars_hsafe_pre
829
830 draw_cursor_unsafe_word:
831         move.l          a6,d0
832         and.l           #7,d0           /* byte offs */
833         move.l          d0,d1
834         lsr.b           #1,d1           /* which word */
835         move.b          d1,d2
836         lsl.b           #2,d2
837         add.b           d2,d1           /* num of chars to skip */
838         add.b           d1,d1
839
840         lea             (8*2,a2,d1),a0
841         jsr             load_prepare
842         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),d0
843         move.l          d0,(a0)
844         move.l          d0,(a0)
845
846         move.l          a2,a0
847         add.w           #29*2,a0
848         jsr             load_prepare    /* restore a0 */
849         bra             draw_chars_hsafe_pre
850
851
852 draw_cursor_byte:
853         move.l          a6,d0
854         and.l           #7,d0           /* byte offs */
855         move.w          #0x2002,d3
856
857         move.b          (-8,a1,d0),d2
858         move.b          d0,d1
859         add.b           d0,d0
860         add.b           d1,d0           /* d0 *= 3 (chars) */
861         add.b           d0,d0
862         lea             (7*2,a2,d0),a0
863         jsr             load_prepare
864         jsr             print_hex_preped
865
866         move.l          a2,a0
867         add.w           #31*2,a0
868         jsr             load_prepare    /* restore a0 */
869
870         bra             draw_chars_pre
871
872 draw_cursor_word:
873         move.l          a6,d0
874         and.l           #7,d0           /* byte offs */
875         move.l          d0,d1
876         lsr.b           #1,d1           /* which word */
877         move.b          d1,d2
878         lsl.b           #2,d2
879         add.b           d2,d1           /* num of chars to skip */
880         add.b           d1,d1
881         move.w          #0x2004,d3
882
883         move.w          (-8,a1,d0),d2
884         lea             (8*2,a2,d1),a0
885         jsr             load_prepare
886         jsr             print_hex_preped
887
888         move.l          a2,a0
889         add.w           #29*2,a0
890         jsr             load_prepare    /* restore a0 */
891
892         bra             draw_chars_pre
893
894
895 #################### hedit #######################
896
897 mode_edit_val:
898         btst.l          #7,d6
899         bne             mode_hedit_finish
900
901         /* read val to edit */
902         moveq.l         #0,d5
903         mk_a6_addr      d1
904         move.l          d1,a0
905         btst.l          #15,d7
906         bne             0f
907         move.b          (a0),d5
908         lsl.l           #8,d5
909         or.b            #1,d5
910         bra             1f
911 0:
912         move.w          (a0),d5
913         lsl.l           #8,d5
914         or.b            #2,d5
915 1:
916
917         change_mode     MMODE_VAL_INPUT, MMODE_EDIT_VAL
918         bra             vbl_end
919
920 mode_hedit_finish:
921         /* write the val */
922         mk_a6_addr      d1
923         move.l          d1,a0
924         lsr.l           #8,d5
925
926         btst.l          #15,d7
927         bne             0f
928         move.b          d5,(a0)
929         bra             1f
930 0:
931         move.w          d5,(a0)
932 1:
933
934         bra             return_to_main
935
936 ##################### goto #######################
937
938 mode_goto:
939         btst.l          #7,d6
940         bne             mode_goto_finish
941
942         moveq.l         #0,d5
943         swap            d6
944         move.w          d6,d5
945         swap            d6
946         swap            d5
947         or.b            #3,d5           /* 3 bytes */
948         bclr.l          #7,d6
949         change_mode     MMODE_VAL_INPUT, MMODE_GOTO
950         bra             vbl_end
951
952 mode_goto_finish:
953         lsr.l           #8,d5
954         move.l          d5,d0
955         move.l          d0,d1
956         and.l           #7,d1
957         and.b           #0xf8,d0
958         lsl.l           #8,d0
959         or.l            d1,d0
960         move.l          d0,a6
961
962         lsr.l           #8,d5
963         swap            d6
964         move.w          d5,d6
965         swap            d6
966
967         bra             return_to_main
968
969 ################### val edit #####################
970
971 mode_val_input:
972         /* frame */
973         movea.l         #0xe000+14*2+11*64*2,a1
974         moveq.l         #6-1,d1
975 0:
976         move.w          a1,a0
977         jsr             load_prepare
978         moveq.l         #11-1,d0
979 1:
980         move.w          #0,(a0)
981         dbra            d0,1b
982
983         add.w           #64*2,a1
984         dbra            d1,0b
985
986         /* text */
987         lea             (txt_edit,pc),a0
988         move.l          #15,d0
989         move.l          #11,d1
990         move.l          #0xc000,d2
991         jsr             print
992
993         lea             (txt_a_confirm,pc),a0
994         move.l          #15,d0
995         move.l          #15,d1
996         move.l          #0xc000,d2
997         jsr             print
998
999         /* edit field */
1000         moveq.l         #0,d0
1001         moveq.l         #0,d1
1002         moveq.l         #0,d3
1003         move.b          d5,d3
1004         and.b           #3,d3           /* edit field bytes */
1005
1006         move.b          #19,d0
1007         sub.b           d3,d0
1008         move.b          #13,d1
1009         move.l          d5,d2
1010         lsr.l           #8,d2
1011         add.b           d3,d3
1012         or.w            #0x8000,d3
1013         jsr             print_hex
1014
1015         /* current char */
1016         moveq.l         #0,d0
1017         moveq.l         #0,d1
1018
1019         and.w           #6,d3
1020         move.b          #19,d0
1021         move.b          d3,d1
1022         lsr.b           #1,d1           /* length in bytes */
1023         sub.b           d1,d0
1024         move.b          d5,d1
1025         lsr.b           #2,d1
1026         and.b           #7,d1           /* nibble to edit */
1027         add.b           d1,d0
1028
1029         sub.b           d1,d3
1030         sub.b           #1,d3           /* chars to shift out */
1031         lsl.b           #2,d3
1032         add.b           #8,d3
1033         move.l          d5,d2
1034         lsr.l           d3,d2
1035
1036         move.b          #13,d1
1037         move.w          #0xa001,d3
1038         jsr             print_hex
1039
1040         /* handle input */
1041         jsr             get_input       /* x0cbrldu x1sa00du */
1042
1043         move.w          d0,d1
1044         and.w           #0x0f00,d1
1045         beq             ai_no_dpad
1046         move.b          d5,d1
1047         and.b           #3,d1
1048         add.b           d1,d1           /* nibble count */
1049         sub.b           #1,d1           /* max n.t.e. val */
1050         move.b          d5,d2
1051         lsr.b           #2,d2
1052         and.b           #7,d2           /* nibble to edit */
1053
1054         move.b          d0,d3
1055         and.b           #3,d3
1056         beq             ai_no_ud
1057         moveq.l         #0,d3
1058         moveq.l         #0,d4
1059         move.b          #0xf,d3
1060         move.b          #0x1,d4
1061         sub.b           d2,d1
1062         lsl.b           #2,d1
1063         add.b           #8,d1
1064         lsl.l           d1,d3           /* mask */
1065         lsl.l           d1,d4           /* what to add/sub */
1066         move.l          d5,d1
1067         and.l           d3,d1
1068         btst.l          #8,d0
1069         beq             0f
1070         add.l           d4,d1
1071         bra             1f
1072 0:
1073         sub.l           d4,d1
1074 1:
1075         and.l           d3,d1
1076         eor.l           #0xffffffff,d3
1077         and.l           d3,d5
1078         or.l            d1,d5
1079         bra             vbl_end
1080
1081 ai_no_ud:
1082         btst.l          #10,d0
1083         bne             0f
1084         add.b           #1,d2
1085         bra             1f
1086 0:
1087         sub.b           #1,d2
1088 1:
1089         cmp.b           #0,d2
1090         bge             0f
1091         move.b          d1,d2
1092 0:
1093         cmp.b           d1,d2
1094         ble             0f
1095         move.b          #0,d2
1096 0:
1097         and.b           #0xe3,d5
1098         lsl.b           #2,d2
1099         or.b            d2,d5
1100         bra             vbl_end
1101
1102 ai_no_dpad:
1103         move.w          d0,d1
1104         and.w           #0x1020,d1
1105         beq             ai_no_sb
1106
1107         bra             return_to_main
1108
1109 ai_no_sb:
1110         btst.l          #4,d0           /* A - confirm */
1111         beq             ai_no_input
1112         bset.l          #7,d6
1113         move.w          d7,d1           /* back to prev mode */
1114         and.w           #0x3800,d1
1115         lsr.w           #3,d1
1116         and.w           #0xc0ff,d7
1117         or.w            d1,d7
1118
1119 ai_no_input:
1120         bra             vbl_end
1121
1122
1123 ################### start menu ###################
1124
1125 mode_start_menu:
1126         /* frame */
1127         bsr             start_menu_box
1128
1129         /* text */
1130         menu_text       txt_about,       13,  9, 1
1131         menu_text       txt_goto,        13, 11, 0
1132         menu_text       txt_goto_predef, 13, 12, 0
1133         menu_text       txt_jmp_addr,    13, 13, 0
1134         menu_text       txt_dump,        13, 14, 0
1135         menu_text       txt_dtack,       13, 15, 0
1136         menu_text       txt_a_confirm,   13, 17, 2
1137
1138         /* dtack safety on/off */
1139         movea.l         #0xe000+26*2+15*64*2,a0
1140         jsr             load_prepare
1141         move.w          #0x8000|'O',(a0)
1142         btst.l          #4,d6
1143         bne             0f
1144         move.w          #0x8000|'N',(a0)
1145         bra             1f
1146 0:
1147         move.w          #0x8000|'F',(a0)
1148         move.w          #0x8000|'F',(a0)
1149 1:
1150
1151         /* cursor */
1152         movea.l         #0xe000+11*2+11*64*2,a0
1153         moveq.l         #0,d0
1154         move.b          d5,d0
1155         and.b           #7,d0
1156         lsl.w           #7,d0
1157         add.w           d0,a0
1158         jsr             load_prepare
1159         move.w          #'>',(a0)
1160
1161         /* input */
1162         jsr             get_input       /* x0cbrldu x1sa00du */
1163
1164         move.w          d0,d1
1165         and.w           #3,d1
1166         beq             msm_no_ud
1167         move.b          d5,d1
1168         and.b           #7,d1
1169         btst.l          #0,d0
1170         sne             d2
1171         or.b            #1,d2           /* up -1, down 1 */
1172         add.b           d2,d1
1173         cmp.b           #0,d1
1174         bge             0f
1175         move.b          #4,d1
1176 0:
1177         cmp.b           #4,d1
1178         ble             0f
1179         move.b          #0,d1
1180 0:
1181         and.b           #0xf8,d5
1182         or.b            d1,d5
1183         bra             vbl_end
1184
1185 msm_no_ud:
1186         btst.l          #4,d0           /* A - confirm */
1187         beq             msm_no_a
1188         move.b          d5,d1
1189         and.b           #7,d1
1190         bne             0f
1191         change_mode     MMODE_GOTO, MMODE_MAIN
1192         bsr             start_menu_box
1193         bra             vbl_end
1194 0:
1195         cmp.b           #1,d1
1196         bne             0f
1197         moveq.l         #0,d5
1198         change_mode     MMODE_GOTO_PREDEF, MMODE_MAIN
1199         bsr             start_menu_box
1200         bra             vbl_end
1201 0:
1202         cmp.b           #2,d1
1203         bne             0f
1204         change_mode     MMODE_JMP_ADDR, MMODE_MAIN
1205         bsr             start_menu_box
1206         bra             vbl_end
1207 0:
1208         cmp.b           #3,d1
1209         bne             0f
1210         change_mode     MMODE_PC, MMODE_MAIN
1211         bsr             start_menu_box
1212         bra             vbl_end
1213 0:
1214         cmp.b           #4,d1
1215         bne             0f
1216         bchg.l          #4,d6
1217         bra             vbl_end
1218 0:
1219
1220 msm_no_a:
1221         move.w          d0,d1
1222         and.w           #0x3000,d1
1223         beq             msm_no_bc
1224         bra             return_to_main
1225
1226 msm_no_bc:
1227         bra             vbl_end
1228
1229 start_menu_box:
1230         movea.l         #0xe000+10*2+8*64*2,a1
1231         move.w          #11-1,d1
1232 0:
1233         move.w          a1,a0
1234         jsr             load_prepare
1235         move.w          #20-1,d0
1236 1:
1237         move.w          #0,(a0)
1238         dbra            d0,1b
1239
1240         add.w           #64*2,a1
1241         dbra            d1,0b
1242         rts
1243
1244 ################### goto predef ##################
1245
1246 mode_goto_predef:
1247         /* frame */
1248         movea.l         #0xe000+14*2+8*64*2,a1
1249         move.l          #predef_addr_cnt+2-1,d1
1250 0:
1251         move.w          a1,a0
1252         jsr             load_prepare
1253         moveq.l         #10-1,d0
1254 1:
1255         move.w          #0,(a0)
1256         dbra            d0,1b
1257
1258         add.w           #64*2,a1
1259         dbra            d1,0b
1260
1261         /* draw addresses */
1262         movea.l         #0xe000+17*2+9*64*2,a1
1263         lea             (predef_addrs,pc),a2
1264         move.w          #predef_addr_cnt-1,d4
1265         move.l          #0x8006,d3
1266 mgp_da_loop:
1267         move.w          a1,a0
1268         jsr             load_prepare
1269         move.l          (a2)+,d2
1270         jsr             print_hex_preped
1271         add.w           #64*2,a1
1272         dbra            d4,mgp_da_loop
1273
1274         /* cursor */
1275         movea.l         #0xe000+15*2+9*64*2,a0
1276         moveq.l         #0,d0
1277         move.b          d5,d0
1278         lsl.w           #7,d0
1279         add.w           d0,a0
1280         jsr             load_prepare
1281         move.w          #'>',(a0)
1282
1283         /* input */
1284         jsr             get_input       /* x0cbrldu x1sa00du */
1285
1286         move.w          d0,d1
1287         and.w           #3,d1
1288         beq             mgp_no_ud
1289         btst.l          #0,d0
1290         sne             d2
1291         or.b            #1,d2           /* up -1, down 1 */
1292         add.b           d2,d5
1293         cmp.b           #0,d5
1294         bge             0f
1295         move.b          #predef_addr_cnt-1,d5
1296 0:
1297         cmp.b           #predef_addr_cnt-1,d5
1298         ble             0f
1299         move.b          #0,d5
1300 0:
1301         bra             vbl_end
1302
1303 mgp_no_ud:
1304         btst.l          #4,d0           /* A - confirm */
1305         beq             mgp_no_a
1306         moveq.l         #0,d0
1307         move.b          d5,d0
1308         lsl.w           #2,d0
1309         lea             (predef_addrs,pc),a0
1310         move.l          (a0,d0),d5
1311         lsl.l           #8,d5
1312         bra             mode_goto_finish
1313
1314 mgp_no_a:
1315         move.w          d0,d1
1316         and.w           #0x3000,d1
1317         beq             mgp_no_bc
1318         bra             return_to_main
1319
1320 mgp_no_bc:
1321         bra             vbl_end
1322
1323 ##################### jmp ########################
1324
1325 mode_jmp_addr:
1326         btst.l          #7,d6
1327         bne             mode_jmp_finish
1328
1329         moveq.l         #0,d5
1330         or.b            #3,d5           /* 3 bytes */
1331         bclr.l          #7,d6
1332         change_mode     MMODE_VAL_INPUT, MMODE_JMP_ADDR
1333         bra             vbl_end
1334
1335 mode_jmp_finish:
1336         lsr.l           #8,d5
1337         write_vdp_r_dst 1,(VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)       /* disable vint */
1338         move.l          d5,a0
1339         jmp             (a0)
1340
1341 mode_transfer:
1342         move.b          #0x40,(0xa1000b).l      /* port 2 ctrl */
1343         move.b          #0x00,(0xa10005).l      /* port 2 data - start with TH low */
1344
1345         lea             (txt_transfer_ready,pc),a0
1346         move.l          #13,d0
1347         move.l          #13,d1
1348         move.l          #0x8000,d2
1349         jsr             print
1350
1351 wait_tl_low0:
1352         move.b          (0xa10005),d0
1353         btst.b          #4,d0
1354         bne             wait_tl_low0
1355
1356         menu_text       txt_working, 13, 13, 0
1357         bsr             do_transfer
1358         bra             return_to_main
1359
1360 # go back to main mode
1361 return_to_main:
1362         bclr.l          #7,d6           /* not edited */
1363         change_mode     MMODE_MAIN, MMODE_MAIN
1364         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320),(GFXCNTL)
1365         bra             vbl_end
1366
1367
1368 #################################################
1369 #                                               #
1370 #         Initialize VDP registers              #
1371 #                                               #
1372 #################################################
1373
1374 init_gfx:
1375         move.l          #GFXCNTL,a3
1376         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
1377         write_vdp_reg   1,(VDP1_E_DISPLAY | VDP1_MODE5)
1378         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
1379         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
1380         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
1381         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
1382         write_vdp_reg   6,0     
1383         write_vdp_reg   7,0                     /* Backdrop color */
1384         write_vdp_reg   0x0a,1                  /* Lines per hblank interrupt */
1385         write_vdp_reg   0x0b,0                  /* 2-cell vertical scrolling */
1386         write_vdp_reg   0x0c,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
1387         write_vdp_reg   0x0d,(0x8000 >> 10)     /* Horizontal scroll address */
1388         write_vdp_reg   0x0e,0
1389         write_vdp_reg   0x0f,2
1390         write_vdp_reg   0x10,(VDP16_MAP_V32 | VDP16_MAP_H64)    /* layer size */
1391         write_vdp_reg   0x11,0
1392         write_vdp_reg   0x12,0
1393         rts
1394
1395
1396 # get mask of bits representing safe words
1397 #  a1 - address to check
1398 #  destroys d0-d2, strips upper bits from a1
1399 get_safety_mask:
1400         move.l          a1,d1
1401         lsl.l           #8,d1
1402         lsr.l           #8,d1
1403         lea             (safe_addrs,pc),a1
1404         move.w          #(safe_addrs_end - safe_addrs)/8-1,d2
1405 0:
1406         move.l          (a1)+,d0
1407         cmp.l           d0,d1
1408         blt             1f
1409         move.l          (a1),d0
1410         cmp.l           d0,d1
1411         ble             addr_safe
1412 1:
1413         addq.l          #4,a1
1414         dbra            d2,0b
1415
1416         move.l          d1,a1
1417
1418         moveq.l         #0x0c,d0
1419         cmp.l           #0xa14000,d1
1420         beq             gsm_rts
1421
1422         moveq.l         #0x08,d0
1423         cmp.l           #0xa14100,d1
1424         beq             gsm_rts
1425
1426         /* check for VDP address */
1427         move.l          d1,d0
1428         swap            d0
1429         and.b           #0xe0,d0
1430         cmp.b           #0xc0,d0
1431         bne             addr_unsafe     /* not vdp */
1432
1433         move.l          d1,d0
1434         and.l           #0x0700e0,d0
1435         bne             addr_unsafe
1436
1437         move.l          d1,d0
1438         and.b           #0x1f,d0
1439         cmp.b           #0x04,d0
1440         blt             addr_hsafe_3    /* data port */
1441         cmp.b           #0x10,d0
1442         blt             addr_safe       /* below PSG */
1443         cmp.b           #0x18,d0
1444         bge             addr_safe       /* above PSG */
1445
1446 addr_unsafe:
1447         moveq.l         #0,d0           /* skip line */
1448         rts
1449
1450 addr_hsafe_3:
1451         moveq.l         #3,d0           /* skip 2 words */
1452         rts
1453
1454 addr_safe:
1455         move.l          d1,a1
1456         moveq.l         #0xf,d0
1457 gsm_rts:
1458         rts
1459
1460
1461 # read single phase from controller
1462 #  #a0 - addr
1463 #  d0 - result
1464 #  destroys d1,d2
1465 get_input:
1466         move.b          #0x40,(0xa10003)
1467         nop
1468         nop
1469         nop
1470         move.b          (0xa10003),d0
1471         move.b          #0x00,(0xa10003)
1472         lsl.w           #8,d0
1473         nop
1474         move.b          (0xa10003),d0
1475         eor.w           #0xffff,d0
1476
1477         swap            d7
1478         move.w          d7,d1
1479         eor.w           d0,d1           /* changed btns */
1480         move.w          d0,d7           /* old val */
1481         swap            d7
1482         and.w           d0,d1           /* what changed now */
1483         bne             0f
1484
1485         addq.b          #1,d6
1486         move.b          d6,d2
1487         and.b           #0x0f,d2        /* do autorepeat */
1488         cmp.b           #9,d2
1489         bne             1f
1490         move.w          d0,d1
1491 0:
1492         and.b           #0xf0,d6
1493 1:
1494         swap            d0
1495         move.w          d1,d0
1496         rts
1497
1498 # Prepare to write to VDP RAM @a0
1499 # sets a0 to VDP data port for convenience
1500 #  a0: VRAM base
1501 #  destroys d0
1502
1503 load_prepare:
1504         VRAM_ADDR_var   a0
1505         move.l          d0,(GFXCNTL).l
1506         move.l          #GFXDATA,a0
1507         rts
1508
1509
1510 # Load color data from ROM
1511 #  a0: CRAM base
1512 #  a1: color list address
1513 #  d0: number of colors to load
1514 #  destroys d1
1515
1516 load_colors:
1517         move.l          d0,d1
1518         CRAM_ADDR_var   a0
1519         move.l          d0,(GFXCNTL).l
1520
1521         move.l          #GFXDATA,a0
1522         subq.w          #1,d1
1523 0:
1524         move.w          (a1)+,(a0)
1525         dbra            d1,0b
1526
1527         rts
1528
1529
1530 # print
1531 #  a0 - string
1532 #  d0 - x
1533 #  d1 - y 
1534 #  d2 - tile_bits[15:11]
1535 #  destroys a1
1536
1537 print:
1538         move.l          a0,a1
1539         XY2NT
1540         jsr             load_prepare
1541         move.l          d2,d0
1542         and.w           #0xf800,d0
1543
1544 _print_loop:
1545         move.b          (a1)+,d0
1546         beq             _print_end
1547
1548         move.w          d0,(a0)
1549         bra             _print_loop
1550
1551 _print_end:
1552         rts
1553
1554
1555 # print_hex
1556 #  d0 - x
1557 #  d1 - y 
1558 #  d2 - value
1559 #  d3 - tile_bits[15:11]|digit_cnt[7:0]
1560 #  destroys a0, preserves d3
1561
1562 print_hex:
1563         XY2NT
1564         jsr             load_prepare
1565
1566 print_hex_preped:
1567         moveq.l         #0,d0
1568         move.b          d3,d0
1569         move.l          d0,d1
1570         lsl.b           #2,d0
1571         ror.l           d0,d2           /* prep value */
1572         subq.l          #1,d1           /* count */
1573         move.w          d3,d0
1574         and.w           #0xf800,d0      /* keep upper bits in d0 */
1575
1576 _print_hex_loop:
1577         rol.l           #4,d2
1578         move.b          d2,d0
1579         and.b           #0xf,d0
1580
1581         add.b           #'0',d0
1582         cmp.b           #'9',d0
1583         ble             0f
1584         addq.b          #7,d0
1585 0:
1586         move.w          d0,(a0)
1587         dbra            d1,_print_hex_loop
1588
1589         rts
1590
1591
1592 # wait vertical sync interrupt
1593
1594 wait_vsync:
1595         move.b          d7,d0
1596 _wait_change:
1597         stop            #0x2000
1598         cmp.b           d7,d0
1599         beq             _wait_change
1600         rts
1601
1602
1603 # wait vsync start (polling)
1604 #  destroys a0,d0
1605
1606 wait_vsync_poll:
1607         move.l          #GFXCNTL,a0
1608 0:
1609         move.w          (a0),d0
1610         and.b           #8,d0
1611         nop
1612         nop
1613         bne             0b
1614 0:
1615         move.w          (a0),d0
1616         and.b           #8,d0
1617         nop
1618         nop
1619         beq             0b
1620         rts
1621
1622
1623 test_code:
1624         nop
1625
1626 test_code_ret_op:
1627         jmp     0x123456        /* will be patched */
1628 test_code_end:
1629
1630 #################################################
1631 #                                               #
1632 #                 RAM DATA                      #
1633 #                                               #
1634 #################################################
1635
1636 .bss
1637
1638 # nothing :)
1639
1640 .end
1641
1642 # vim:filetype=asmM68k