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