Page 1 of 2

ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Sun Jun 07, 2020 6:31 pm
by zx81ultra
Hello,

I'm trying to learn how interrupts work on the ZX81 with z88dk. This im2 mode code crashes but it works fine on the Spectrum.

I also read that it's possible to install an isr that's called every time the screen is rendered, that is 50 or 60 times each second, anyone knows if that's possible to do in C ?

Thanks !

Code: Select all

#include <stdlib.h>
#include <stdio.h>                
#include <string.h>
#include <zx81.h>
#include <im2.h>

// zcc +zx81 -create-app isr03.c

M_BEGIN_ISR(isr)                    
{
// do stuff
}
M_END_ISR
 
void main(void)
{
   #asm
   di
   #endasm
 
   im2_Init((void *)0xd300);          // place z80 in im2 mode with interrupt vector table located at 0xd300
   memset((void *)0xd300, 0xd4, 257); // initialize 257-byte im2 vector table with all 0xd4 bytes
   bpoke(0xd4d4, 195);                // POKE jump instruction at address 0xd4d4 (interrupt service routine entry)
   wpoke(0xd4d5, (unsigned int) isr); // POKE isr address following the jump instruction
 
   #asm
   ei
   #endasm
 
loop:

//do stuff

goto loop; 
}

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Sun Jun 07, 2020 7:19 pm
by dr beep
zx81ultra wrote: Sun Jun 07, 2020 6:31 pm Hello,

I'm trying to learn how interrupts work on the ZX81 with z88dk. This im2 mode code crashes but it works fine on the Spectrum.

I also read that it's possible to install an isr that's called every time the screen is rendered, that is 50 or 60 times each second, anyone knows if that's possible to do in C ?

Thanks !

Code: Select all

#include <stdlib.h>
#include <stdio.h>                
#include <string.h>
#include <zx81.h>
#include <im2.h>

// zcc +zx81 -create-app isr03.c

M_BEGIN_ISR(isr)                    
{
// do stuff
}
M_END_ISR
 
void main(void)
{
   #asm
   di
   #endasm
 
   im2_Init((void *)0xd300);          // place z80 in im2 mode with interrupt vector table located at 0xd300
   memset((void *)0xd300, 0xd4, 257); // initialize 257-byte im2 vector table with all 0xd4 bytes
   bpoke(0xd4d4, 195);                // POKE jump instruction at address 0xd4d4 (interrupt service routine entry)
   wpoke(0xd4d5, (unsigned int) isr); // POKE isr address following the jump instruction
 
   #asm
   ei
   #endasm
 
loop:

//do stuff

goto loop; 
}
IM 2 doesn't work that way on the ZX81.
However you can use the start of the screendisplay to do a small other routine.
Best moment is to do a display first and the routine after the display.

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Tue Jun 09, 2020 1:53 am
by zx81ultra
Could you point me somewhere to find info on how it works ? not really strong in MC, that's why I'm trying to do it from C

Thank you Dr. Beep !

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Tue Jun 09, 2020 10:02 pm
by hlide
Let me explain.

First, the ZX81 ROM uses IM1 and address 0x38 to service interrupts, which should raise some questions about the feasability to use IM2. Why? in IM2, the address of the routine to service the interrupt is given by register I and an identifier set by the device interrupting the CPU tha way: I * 256 + byte put by the device in the data bus while /IRQing. See the point? IM1 has no need for a device to put a byte in the data bus. By using IM2 and having no device to put the right byte you may jump to anywhere in a page because it will read a fake byte on the data bus.
p4xup.png

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 4:08 am
by zx81ultra
if I got it right, with no device feeding the bus, IM2 will catch any floating byte there and crash ? I guess this is far beyond my technical knowledge :)

So if i'm correct, the alternative left is to implement a routine that is called after the display is done, I'm not sure if that's possible to do from C with z88dk, I hope there's a way.

Thank you for the detailed explanation !

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 10:46 am
by siggi
hlide wrote: Tue Jun 09, 2020 10:02 pm Let me explain.

By using IM2 and having no device to put the right byte you may jump to anywhere in a page because it will read a fake byte on the data bus.
The ZX81 has 10K pullup resistors connected to the data bus. Thus if no device drives the data bus during interrupt acknowledge cycle, the Z80 will get value $FF. But this is not a good value, because it is odd. Usually the externally applied interrupt vector should be even, because it points to a 16-bit table in memory.

Siggi

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 12:35 pm
by dr beep
zx81ultra wrote: Thu Jun 11, 2020 4:08 am if I got it right, with no device feeding the bus, IM2 will catch any floating byte there and crash ? I guess this is far beyond my technical knowledge :)

So if i'm correct, the alternative left is to implement a routine that is called after the display is done, I'm not sure if that's possible to do from C with z88dk, I hope there's a way.

Thank you for the detailed explanation !
yes, in fact it is a fixed routine ( will share later) with a call to your routine.

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 1:20 pm
by siggi
Using BASIC and machine code, Wilf's NOVA allows to call "short" or "long" machine code routines during display. Docs are here (switch to character set "western" for correct display).

http://www.user.dccnet.com/wrigter/inde ... va2005.htm

Siggi

PS: The "machine code" could also be a compiled C program ;)

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 6:49 pm
by olofsen
Just a note that the clock available here viewtopic.php?p=17265#p17265 hooks up an ISR, but I don't remember all details... The address of a C function (although consisting of assembly code) is "poked" to the startup code of the ISR that z88dk installed, at 0x41b4.The source for this alternative ISR may now be found in "lib/target/zx81/classic", but at the time it may have been in "lib". Most likely I inspected the generated P file to find the address to hook to; and in later versions of z88dk this address may have changed. But perhaps this is the difficult way to do this...

Re: ZX81 interrupts with z88dk, how to install an ISR ?

Posted: Thu Jun 11, 2020 7:53 pm
by siggi
FYI:
old feature request for Z88DK about this topic:

https://www.z88dk.org/forum/viewtopic.php?id=4877

old thread about this topic:

https://www.sinclairzxworld.com/viewtop ... 046#p31046

BTW: in my ZX81-MIDI-Player I am using the ZX81 NMI interrupt generator to make the MIDI clock. Of course the display is not generated during playing the MIDI song:
https://forum.tlienhard.com/phpBB3/view ... 598#p35598