printf(" PC: %08x SR: %04x \n", f->g.pc, f->g.sr);
sp_add = 6;
}
- for (i = 0; i < 8; i++)
+ sp = (u32 *)(f->ar[7] + sp_add);
+ for (i = 0; i < 7; i++)
printf(" D%d: %08x A%d: %08x \n", i, f->dr[i], i, f->ar[i]);
+ printf(" D%d: %08x SP: %08x \n", i, f->dr[i], (u32)sp);
printf(" \n");
- sp = (u32 *)(f->ar[7] + sp_add);
printf(" %08x %08x %08x %08x\n", sp[0], sp[1], sp[2], sp[3]);
printf(" %08x %08x %08x %08x\n", sp[4], sp[5], sp[6], sp[7]);
}
;
}
+static void wait_next_vsync(void)
+{
+ while (read16(VDP_CTRL_PORT) & SR_VB)
+ /* blanking */;
+ while (!(read16(VDP_CTRL_PORT) & SR_VB))
+ /* not blanking */;
+}
+
static void t_dma_zero_wrap_early(void)
{
const u32 *src = (const u32 *)0x3c0000;
expect(ok, r32[0x28/4], 0x5a5a5a28);
expect(ok, r32[0x2c/4], 0x07075a2c); // 7 - last_irq_vec
if (!(r16[0x00/2] & 0x8000)) {
- expect(ok, r8 [0x81], 0);
- expect(ok, r16[0x82/2], 0);
- expect(ok, r16[0x84/2], 0);
- expect(ok, r16[0x86/2], 0);
- //expect(ok, r16[0x88/2], 0); // triggers fill?
+ expect(ok, r8 [0x81], 1);
+ expect(ok, r16[0x82/2], 1);
+ expect(ok, r16[0x84/2], 0xff);
+ expect(ok, r16[0x86/2], 0xffff);
+ expect(ok, r16[0x88/2], 0);
expect(ok, r8 [0x8b] & ~2, 0); // FEN toggles periodically?
expect(ok, r16[0x8c/2], 0);
expect(ok, r16[0x8e/2], 0);
+ // setup vdp for t_32x_init
+ r8 [0x81] = 0;
+ r16[0x82/2] = r16[0x84/2] = r16[0x86/2] = 0;
}
r32[0x20/4] = r32[0x24/4] = r32[0x28/4] = r32[0x2c/4] = 0;
for (s = 0; s < 2; s++)
// prepare for reset btn press tests
static int t_32x_reset_prep(void)
{
- u32 *fbl_icnt = (u32 *)(0x840000 + IRQ_CNT_FB_BASE);
+ u32 *fbl = (u32 *)0x840000;
+ u32 *fbl_icnt = fbl + IRQ_CNT_FB_BASE / 4;
u32 *r32 = (u32 *)0xa15100;
u16 *r16 = (u16 *)r32;
u8 *r8 = (u8 *)r32;
r32[0x24/4] = 0x5a5a5a24;
r32[0x28/4] = 0x5a5a5a28;
r32[0x2c/4] = 0x5a5a5a2c;
+ if (!(r16[0x00/2] & 0x8000)) {
+ wait_next_vsync();
+ r16[0x8a/2] = 0x0001;
+ mem_barrier();
+ for (i = 0; i < 220/2; i++)
+ fbl[i] = 0;
+ r8 [0x81] = 1;
+ r16[0x82/2] = 0xffff;
+ r16[0x84/2] = 0xffff;
+ r16[0x86/2] = 0xffff;
+ r16[0x8a/2] = 0x0000;
+ r16[0x8c/2] = 0xffff;
+ r16[0x8e/2] = 0xffff;
+ r16[0x100/2] = 0;
+ }
return ok;
}
;
}
-static void wait_next_vsync(void)
-{
- while (read16(VDP_CTRL_PORT) & SR_VB)
- /* blanking */;
- while (!(read16(VDP_CTRL_PORT) & SR_VB))
- /* not blanking */;
-}
-
static unused int hexinc(char *c)
{
(*c)++;
(v8 & 0x40) ? "pal" : "ntsc",
have_32x ? "32X" : "",
en_32x ? "+" : "");
+ printf("reset hvc %04x->%04x\n", read16(-4), read16(-2));
+
+ // sanity check
+ extern u32 sh2_test[];
+ if (sh2_test[0] != read32(0x3e0) || sh2_test[0x200/4] != read32(0x3e4))
+ printf("bad 0x3c0 tab\n");
for (i = 0; i < ARRAY_SIZE(g_tests); i++) {
// print test number if we haven't scrolled away
printf_ypos = 0;
printf(" ");
- if (have_32x) {
+ if (have_32x && (read16(0xa15100) & 1)) {
u8 *p = (u8 *)0xff0040;
u32 len = x32x_switch_rv_end - x32x_switch_rv;
px32x_switch_rv = (void *)p; p += len;
// todo: broken printf
px32x_switch_rv(0);
}
- for (i = 0; i < 60*60 && !(pget_input() & BTNM_A); i++)
- wait_next_vsync();
+ for (i = 0; i < 60*60 && !(pget_input() & BTNM_A); i++) {
+ while (read16(VDP_CTRL_PORT) & SR_VB)
+ write16(-4, read16(VDP_HV_COUNTER)); /* blanking */
+ while (!(read16(VDP_CTRL_PORT) & SR_VB))
+ write16(-4, read16(VDP_HV_COUNTER)); /* not blanking */;
+ }
#ifndef PICO
// blank due to my lame tv being burn-in prone
VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
#endif
while (!(pget_input() & BTNM_A))
- burn10(488*100/10);
+ write16(-4, read16(VDP_HV_COUNTER));
VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
.word 0x5100,0x3340,0x0006,0x303C,0x8000,0x6004,0x44FC,0x0001\r
\r
RST:\r
- move.w #0x2600, %sr\r
-\r
- move.b (0xA10001), %d0\r
- andi.b #0x0F, %d0\r
- beq.s 0f\r
- move.l #0x53454741, (0xA14000) /* 'SEGA' */\r
+ andi.b #0x0F, (0xA10001) /* 24 */\r
+ bne.s 0f /* 10 */\r
+ move.w #0x8104, (0xc00004)\r
+ bra 1f\r
0:\r
- tst.w (0xc00004).l\r
+ move.l #0x53454741, (0xA14000) /* 28 'SEGA' */\r
+1:\r
+ move.w (0xc00008), %d0 /* 16 */\r
+ move.w %d0, -(%sp)\r
+ subq.l #2, %sp\r
+ move %sp, %usp\r
\r
- moveq #0, %d0\r
- movea.l %d0, %a7\r
- move %a7, %usp\r
+ move.w #0x2600, %sr\r
\r
/* clear .bss */\r
+ moveq.l #0, %d0\r
lea __bss_start, %a0\r
lea __end, %a1\r
0:\r
pre_exception:\r
move.w #0x2700, %sr\r
movem.l %d0-%d7/%a0-%a7,-(%sp)\r
- add.w #2, 0x3e(%sp)\r
+ add.w #2, 0x3e(%sp) /* ecxnum */\r
move.l %sp, %d0\r
- move.l %d0,-(%sp) /* arg0 */\r
+ move.l %d0,-(%sp) /* arg0 */\r
jsr exception\r
0:\r
bra 0b\r
.long master_irq4 /* Command interupt */
.long master_irq5 /* H Blank interupt */
.long master_irq6 /* V Blank interupt */
+! .long main_irq_vres
.long master_irq7 /* Reset Button */
.rept 56
.long master_err /* peripherals */
mov.l r1, @-r15
mov.l l_irq_cnt, r1 /* counters in fb (0x2401ff00) */
+! According to "32X Technical Information Attachment 1" FTOA pin must be toggled
+! or interrupts may be missed when multiple irqs trigger. We skip that here since
+! we test only 1 irq at a time.
do_irq_cmn:
mov.l r2, @-r15
mov #0x80, r0
! not used
.if 0
-main_irq_vres_:
+main_irq_vres:
mov.w r0, @(0x14, gbr) /* ack */
mov.b @(7, gbr), r0 /* RV */
tst #1, r0
mov.b r0, @(5, r1) /* OCRB L */
mov.b r0, @(2, r1) /* FRC H */
mov.b r0, @(3, r1) /* FRC L */
- mov.b @(7, r1), r0
+ mov.b @(3, r1), r0
! sleep - docs say not to use
! sleep
0: