Turbo R - interrupt line issues

Page 2/2
1 |

By ro

Scribe (4962)

ro's picture

31-03-2023, 14:55

You know, the VDP can trigger two kind of interrupts: a vblank, and a line interrupt. The code you posted looks correct and only handles vblank. Or at least, it looks like that.

First, the stat reg should prolly already be set at zero, so just do IN A,(#99) directly. Second, by doing RLCA you might wanna check Carry flag, not the zero flag. The Cy should contain bit 7 of A.

Here's a snippet of my code called from #38 (I've left out some, this is the base you need)

; Int. Service Routine (RST &H38)
ISR:	PUSH	AF
	IN	A,($99)  ;statreg should be 0
	RLCA	
LNIISR:	JP	NC,LNI_00  ;jump directly to line int.
	PUSH	BC
	PUSH	DE
	PUSH	HL
	EX	AF,AF
	EXX	
	PUSH	AF
	PUSH	BC
	PUSH	DE
	PUSH	HL
	PUSH	IX
	PUSH	IY
	CALL	VBLANK ;the vbl int
	POP	IY
	POP	IX
	POP	HL
	POP	DE
	POP	BC
	POP	AF
	EXX	
	EX	AF,AF
	POP	HL
	POP	DE
	POP	BC
LNI_00:	POP	AF
	EI	
	RET	

Notice you don't have to DI, it's already disabled at this point. Second, after saving AF, a check for which int follows. In the NC case (b7=0), I assume a line interrupt. Now, in this example there's some self modifying code going on if you want a line interrupt routine be called. In this case, it just end the ISR.

By reading statreg 0, you will also automatically reset the interrupt flag.

The reason why I jump to LNI as fast as possible, is because you prolly need that timing. If you are familiar with line interrupts, screensplits, etc, you'll know what I mean. (I'm from the demo scene).

But yeah, nothing more to it. Make sure #38 is accessible, that's all.

By shram86

Expert (117)

shram86's picture

02-04-2023, 16:45

Hey ro, thanks for the follow-up - I wanted to clarify some things since this is a common beginner issue and its all about compatibility with multiple systems.

1. SREG may actually be not 0, I do a lot of VDP commands so I use status reg 2 fairly often.
2. Ah yes... should check the correct flag of course lol. In the example code, I was cp $80 ; jr z just to be 100% sure I was doing it right. I usually do rlca ; jr c . My code is right but I do make mistakes like that late at night Smile.
3. Thanks for the tips on speed. My current project uses mode 6 so its not a fast game overall, but Ill adjust things if I do buffer effects or timing critical stuff.
4. I could have been seeing some other bug, but in my tests on emulator, both $fd9a and $fd9f (HKEYI and HTIMI) must be called to reset all the interrupt lines. This matches the BIOS code in my MSX2, which didn't have any interrupt woes.

In addition, to make sure that the code will execute on ALL systems across all page formats, the best place for the routine is in page 3, which to my knowledge is a RAM page that is almost never paged out. The beginning of my program now starts with

ld hl,_irq 
    ld de,0xc580 
    ld bc,_endirq-_irq 
    ldir 
    ; install ISR
    ld a,$c3 
    ld ($0038),a 
    ld hl,0xc580
    ld ($0039),hl 
    

Again, this matches my working MSX2 system which only stores a vector to page 3 in page 0, contrasting to the A1ST whose vector remains in page 0.

By snake

Expert (71)

snake's picture

07-04-2023, 16:56

Under Dos, addresses 0-255 are system reserved area, so you can't hook your interrupt routine directly to address 56.

Page 2/2
1 |