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