Autor
| Quick and dirty interrupt?
|
Sdw msx novice Posts: 29 | Postado em: 05 Outubro 2008, 20:16   |
I have a routine. I want it called once per frame. What is the quick and dirty way to do it?
I have set up gfx-modes myself straight from the VDP, no BIOS stuff used.
This is for a demo, so no need to be system friendly by setting stuff back to the original state later etc., all I want is something that calls my routine once each VBL.
I have been reading and testing and getting more and more confused by different IM (0/1/2) and BIOS-stuff and call-vectors and 38h and fd9fh and whatnot. For example there seems to be two different VBL interrupts that one can enable in the VDP, one in register 1 and one in register 2?
I guess I'm in a bit over my head, knowing next to nothing about the MSX and only semi-experienced with the Z80 itself.
So in essence, please fill in the blanks:
di
// Magic code here that makes MyRoutine called once per frame, please!
ei
infloop:
jp infloop
MyRoutine:
Here I do my graphical effect
...
ret
|
|
Sonic_aka_T
 msx guru Posts: 2269 | Postado em: 05 Outubro 2008, 20:51   |
Just use the hooks on FD9A / FD9F...
ORG $C000
SETISR:
LD HL,$FD9F
LD DE,OLD_HK
LD BC,$0005
LDIR
LD A,$C3
LD HL,NEW_HK
DI
LD ($FD9F),A
LD ($FDA0),HL
EI
RET
NEW_HK:
; THIS IS CALLED EVERY INT
JP OLD_HK
OLD_HK:
DB $C9,$C9,$C9,$C9,$C9
|
|
Sonic_aka_T
 msx guru Posts: 2269 | Postado em: 05 Outubro 2008, 20:52   |
Oh, and don't forget to restore the hook on $FD9F before you exit your program... (just LDIR OLD_HK back to $FD9F)
|
|
Sdw msx novice Posts: 29 | Postado em: 05 Outubro 2008, 22:32   |
Thanks, I actually tried something similar before, but couldn't get it to work. However I did finally find a bit of code that did exactly what I wanted and that works:
di
ld hl,irq
ld (38h+1),hl
ld a,0c3h
ld (38h),a
ei
inf:
jp inf
irq:
push af
push bc
push de
push hl
push ix
push iy
in a,(99h) ; ACKnowledge?
call myeffect
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ei
ret
This seems to work fine, the $df9f approach never did for me for some reason. Ah well, the only thing that matters is that at leat I got SOMETHING to work! |
|
Prodatron msx master Posts: 1110 | Postado em: 06 Outubro 2008, 01:41   |
I would modify it a little bit:
[...]
irq:
push af
in a,(99h) ; ACKnowledge?
rla
jr nc,other_irq
push bc
push de
push hl
push ix
push iy
call myeffect
pop iy
pop ix
pop hl
pop de
pop bc
other_irq:
pop af
ei
ret
This will check, if the IRQ has been really triggered by the VDP. If not (there is other additional MSX hardware, which could trigger an IRQ) it won't call the routine. |
|
ARTRAG msx master Posts: 1737 | Postado em: 06 Outubro 2008, 10:40   |
@Sdw
naturally, in order to write at 38h, you need to have RAM in page 0,
i.e., or you started your program in msxdos (the easiest way to get ram there),
or you have started from basic and set by yourself RAM at page 0 using
or I/O ports or BIOS calls.
|
|
Sdw msx novice Posts: 29 | Postado em: 06 Outubro 2008, 13:22   |
Thanks Prodatron, that makes sense!
ARTRAG:
Actually I hadn't realized that the MSX didn't have the RAM at fixed locations. Guess I need to read up a bit on that!
|
|
nikodr msx addict Posts: 491 | Postado em: 06 Outubro 2008, 14:44   |
I think that the default 38 interrupt handler is not good and is not optimized for speed.Apart from the call to the $Fd9a and $Fd9f Hook there are some unneeded calls.
I think this one will help you (From the Karoshi msx forum)
Patch FD9a |
|
ARTRAG msx master Posts: 1737 | Postado em: 06 Outubro 2008, 15:29   |
It is not correct.
The BIOS interrupts is not optimized for speed, so using FD9A implies a waste of time that can only oartially avoided by the trick you pointed.
On the speed side, writing your code at 0x38 is the best thing you can do.
|
|
jltursan msx professional Posts: 886 | Postado em: 06 Outubro 2008, 19:11   |
...or implement an IM2 interrupt, keeping the BIOS in page 0.
|
|
nikodr msx addict Posts: 491 | Postado em: 07 Outubro 2008, 00:17   |
I am amazed though by the tricks of konami programers.As stated on other threads,the games are completely based on the interrupts since the main loop of the games conists of
XXXX:JR XXXX
(though i think would be better if it was something like
xxxx:Halt
Jr xxxx)
They used bios calls to 38 and then used the hooks on Fd9a and Fd9f.
How much faster would those vdp driven games be if they had written their own custon interrupt handler directly on 0x38 ?
Jitursan i would be interested if you could tell us some more about Im2 examples,i have seen a demo on karoshi site that has some text demo with flashing fonts using im2.
|
|
Edwin msx professional Posts: 626 | Postado em: 07 Outubro 2008, 00:24   |
Quote:
| How much faster would those vdp driven games be if they had written their own custon interrupt handler directly on 0x38 ?
|
I don't think they would have increased the memory requirements to 64KB for that. |
|
nikodr msx addict Posts: 491 | Postado em: 07 Outubro 2008, 15:09   |
Edwin what i meant is that there is some precious time lost when there is the call to $fd9a and $fd9f through bios at the call to $38.
Yet despite that loss most of konami games are fast and do not suffer from it.Maybe the fact that the main loop of the game is in the interrupt routine has something to do with it?
Now if somebody could post an asm example that would feature sprite moving or horizontal scrolling through interrupt mode 2 ?
The flashing text example posted at karoshi site seems very good and uses im2 (though it does not have scrolling or moving of sprites).
|
|
|
|
|