Is IM2 mode supported on the ZX81 ?

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Is IM2 mode supported on the ZX81 ?

Post by zx81ultra »

Hello,

This code crashes, tested on ZesarUX and ZXSP. Is IM2 mode supported on this target ? maybe the vector table has to be located elsewhere ?

Code: Select all

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

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

int x = 0; 
 
M_BEGIN_ISR(isr)                    
{
  ++x;
}
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; 
}
siggi
Well known member
Posts: 343
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

The ZX81 uses /INT and /NMI to generate the display. Thus you cannot use any other interrupt during SLOW mode.
Maybe your code will run during FAST mode of ZX81. But restore all registers AND the original int-mode before switching back to SLOW mode to show a result ...

Siggi
siggi
Well known member
Posts: 343
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

If you check the schema of the ZX81, you will notice that the /NMI line is driven by the ULA and /INT is driven by the Z80. Thus it's not easy to drive the /INT line by an external device ...

Siggi
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

What other options could I explore to have some sort of ISR on the ZX81 with z88dk ? I've seen assembly code programs that implement a routine that is called 50 or 60 times a second, after the display is done refreshing, is that possible in C ?

Thank you for the explanations !
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

I found the example of a clock implemented as a ISR with z88dk calling a function every display refresh: https://sinclairzxworld.com/viewtopic.p ... 265#p17265 download source here:http://rullf2.xs4all.nl/sg/clock.zip

My new test code is based on that example but the hard-coded 0x41b4 address must have changed in z88dk since then:

Code: Select all

/* zcc +zx81 -create-app disp_isr.c */

/* Inspired by RELOGIO By K. Murta http://zx81.eu5.org/toddysofte.html,
   and the z88dk source of gmtime(). 

Also based on olofsen post https://www.sinclairzxworld.com/viewtopic.php?p=17265#p17265
*/

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

extern int d_file @16396;
unsigned char i, isrText[32], *Display; 

void DisplayISR(void)
{
for(i = 0; i < 32; ++i)
        isrText[i] = rand()%64;

memcpy(Display,isrText,32);

#asm
jp 0x02a4  ; return to the main program
#endasm 
}

void hook()
{
#asm
          ld      hl,_DisplayISR
          ld      (0x41b4),hl        ; 0x41b4 I guess this address has changed in z88dk ?
          ld      a,0xc9                                                        
          ld      (0x412e),a         ; same here ?
#endasm
}

void main(void)
{
Display = (unsigned char *) d_file + 1; 

hook();

while(1);
}
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

It works now !

Source code and executable here: https://www.sinclairzxworld.com/viewtop ... 287#p38287
Post Reply