New Plasma effect for TMS9918

Página 1/3
| 2 | 3

Por jblang

Rookie (29)

imagem de jblang

06-09-2020, 21:05

I have written a new plasma demo for TMS9918. I thought that Plascii Petsma by Cruzer/Camelot had one of the nicest looking plasma effects I've seen, and he included source, so I've ported it from C64 to the Z80/TMS9918. Here is a video of it running on my RC2014 homebrew computer with the TMS9918A video card I designed. I'm getting solid 60 fps on 10 MHz Z80, and 30fps when the clock is slowed down to MSX speeds. I followed the high-level structure of the original C64 code where it made sense, but obviously the low-level code is completely rewritten since it's on a Z80 instead of 6502. Also, rather than PETSCII characters, I've used the gradient tiles from the plasma effect in Produkthandler Kom Her. On top of this, I have added the following interactive features:

- change the palette independent of the effect
- hold a particular effect on screen indefinitely
- switch immediately to a new effect
- runtime generation of random effects
- adjust parameters to customize an effect

Translating 6502 to Z80 as efficiently as possible was an interesting exercise. The lack of indexed indirect mode made it pretty tricky sometimes. I tried to play to the Z80's strengths when I could. I keep almost everything in registers and use the alternate register set extensively. The speed code is composed entirely of one byte instructions and the only things held in memory are the input and output arrays.

A lot of the complexity in Plascii Petsma's code was because he didn't want to use a custom character set. Since I didn't have this self-imposed restriction, I was able to remove that code and just calculate the tile names directly from the sine table.

I'm using the TMS9918A's Graphics I mode, which is similar to the VIC-II's extended color mode used by the original demo, except there's no separate foreground color, so I only have to do one write per tile instead of two. Since the TMS9918 has separate video ram, the name table is written to a back buffer in main ram and copied to the screen during vsync.

I confirmed that the basic demo runs on OpenMSX (I don't have a real MSX to test on) and cycles through the preconfigured effects. The interactive features don't work yet. I'm using the CP/M BDOS 06H function for keyboard polling. My understanding is this should be compatible with MSX-DOS but it's not working. I will have to research why. Also seeing a bit of tearing. On the RC2014 I was polling the interrupt flag and intentionally insert delays between VDP writes. Maybe on a real MSX this is too slow and I need to use interrupts and a faster VRAM copy function.

Any ideas about about why keyboard input is not working on MSX?

Entrar ou registrar-se para comentar

Por Pencioner

Scribe (1172)

imagem de Pencioner

06-09-2020, 21:35

Very nice video Smile I guess I'm gonna take my MSX1 back from shelf to see it live Smile

If you have your own interrupts handler which doesn't call default handler - BDOS function wouldn't work because it uses the keypress buffer which is populated by default BIOS interrupt handler. In this case you have to read keyboard matrix directly

The timing of Z80 commads on MSX is a little bit different - it has an extra wait cycle for M1 cycle (i think it adds up 1 cycle for regular commands and 2 extra cycles for IX/IY register commands if i remember that correctly). I don't know how much original code depends on timing, but this might be a reason for tearing

Por jblang

Rookie (29)

imagem de jblang

06-09-2020, 22:22

Thanks! Let me know how it works on the real thing. To save you the trouble of assembling it, you can get the binary here. The MSX was never common here in the US so it is difficult to get my hands on a real one. However, with my video card, YM2149 sound card, and emulated MSX keyboard, it's possible to run MSX-BASIC and some other MSX software on my RC2014, such as the Bold demo by dvik/joyrex.

I am not using any interrupts currently. I am just polling the vsync interupt bit on the TMS9918. It was easier to do this because on my video card, VDP interrupt can be connected via jumpers as either INT (used on MSX) or NMI (used on ColecoVision), and it was easier to just use polling so that the software can work without modification regardless of how the user has their hardware configured.

But since TMS9918 interrupts are disabled completely by my code, I guess the MSX doesn't have any other interrupt source to trigger the keyboard handling... maybe this is why I don't get any input.

Regarding timing, I am using a function with a delay loop to prevent writes to the VDP more than every 8 us. For a 10MHz Z80 the timing with a single iteration of this loop is just about right and more iterations can be added for faster speeds (e.g. using 18MHz or 36MHz Z180). However, for slower speeds this is probably not fast enough to allow the entire name table to be copied during vblank and therefore it tears because the write wasn't finished before the active display began. I may have to use a compile time option to enable interrupts and use a faster copy function for the MSX.

Por jblang

Rookie (29)

imagem de jblang

07-09-2020, 01:00

Enabling interrupts has fixed the problems. Thanks for the pointer. Now my program processes input correctly and the tearing is gone. I wrote an interrupt handler especially for MSX that uses a faster loop to copy the nametable to vram. There is an MSX equate at the top of the source, which when set to 1 will assemble a special version for MSX.

The remaining problem is that I don't know how to reinitialize text mode when returning to MSX-DOS. Pressing q does return to DOS but the screen is left in graphics mode. You won't be able to see the DOS prompt, but you can blindly type "mode 40" to restore text mode. I tried calling the INITXT BIOS function but this didn't work. Apparently that only restores the registers to text mode, but doesn't reload the pattern table.

Por lintweaker

Champion (307)

imagem de lintweaker

07-09-2020, 07:47

Very nice, never knew a TMS9918 could do that :-)

This quick peace of code you can use to restore to screen 0 on exit on msx:

CHGMOD	equ	05fh
CALSLT	equ	01ch
EXPSLT	equ	0fcc1h

 ld  a,0
 ld ix,CHGMOD
 ld iy,(EXPSLT-1)
 call CALSLT

Por NYYRIKKI

Enlighted (5595)

imagem de NYYRIKKI

07-09-2020, 09:20

This will return the screen mode to same as it was on start of the program:

	ld a,(#fcb0)
	rst #30
	db #80
	dw #5f
	ret

Por santiontanon

Paragon (1092)

imagem de santiontanon

07-09-2020, 10:05

Wow, that's amazing!! very cool!

Por Sandy Brand

Master (196)

imagem de Sandy Brand

07-09-2020, 11:39

That looks really cool! Smile

Por jblang

Rookie (29)

imagem de jblang

07-09-2020, 15:48

Are these code snippets to change back to text mode supposed to work on MSX 1? I tried both and neither worked. The first one just hung and the second one caused the machine to halt.

Por lintweaker

Champion (307)

imagem de lintweaker

07-09-2020, 17:36

jblang wrote:

Are these code snippets to change back to text mode supposed to work on MSX 1? I tried both and neither worked. The first one just hung and the second one caused the machine to halt.

Should work from MSX-DOS. Or are you running this from CP/M?

Por jblang

Rookie (29)

imagem de jblang

07-09-2020, 18:59

I'm running the MSX version on MSX-DOS 1.03 in OpenMSX, configured as a Philips VG 8020/20 with a Sony HBD-F1 disk.

When I am running it on my RC2014 hardware, it runs on CP/M, but in that case, the serial port is used for the text console so I don't care about text mode on the TMS9918.

Página 1/3
| 2 | 3