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