A while back, I got a couple of VCB01 cards in a lot of other MicroVAX cards I wanted. The VCB01 was used in the VAXstation I and VAXstation II to provide simple graphics, and mouse and keyboard. This was referred to as QVSS graphics - Qbus Video Sub System. It's a relatively simple card - plugs into a Q22 bus, and has 256Kb of memory for screen memory, and a scan map that determines what lines are mapped where on the screen. And, like I said, it also supports a mouse and a keyboard. It displays one plane of monochrome. Not the most capable graphics card in the world, but, I got to wondering - could it work on a Micro-PDP11?. Micro PDP-11s have a Q22 bus - could the VCB01 provide graphics on a PDP-11? Graphics for RSX sounds interesting. A look at the VCB01 doccos didn't turn up anything that would prevent it from working.
I have a BA23 box test system that has a PDP-11/73, 1024KB of memory, an RD32 and assorted other options in it. I stuck the VCB01 in the box, after all the other cards on the bus - apparently the VCB01 can act funny with bus grants, so it gets to be last, where it can't screw up as much. I powered on the machine, and it went into its normal self test. Interrupting the self test lets me use the "M" command - display the hardware map. I saw all the usual things, CPU, memory, CSRs. I additionally now saw a new 256 KB area of memory at 16000000, and a set of 16 CSRs at 177200. Both of those are what's expected with a VCB01. So that's a good start - the hardware is visible to the system, and didn't look like it stepped on any of the other hardware already present.
Commands are Help, Boot, List, Setup, Map and Test.
Type a command then press the RETURN key: M
15.206 MHz
Memory Map
Starting Ending Size in CSR CSR Bus
Address address K Bytes address type type
00000000 - 03777776 1024 17772100 Parity Qbus
16000000 - 16777776 256 Qbus <------This is the 256K of VCB01 memory
I/O page Map
Starting Ending
Address address
17760440 - 17760456
17765000 - 17765776 CPU ROM or EEPROM
17772100 Memory CSR
17772150 - 17772152
17772200 - 17772276 Supervisor I and D PDR/PAR's
17772300 - 17772376 Kernel I and D PDR/PAR's
17772516 MMR3
17773000 - 17773776 CPU ROM
17774440 - 17774456
17774500 - 17774502
17776500 - 17776516
17777200 - 17777276 <----------------------------------These are the VCB01's 16 CSRs.
17777520 - 17777524 BCSR, PCR, BCR/BDR
17777546 Clock CSR
17777560 - 17777566 Console SLU
17777572 - 17777576 MMR0,1,2
17777600 - 17777676 User I and D PDR/PAR's
17777744 - 17777752 MSER, CCR, MREG, Hit/Miss
17777766 CPU Error
17777772 PIRQ
17777776 PSW
I booted RSX11M+, and it completed successfully. Man, was I surprised! RMD showed that RSX only knew about the usual 1024KB of memory - that's good, it didn't detect and try to use the 256KB on the VCB01, so I wouldnt have to fight with RSX over using it for graphics. So far, so good....time to hook up a monitor, I reckoned. I had an old DEC VR100 taking up (a lot) of space, left over from my old VAXstation 100, that was specced to be compatible with the video output of the VCB01. I hauled it out and and dusted it off. It turned on and displayed...well, not a raster, but some brightness on the screen, so I went to work making a cable from the DB15 on the VCB01 to the three BNC connectors on the monitor - Video, Horizontal Sync and Vertical Sync.
This took a while and a lot of experimentation. I hooked up an oscilloscope to the three outputs and saw that the video was present, but the sync signals were missing. Turns out that I really needed to program the 6845 CRT controller on the VCB01 before it would know what kind of sync to generate, and when. This looked like a complicated slug of calculations, about a page's worth, to get 16 values. This stuff looked like Buck Rogers math, so I looked for an example somewhere to copy from (I remember when the motto of DECUS was "steal from your friends"). I tried the values in the VAXstation 100 Architecture Manual, figuring, they'd be close. Some sync signals now showed up on the osillloscope, but no soap - nothing on the VR100 display. Totally nothing, actually, now not even the former bright glow it had before I hooked up the cables from the VCB01. Now I'm thinking, the VR100 is dead. No brightness on the screen. Was it damaged by the strange sync frequencies that were produced while I was trying to program the 16 values? That was apparently a problem thing, back in the day. I dunno. I'll have to dig into it and see what's wrong. Could just be a coincidence. Maybe an aged capacitor gave up the ghost right as I needed to use the monitor. Looks like I'l have to troubleshoot it like an old TV. But that's a project for another day. I pushed the deadly high voltage box of puzzles and surprises aside on the workbench, and looked for a substitute display. Josh Densch, a VAXstation 100 owner, pointed out that a NEC Multisync monitor would work, so I got a cheap one from Ebay. Apparently they will sync up to most anything, without blowing up.
So I hooked it up and had another go. Success! I got some more or less random patterns on the screen at power on, no doubt due to whatever random values were in the 256K of pixel RAM on the card. But the screen didn't look right, it was tearing and flashing and rolling - the sync clearly was still an issue.
Apparently, the 6845 has to be set just right before you get a usable display. For whatever reason, the VAXstation 100 values I had weren't doing the business. I tried a bunch of settings for similar graphics cards that used 6845s on hobby gear (back in the day, the 6845 was a popular hobby microcomputer CRT controller) - still no luck. I started looking for the sources to the QVSS driver from the MicroVAX, to copy the initializaion of the 6845 from, but, nothing to be found. I posted a query on the Vintage Computer DEC forum, and user Bitly provided the initialization values that QVSS uses, which turned out to be in the DECWindows sources. Thanks again, Bitly!. I plugged in those values, and, success! A more orderly pattern appreaed on the screen, still looking wild but no tearing and rolling. Here's what it looked like.
Why the VAXstation 100 Architecture values for its 6845 didn't work - another DEC history mystery.
Now that the display seems stable, it's onward to accessing it while running RSX. But this is a PDP-11. A task can only address 64KB, as 8 8KB chunks, at a time, using 16 bit addressing. You can't directly access the 128K of pixel space from a simple task. But we can access anywhere in the Q22 address space, by changing the mapping of a tasks' APRs - an address page register. A task's 8 APRs map the 8KB chunks of task logical space to the 22 bit space of the Q22 bus. I could map an 8KB chunk of a task's address space to 8KB chunks of the 128K of pixel memory on the VCB01 starting at physical address 16000000.
So I wrote the typical sort if task to test something like this - it's built as /PR privileged to give it access to the IO page, where the APRs live. The 256K of pixel memory is effectively a 1024X768 pixel array. Program setlin abstracts that as x,y values. When it comes time to write to the memory, it first converts the x,y coordinates to an index into the equivalent 98304 byte array, with the low 3 bits indicating which bit in the byte needs to be set. From there, we look up what value to enter in an APR to reach it. Then we switch to Kernel mode and put that value in KISAR6 (Kernel Instruction Space APR 6), to map the 8KB chunk that contains that byte. Why Kernel mode? Why KISAR6? It's what similar DEC utilties do. If you're interested, have a look at the code. I did a previous blog entry that does a poor job of describing mapping things via APR, have a look at that, or better yet, have a look at the RSX Task Builder manual to find out more.
In any case, now I can write programs that set bits by X,& coordinates on the screen (the upper left corner is 0,0. X increases to the left, and y increases going downward). Here's some examples.
OK, they aren't great art, but I don't have any ready to go drawing software for RSX.
Here are programs that zero out or set all the bits in the pixel memory. They write entire bytes instead of setting bits, in the interests of speeding things along.
This one zeroes out the pixel memory.
This program writes all ones to the pixel memory.
Here's a test program - it draws some boxes, and some lines. It addresses individual bits/pixels, has more logic in it than the above two. It draws the RSX11 banner and a grid.
These programs have to be assembled and linked...special, to find all the symbols and routines invovled. Here's the commands for setlin.mac as an example
mac setlin=[1,1]exemc.mlb/ml,[11,10]rsxmc/pa:1,[vcb01]setlin
hft setlin/pr/-cp=setlin,[3,54]rsxvec.stb/ss,[1,1]exelib.olb/lb
Here's the command files to assemble and link them
So, this is all middlin' interesting. One big problem, though, is that this is slower than Christmas. I mean S-L-O-W. You'd think it was coming in via 1200 baud modem. For some reason, it takes forever to draw something. Part of it is the test programs were not written to be fast - to write a pixel, you have to call several subroutines and do a $swstk for each one. Also I was experimenting with passing all args on the stack, instead of in registers. Doing dozens of pushes and pops for every bit set doesn't help speed things up. Hey, these are proof of concept test programs, not production grade. Ideally, this should be implemented as a driver (I'll get around to doing that). Maybe there's something wrong with my test system. But I wonder, if the VCB01 is just intrinsically slow on an 11, and that's the reason that it was never supported on 11s. Or it's bugs in the programs. Dunno yet. I want to get it running faster, so I can do some fun things, like using the pixel memory as a disk, and get to watch the blocks fly in and out on the screen. Or maybe as a swap disk, work files or task memory, like the classic Alan Frisbie story. As the story has it, he realized that an early memory mapped graphics display was being sold cheaper than just buying the memory it contained. He started running tasks out of that memory, and jokingly asked the manufacturer to add the ability to select what task to run next using the light pen.
Anyway, let me know if you give any of this a try. I'd love to hear about other results.