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