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