CPCWiki forum

General Category => Programming => Topic started by: Fran123 on 17:46, 14 April 24

Title: Interruptions
Post by: Fran123 on 17:46, 14 April 24
Hello,

I was reading about interruptions on z80, and the doubt arose...

In what cases are IM0 and IM2 modes used in CPC?  are there examples?

Thank you!
Title: Re: Interruptions
Post by: andycadley on 18:18, 14 April 24
IM0 is essentially pointless, it requires hardware support the CPC does not have. IM2 is usable in the same sense it is on the Spectrum, you can just make a big table of jump addresses, but it's a lot more wasteful than just using IM1. Might have been more useful on the Plus machines, which were built with it in mind, except the implementation is buggy and better avoided.
Title: Re: Interruptions
Post by: McArti0 on 19:42, 14 April 24
org #8000
REPEAT 128
DW #B941
REND
.L8100
DI
LD A,#80 ;00.
LD I,A
IM 2
RET

CALL &8100
Title: Re: Interruptions
Post by: Prodatron on 20:30, 14 April 24
IM2 only makes sense if you have hardware expansions which are supporting this.
The CPC didn't have much/any, which made IM2 useful.
So like on nearly any other Z80 systems, which was comparable to the CPC, IM1 is your choice.
I just know that some MSX guys are using IM2.
Title: Re: Interruptions
Post by: andycadley on 20:54, 14 April 24
Quote from: Prodatron on 20:30, 14 April 24IM2 only makes sense if you have hardware expansions which are supporting this.
.
Very much this although on the Spectrum, which has ROM in the lower 16K, it becomes necessary to bypass the system interrupt handler.
Title: Re: Interruptions
Post by: McArti0 on 20:54, 14 April 24
IM2 makes sense when You want bank0 use as screen and You must remove 038h Vector.
Title: Re: Interruptions
Post by: roudoudou on 21:23, 14 April 24
Quote from: McArti0 on 20:54, 14 April 24IM2 makes sense when You want bank0 use as screen and You must remove 038h Vector.
you can start your screen at #38 (ok, a few bytes more) if you do not scroll...
Title: Re: Interruptions
Post by: McArti0 on 21:39, 14 April 24
But you know what I mean. You can escape from there thanks to IM2
Title: Re: Interruptions
Post by: toms on 12:33, 15 April 24
The tunnel effect in Octopus Pocus (https://www.pouet.net/prod.php?which=81008) uses IM2 because &0038 is not available for the interruptions (used as VRAM).
Title: Re: Interruptions
Post by: Longshot on 19:55, 26 April 24
Quote from: McArti0 on 19:42, 14 April 24org #8000
REPEAT 128
DW #B941
REND
.L8100
DI
LD A,#80 ;00.
LD I,A
IM 2
RET

CALL &8100
This routine can crash because the value of bit 0 of the address is not always 0.

You can identify the value of this bit beforehand to set a non-specific interrupt vector.

The most used is to create a table with 257 times the same value.
So if the value is #B9, for example, the interrupt will always occur at #B9B9 whatever the value of bit 0.
Title: Re: Interruptions
Post by: McArti0 on 21:01, 26 April 24
Quote from: Longshot on 19:55, 26 April 24This routine can crash
This routine must crash.

because readed low byte from D0-D7 is FF and jump address readed is 80FF(8100)

org #8001
REPEAT 128
DW #B941
REND
.L8101
DI
LD A,#80 ;00.
LD I,A
IM 2
RET

CALL &8101
Title: Re: Interruptions
Post by: lightforce6128 on 01:33, 27 April 24
Quote from: McArti0 on 21:01, 26 April 24org #8001


Why is it #8001 and not #8000? What happens if by chance #00 is used to calculate the table entry?
Title: Re: Interruptions
Post by: lightforce6128 on 01:42, 27 April 24
This reminds me on something: Without knowing about IM2 and under some very special conditions, I developed another possibility to "move" the interrupt address out of the way.

Four conditions: If you need the memory at #0038 because of e.g. an overscan screen, cannot spend 256 bytes for an interrupt table, you know that the pixels at #0038 to #003A will always show the same thing, e.g. background, and the screen is presented in mode 0, it is possible to use the following trick:

Command 'JP nnnn' has opcode #C3. Interpreted as mode 0 colors, these are two pixels drawn with pen 9. This means that command 'JP #C3C3' will forward the interrupt call to another address and will be visible as six pixels with pen 9. If pen 9 is used e.g. as background, the command itself will be invisible.

Now it is questionable, if address #0038 should not create clutter in the visible image, whether address #C3C3 is an improvement. In some special cases this might be. If not, one can sacrifice one other pen (set to the same ink as pen 9) to create a bunch of different addresses as target for the interrupt.

Of course, a similar result can be achieved by other techniques, e.g. color rasters or screen splitting, that have all their own pros and cons.
Title: Re: Interruptions
Post by: McArti0 on 06:13, 27 April 24
Manual z80 page 20:
A CPU reset clears the I Register so that it is initialized to 0. The lower eight bits of the pointer must be supplied by the interrupting device. Only seven bits are required from the interrupting device, because the least-significant bit must be a 0.

I misunderstood that bit0 is ignored and used as zero by z80. and that's not the case.

org #41b9
jp #b941 ; int with bit0=0

org %8000
db #B9
org #8001
REPEAT 128
DW #B941
REND
.L8101
DI
LD A,#80 ;8000-80FF
LD I,A
IM 2
RET

CALL &8101
Title: Re: Interruptions
Post by: andycadley on 08:59, 27 April 24
You need 257 identical bytes because the value on the bus is usually FFh, but not guaranteed. That also means your ISR needs to start at an address with matching low/high bytes, eg. C3C3h

On a Plus things are different, because the hardware has support for auto vectoring and thus will put one of four values on the bus with bit 0 guaranteed to be 0. It's broken and doesn't put the correct value on the bus, but does mean you only need an 8 byte vector table and all entries can be set to any address you like.
Powered by SMFPacks Menu Editor Mod