V9958 80x24 Console

A project log for rosco_m68k

A full-featured Motorola 68k retro computer, starring a 68010 running at 10MHz

Ross BamfordRoss Bamford 07/08/2020 at 21:564 Comments

Now that the V9958 video board is shipping on Tindie, and I've gotten fresh stock of all the options for the base board, I've been working on getting a basic text mode console supported by the standard firmware. It took me a while to get used to the way the V9958 works, but thanks to the pretty great Yamaha documentation that's still available online (link for V9938, the V9958 documentation just lists the changes) it wasn't too difficult to make something work.

Here's a shot of it running Jeff Tranter's adventure, with the unmodified code that runs on the board without video connected.

(Sadly I don't currently have a CRT to run it on, but I'm working on that!)

Getting this working in the firmware in a way that was compatible with the current revision 1 board presented two challenges - firstly, I had to write the code for the console, including taking care of scrolling and tracking cursor position etc, and secondly I had to somehow find a way to get the code to fit in the severely-limited 16KB of ROM (a good chunk of which is taken up by the Kermit routines already). 

The first challenge was writing the code. I'd already done some examples and proof-of-concept / demo code for the V9958, including a naive text-mode console demo that basically redrew the whole screen during the vertical blanking interval.

While this worked, it made the VBLANK take so long that there wasn't time for the computer to do anything else! Obviously it was fine as a demo (and let me figure out the basics of the V9958's TEXT2 mode) but for something general purpose that would go into the firmware a better way was needed.

The result of this work was the second text-mode console demo, which is much more efficient, and has a VBLANK that runs in a timely fashion. The general approach here is:

With this scheme, the VBLANK handler usually does nothing much (except handle the blinking cursor). When the time comes to scroll the screen, non-interrupt code does the following:

With that done, next time there's a VBLANK, the handler just flips the pages (by setting the appropriate V9958 register with the new active page start), which again takes very little time.

Obviously it's slightly more involved (handling backspace characters and so on) but that's the basic gist of it, and I have to say I'm pretty happy with it. It works really well, scrolls nicely with no visual tearing or other artefacts, and means that there's never a long-running interrupt handler starving the rest of the system. The use of two VRAM pages means you never see a half-scrolled screen.

did play around with using the V9958s blitter commands (which are available in text modes, unlike on the 9938) but the timing was a nightmare, and the fact that the commands haven't really been updated (and so one has to translate coordinates to their graphics mode equivalents, for example) made it not worth the effort. I may yet revisit this in the future, but as I say, it works and I'm happy with how it turned out.

The next challenge was making it fit in the ROMs. The 16KB ROMs I (short-sightedly) used for the revision one boards were already pretty full, and I definitely didn't want to lose any of the existing functionality - the idea here is to make a new minor revision of the firmware that is a drop in replacement, but also detects and uses the V9958 if fitted.

I played around with a few different ideas, and eventually settled on splitting the firmware into two stages - stage one would handle the basic machine initialisation (including the V9958) and provide the resident ROM code and TRAP handlers (both TRAP 14 which is rosco_m68k basic IO and TRAP 15 which provides Easy68k compatibility). Stage two would take care of loading user programs (via Kermit at the moment, though with this split it can be easily replaced with code to load via SD card, for example, which we're already working towards).

How does this save any ROM space? That's the clever bit - stage 2 is compressed (with a simple Zip-based algorithm). Once the basic machine is initialised, stage one unzips stage two into RAM, and runs it from there. 

The Zip algorithm doesn't give super high compression ratios, and is optimised for size in the decompression code (otherwise the advantage of using compression would be lost), but it's good enough to fit everything that was previously in the firmware, plus the V9958 code and a text-mode font (which currently isn't, but could easily be, compressed too - at the moment it just lives alongside the V9958 code itself, which has to be in stage one so it's always available in ROM).

There's still some scope for saving a few bytes (which I'm hoping to use to provide a similar "pluggable" interface for the UART, to allow it to auto-detect the coming-soon MC68681 expansion board) but overall it works quite nicely, and is available in the current development branch for the new firmware (I'll try to remember to update here once it's actually released!)


zpekic wrote 11/04/2022 at 23:15 point

Great project using this interesting VDP. If you ever feel like converting its signals to VGA display...

  Are you sure? yes | no

Stephen Moody wrote 11/02/2022 at 16:00 point

The V9958 is a nice chip, used it as a video card on a 68000 computer i'm working on.

I still need to do a lot of work on it, Have a buffer with the full screen contents in it. Cursor is handled in a timer and character written in place when key pressed. Scrolling is handled when the buffer overflows and all the lines are moved up, then the entire buffer is copied to the screen. Does cause some issues but it works fairly weell. Using the VBLANK woudl make this a lot better more seamless and fix some of the scrolling artifacts.

@caiannello. When doing the code for my board I used C initially and it was very hit and miss on the results. I had to switch to assembler to control the timings and diable the interrupts when copying the entire page.

  Are you sure? yes | no

caiannello wrote 11/02/2022 at 17:24 point

I had a similar experience, except I was experimenting in A stripped-down version of Microsoft Extended BASIC for 6809 (from the old TRS-80 Color Computer 3), and moving things over into the ROM, as I got them working, using 6309 assembly. Some things, like setting palette registers in VRAM, just NEVER worked consistently in BASIC, but they did work once coded in assembly.  I don't think this implementation of BASIC uses interrupts for anything, but my ROM firmware will, so that's good to know.  Good luck with your project, and geek on! -Craig

  Are you sure? yes | no

caiannello wrote 11/02/2022 at 13:46 point

I love this project! Thank you for documenting this, it has been extremely useful while trying to get a V9958 working in a homebrew 6309 system. 
I wanted to mention that I was able to replace the six DRAM chips of a typical V9958 system with one SRAM and one latch, wired as one might expect, and using part of a ATF16V8B PAL to generate the chip select and latch signals based on the /CAS0..X, /RAS, R/W, etc., from the VDP. 
I think it at least mostly working, as it was able to do 80-column text per your console demo (no scrolling or vblank stuff yet)  and also drew a 256-color Mandelbrot in 256x212.
I say "mostly working" because it is very sensitive to timing and the initialization order of VDP registers. Not sure how much of this is caused by the SRAM stuff, or if its all just the way the V9958 is. 
Anyway, thanks again for documenting this! I'm hoping to return the favor once my stuff is further along. 

  Are you sure? yes | no