Demo of XTRICATOR Pseudo-UDG driver

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
User avatar
siggi
Posts: 1043
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by siggi »

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
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
David G
Posts: 632
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by David G »

Does IM2 require special things (like a floating data bus during reading the interrupt vector)?
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 special

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'
These 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 scanlines
User avatar
siggi
Posts: 1043
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by siggi »

David G wrote: Thu Nov 21, 2024 8:07 pm
Does IM2 require special things (like a floating data bus during reading the interrupt vector)?
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 special

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'
These 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 scanlines
My Zeddies use a "standard" M1NOT logic.

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
David G
Posts: 632
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by David G »

siggi wrote: Thu Nov 21, 2024 8:29 pm Z80 reads probably $FF as interrupt vector. This might be different on my machines (data bus not floating), resulting in a jump to anywhere ...
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 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.
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?

Rigter comments
Since 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.
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-FILE

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
 
I found that it doesn't work if this exact value is not at this exact address. Now i'm thinking that $40FF is the address in the vector table that is the starting address for the interrupt service routine
Since the idle data bus is FF ... when the A6 line interrupts at the end of the horizontal line
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 HALT

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
ChrisB
Posts: 31
Joined: Tue Dec 17, 2024 8:53 am
Location: France

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by ChrisB »

This is such an interesting tutorial.
Thank you very much to the author !
escher
Posts: 20
Joined: Thu May 12, 2011 7:31 pm

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by escher »

David G wrote: Sat Nov 23, 2024 8:31 am 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
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
David G
Posts: 632
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Demo of XTRICATOR Pseudo-UDG driver

Post by David G »

Thank you escher. It has expanded my view of the ZX81
escher wrote: Tue Apr 01, 2025 9:41 pm
David G wrote: Sat Nov 23, 2024 8:31 am 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
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
Post Reply