Interrupt programming

Page 1/2
| 2

By Latok

msx guru (3703)

Latok's picture

01-01-2003, 20:11

It's no secret I'm not a very good ASM coder, so erhm....I guess it's ok to ask a stupid question about programming, right? Some people say stupid questions don't exist, but I don't agree on that, so erhm....Shame on me now Big smile

What I always have wanted to know more about is interrupt programming. I've done some starfields out of sprites lately and the thing I did was diversing the hook at address #fd9f. I've put the old #fd9f content at the end of my source so it would be executed as well. Next I did a DI, PUSH'd registers and I worked through some coding using BIOS calls and the character table of sprites to make a movement. Then POP'd registers and an EI.

This starfield works nicely, but how much code can you execute in one interrupt is my question. ERhm....I do a DI, so there's no interrupt at all, right? But I slow down things if I put too many code to execute before EI again? And how does my program remember the content of the registers? Coz my starfieldprogram has to be executed from BASIC. I don't know how to put sprites on the screen, so I used BASIC for that. Hybride programming Smile

It's just...You see I even have difficulties asking the question. I know I did some interrupt programming and it also works, but I don't REALLY understand the thing. Especially I would like to have some answers on the content of the registers and the amount of code you can execute during a DI.

Thx in advance and don't laugh too loud, will ya! :O

Login or register to post comments

By anonymous

incognito ergo sum (109)

anonymous's picture

01-01-2003, 21:02

Generally it's not a good idea to use EI in an interrupt routine AT ALL. Some interrupt routines may expect interrupts to be disabled (because the Z80 automatically does that when executing an interrupt). The BIOS will 'EI' the interrupts automatically after all FD9F routines have been serviced.

The BIOS interrupt code differs between MSX models and MSX generations and will affect the number of CPU cycles you have at your disposal in an interrupt. But as long as you keep interrupts disabled (which is the default) there is virtually no limit to how much code you can execute. If you execute more code than the CPU can execute within the interrupt, it will just skip one. Ofcourse this makes everything go slower.

As an example take Aleste2. The entire game seems to be programmed on the interrupt. If there are a lot of enemies on screen the whole game will slow down. The slowing down is because half of the interrupts are skipped.

The content of the registers at the moment your interrupt routine starts to be executed is random. Unless you store the registers in memory somwhere your program won't be able to remember the values between 'sessions'. You should know what you did, it's your program! >_<

Latok, IRC to #msxdev @ irc.rizon.net, it is the channel created for questions like this! I (or one of the other programmers there) can help you with your programming questions.

By Latok

msx guru (3703)

Latok's picture

02-01-2003, 09:42

So erhm. It's the address #38 which does the interrupthandling right? And it does a DI before jumping to #fd9f and when it comes back it does an EI? Ok, thanks for that. About the content of the registers. Do I need to PUSH and POP the registers in my routine or does the #38 also do this PUSH and POP thing, just as this routine does DI and EI? And I understand now I have to store the content of the registers somewhere in the memory, coz else between 'sessions' the content of the registers change? I thought maybe #38 also makes sure the content of the registers are being restored to the value they had in my routine.

And you are right, #msxdev on IRC.RIZON.NET is THE place for questions like these.

By BiFi

Enlighted (4348)

BiFi's picture

02-01-2003, 11:29

in short:

- at every interrupt the Z80 jumps to address $0038

- it stores all registers and jumps to $FD9A

- it returns from there it checks if the VDP caused the interrupt

  • if not, it restores all registers and returns to the main program
  • if so, it jumps to $FD9F (AF, containing the contents of VDP status register 0, is NOT stored), so if you need to have i.e. sprite collisions detected in basic after that, you need to store AF yourself before you do anything and restore it before you return to the interrupt routine and it handles stuff like keyboard scanning and basic PLAY command.

that's basically what the interrupt routine does.

By Latok

msx guru (3703)

Latok's picture

