Despite it works on EO (48K Zx81), it does not work on my Zeddies.
Does IM2 require special things (like a floating data bus during reading the interrupt vector)?
I don't have "naked" Zeddies, all have additional hardware installed (for storage of programs on USB-stick or SD-cards), which are also connected to the data bus. None of them is designed for usage during IM2 ...
Siggi
Demo of XTRICATOR Pseudo-UDG driver
Re: Demo of XTRICATOR Pseudo-UDG driver
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
http://zx81.ddns.net/ZxTeaM
Re: Demo of XTRICATOR Pseudo-UDG driver
This is the first program I've ever seen using the Z80 IM2 mode. It runs on a standard 16K machine, so it must require nothing specialDoes IM2 require special things (like a floating data bus during reading the interrupt vector)?
The EXTRICATOR routine is definitely designed for the standard ZX81 display architecture ... so it is a challenge is to find a way to modify it to work with modified machines. Do your 48K machines use standard M1NOT circuit, or a modified implementation? I am no expert on this, but I would guess EightyOne is emulating the basic circuit
To be clear:
* the routine builds HFILE with each line beginning with CD9640, followed by 256 bits of 0 (32 bytes of 00). During runtime it does not modify the CD9640
* No other values are in the range where bit 6 is high are used. The demo (and the original Z-Xtricator game) change the 00 bytes to draw characters on-screen. It uses standard ZX81 character set characters. For example, to draw the custom sprite
Code: Select all
;SHIP sprite 3x8 bytes ;Rendered from scan lines of $1E (standard) ROM patterns $1E00+nn*8+l
' ' //000000 ;00000000 00000000 00000000 00 00 00 ' ' 0 scan line
' ' //000000 ;00000000 00000000 00000000 00 00 00 ' ' 1
'¢¡ ' //020100 ;00001111 11110000 00000000 0F F0 00 ' ±±±±±±±± ' 2
'EX ' //2A3D00 ;01111100 00011000 00000000 7A 0A 00 ' ±±±±± ±± ' 3 2A:$1E00+$2A*8+3=($1E53)=$7C/01111100
'±±¤' //808004 ;11111111 11111111 11110000 FF FF F0 '±±±±±±±±±±±±±±±±±±±± ' 4
'±±¤' //808004 ;11111111 11111111 11110000 FF FF F0 '±±±±±±±±±±±±±±±±±±±± ' 5
'±± ' //808000 ;11111111 11111111 00000000 FF FF 00 '±±±±±±±±±±±±±±±± ' 6
'¥± ' //878000 ;00001111 11111111 00000000 0F FF 00 ' ±±±±±±±±±±±± ' 7
CHR BYTES BYTES (BINARY) scanlines '01234567 bits 01234567'
Re: Demo of XTRICATOR Pseudo-UDG driver
My Zeddies use a "standard" M1NOT logic.David G wrote: ↑Thu Nov 21, 2024 8:07 pmThis is the first program I've ever seen using the Z80 IM2 mode. It runs on a standard 16K machine, so it must require nothing specialDoes IM2 require special things (like a floating data bus during reading the interrupt vector)?
The EXTRICATOR routine is definitely designed for the standard ZX81 display architecture ... so it is a challenge is to find a way to modify it to work with modified machines. Do your 48K machines use standard M1NOT circuit, or a modified implementation? I am no expert on this, but I would guess EightyOne is emulating the basic circuit
To be clear:
* the routine builds HFILE with each line beginning with CD9640, followed by 256 bits of 0 (32 bytes of 00). During runtime it does not modify the CD9640
* No other values are in the range where bit 6 is high are used. The demo (and the original Z-Xtricator game) change the 00 bytes to draw characters on-screen. It uses standard ZX81 character set characters. For example, to draw the custom spriteThese are all standard CHR$: 01, 02, 08, 2A, 3D, 80 and 87. The EXTRICATOR routine changes the characters per-scanline, while the ROM routine uses the same character for eight scanlinesCode: Select all
;SHIP sprite 3x8 bytes ;Rendered from scan lines of $1E (standard) ROM patterns $1E00+nn*8+l ' ' //000000 ;00000000 00000000 00000000 00 00 00 ' ' 0 scan line ' ' //000000 ;00000000 00000000 00000000 00 00 00 ' ' 1 '¢¡ ' //020100 ;00001111 11110000 00000000 0F F0 00 ' ±±±±±±±± ' 2 'EX ' //2A3D00 ;01111100 00011000 00000000 7A 0A 00 ' ±±±±± ±± ' 3 2A:$1E00+$2A*8+3=($1E53)=$7C/01111100 '±±¤' //808004 ;11111111 11111111 11110000 FF FF F0 '±±±±±±±±±±±±±±±±±±±± ' 4 '±±¤' //808004 ;11111111 11111111 11110000 FF FF F0 '±±±±±±±±±±±±±±±±±±±± ' 5 '±± ' //808000 ;11111111 11111111 00000000 FF FF 00 '±±±±±±±±±±±±±±±± ' 6 '¥± ' //878000 ;00001111 11111111 00000000 0F FF 00 ' ±±±±±±±±±±±± ' 7 CHR BYTES BYTES (BINARY) scanlines '01234567 bits 01234567'
But the problem is (maybe) the IM2 mode: if an interrupt occurs, the Z80 reads (during INTACK cycle in IM2) a data byte form data bus. This databyte is used as an interrupt vector pointing to a jumpaddress of the correspondig interrupt routine (*). If data bus is floating during INTACK (probably at a "naked" ZX81), Z80 reads probably $FF as interrupt vector. This might be different on my machines (data bus not floating), resulting in a jump to anywhere ...
Siggi
(*) This databyte is intended to be generated by an interrupting device (e. g. a PIO or SIO) to give a fast interrupt response to process PIO or SIO data as fast as possible ...
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
http://zx81.ddns.net/ZxTeaM
Re: Demo of XTRICATOR Pseudo-UDG driver
Rigter says the "idle data bus is FF". Using the debugger I find no way to verify that on a running machine. Maybe there is a way to test it?
Your comments have opened my eyes and I see a faint vision here ... the questions about how this code all works is beginning to make sense
From the Zilog Z80 Family CPU User Manual
The I register is set to $40 by EXTRICATOR initialization. But what is (or what sets) the least-significant-byte of the interrupt service routine?The IM 2 instruction sets the vectored interrupt mode 2. This mode allows an indirect call to any memory location by an 8-bit vector supplied from the peripheral device. This vector then becomes the least-significant eight bits of the indirect pointer, while the I register in the CPU provides the most significant eight bits. This address points to an address in a vector table that is the starting address for the interrupt service routine.
Rigter comments
That comment has made no sense to me, as $4000 is the system variables, and is not a service routine. I was thinking that EXTRICATOR is the service routine, and it is accessed by the CALL $4096 embedded after the HALT in each line of the H-FILESince the idle data bus is FF and the I register is set to 40, the INT vector is 4000 when the A6 line interrupts at the end of the horizontal line.
But now ... I see there is a table (table from $4000-40FF). And that only one value in this table matters. No matter if the beginning of the table is used for some unrelated purpose
Code: Select all
L40FF: dw $4082
That lines up. $40FF is the pointer, $4082 is the start of EXTRICATOR. I used the debugger in EightyOne and see that when execution starts at $4082, the previous opcode was HALTSince the idle data bus is FF ... when the A6 line interrupts at the end of the horizontal line
02BA JP (HL)
C32D HALT
4082 POP HL
Does this mean the EXTRICATOR is piggy-backing on the standard display routine? C32D is exactly 8000 higher than DFILE, which is at 432D in demo_48K_M1
Re: Demo of XTRICATOR Pseudo-UDG driver
This is such an interesting tutorial.
Thank you very much to the author !
Thank you very much to the author !
Re: Demo of XTRICATOR Pseudo-UDG driver
Hi, I wrote the original routine back in ~1983.
Yes, all it does is "piggy-back" the standard display routine, which means no more memory needed than the 768 byte display unlike the extra 6K needed for other hi-res routines.
But it allows you to mix different character lines from each of eight character lines with ANY other character, hence my description as "pseudo-UDG" (it also allows the entire original character set to be displayed normally, which is a huge advantage over other hi-res available at the time)
This enabled the fast line scrolling mountains in Z-Xtricator for example, and if I had managed to discover it at least a year earlier I would have made a fortune with a perfect hi-res chess program for the ZX81 and many other games that look great with pseudo-UDG
Re: Demo of XTRICATOR Pseudo-UDG driver
Thank you escher. It has expanded my view of the ZX81
escher wrote: ↑Tue Apr 01, 2025 9:41 pmHi, I wrote the original routine back in ~1983.
Yes, all it does is "piggy-back" the standard display routine, which means no more memory needed than the 768 byte display unlike the extra 6K needed for other hi-res routines.
But it allows you to mix different character lines from each of eight character lines with ANY other character, hence my description as "pseudo-UDG" (it also allows the entire original character set to be displayed normally, which is a huge advantage over other hi-res available at the time)
This enabled the fast line scrolling mountains in Z-Xtricator for example, and if I had managed to discover it at least a year earlier I would have made a fortune with a perfect hi-res chess program for the ZX81 and many other games that look great with pseudo-UDG