Page 1 of 1

Is IM2 mode supported on the ZX81 ?

Posted: Sun May 31, 2020 2:08 pm
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; 
}

Posted: Wed Jun 10, 2020 8:34 pm
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

Posted: Wed Jun 10, 2020 9:05 pm
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

Posted: Thu Jun 11, 2020 1:52 am
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 !

Posted: Fri Jun 12, 2020 4:02 pm
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);
}

Posted: Sat Jun 13, 2020 3:27 am
by zx81ultra
It works now !

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