02-01-2003, 12:22

Thanks BiFi. What I was trying to ask is if register B has i.e. 240 (decimal) as value and I have in my routine a DEC B for instance and the interrupt routine goes back to #38, does the same interrupt thing again and comes again at #fd9f, where it jumps to my routine, does the B-register then contain the value 239 (decimal)? Or is the B-register changed by the hardware interruptroutine or other programs? Do I need to put content of the B register somewhere in the memory or can I trust 100% the B-register is restored to the value it should have in my routine? And if it's restored, where does that happen? Maybe more programs are 'hanging' on the interrupt routine? What if they doesn't PUSH and POP correctly?

By BiFi

Enlighted (4348)

BiFi's picture

02-01-2003, 13:03

Outside of an interrupt, when using the standard MSX interrupt, everything is restored the way it was when the interrupt routine is finished.

In an interrupt, if you're not sure a value is stored correctly, PUSH and POP it yourself. You are talking about a counter that is decreased every interrupt? Then you need to store it somewhere in memory.

By Latok

msx guru (3703)

Latok's picture

02-01-2003, 14:17

Ok, thank you all. I think I understand now. I hope. Wink

By anonymous

incognito ergo sum (109)

anonymous's picture

02-01-2003, 22:45

Think about it, if the BIOS would preserve your interrupt registers, it would be backwards!

An interrupt INTERRUPTS a normal program, so that is the one needing its registers preserved.

Also, how do you think that could ever work? You call the old FD9F routine after your own code. Imagine the Moonblaster player also on the FD9F hook, so after you finished your code you call it. Its registers won't be magically preserved! See the problem? Tongue

When using ASM/BASIC hybrid, be sure to use CLEAR to make sure BASIC doesn't touch your ASM code and variables!

By Latok

msx guru (3703)

Latok's picture

03-01-2003, 08:54

GuyveR800, thank you for that last remark. It makes sense and I DO understand it now 100%. Indeed, many programs can be hooked at fd9f. It can't be all the registers are being preserved. And indeed it's the interrupt. The BIOS-routine should preserve its own content of registers.

The thing is, in my starfield code, I use the B-register as a counter. I don't store its content anywhere and still, it works! With hybride programming. So it must be pure luck the content of the B-register isn't changed or something?

By ro

Guardian (4145)

ro's picture

03-01-2003, 11:22

uhu, see if I remember correctly.

Dude, why don't you DISasm from BIOS adr. #0038 and see what it does.

I'll tell you this. It WILL push ALL registers, which is a stupid thing in the first place...

What if you only use the A and HL reg for an int? seems waste of time to push and pop all registers (even the shadow registers!), not?

There for, you might wan't to hurry all thing by checking the order of pushing reg from #38 and POP them in your own routine, INCLUDING an extra POP for SP, so you WON'T jump back to #38 for more int. handling.

OR

make your own BIOs Wink

(remember to make a interrupt routine, eh)

Oh, I forgot to mention you have to reset a certain bit on a certain port when doing own BIOS routs.... can't remember.. damn.

oh.. you do NOT have to DI, coz it's been done allready. Never EI either, why should you?

---------------

And, why is it hard to put sprites in ASM? Just put data in VRAM (eg VPOKE), just check the 'all you wanna know about sprites' documents I've written many years ago (check, sunrise mag. special or even MILC). They might clear up things for you, in DETAIL!

gr, ro

ps. I always checked the length of my ints by using background colour switching at the beginning and end of my ints... you can SEE how lang it takes for the machine to handle your code.

By Latok

msx guru (3703)

Latok's picture

04-01-2003, 10:40

Cheers for all your reactions! It got me programming the interrupt again, last night. And I succeeded integrating a starfield on the interrupt and a heart beat visualization at the same time....hehehe.....This is something I never thought of being capable of. Cool! Let's see if I can add some music on the background Big smile Big smile

Page 1/2
| 2