Friday, 22 January 2016

Sound, video, DMA; more bring up

Construction of the MAXI09 is continuing. With each part soldered onto the board comes a limited amount of testing with the monitor. Enough to exercise the very basic level of functionality, nothing more. Proper testing, and actually making the part do cool things, will come later.

The first part added was the OPL2:


Since this was previously prototyped on breadboard I didn't foresee any problems, and sure enough there weren't any, save for a strange problem with the 3.5mm mono socket. I had assumed that I could still use a stereo plug, with the sound coming out of both channels. But instead I got a sound mostly consisting of fuzz. I have solved the problem by using a splitter cable, between my PC speakers and the MAXI09, but it would be nice to understand what's going on. Testing was done by sending the simplest stream of register writes that will play a tone.

The next parts to be attached was the keyboard controller section:


As you can see, the RGB LED is not yet soldered. After soldering it was time to test that the QUART could talk to the controller. I did this by modifying the AVR controller code to output the scancodes as a stream of bytes instead of printable characters, and writing a routine in the monitor to print this stream as bytes are received from the keyboard controller port, Port D in the QUART. It was a big relief to see this working. MAXI09 will have a nice keyboard!

I haven't yet tested comms the other way. This will be needed to control the RGB LED, and possibly configure key repeat parameters, though I may decide to implement that in the MPU. Nor have I made the controller code process these messages.

Continuing on with the QUART, the next step was to attach the RJ45 serial ports and the accompanying MAX238 (PDF):


After the problems I had with the previous board's RS232 level serial ports, and despite all the checking I'd done on the MAXI09 schematic, I still did not expect these ports to work. But strangely enough, both ports work flawlessly. I have since switched to using an RJ45 port as the main console port, since it's use does not require fiddling with the small wires at the end of the USB TTL serial converter lead.

At some point in the design of the PCB I made a small blunder. Somehow I hadn't noticed that I'd used the footprint for a very small buzzer. Like the previous board MAXI09 includes a buzzer, this time attached to the DISCo FPGA. But this time I accidentally chose a footprint for a 7mm buzzer instead of the 12mm ones used before. This was especially irritating since I have at least a dozen 12mm buzzers in my parts drawer. The solution was simple though and I sourced some 7mm buzzers from eBay. Unfortunately the results are not great; these buzzers are not very loud. I thought it might be weak drivers in the FPGA, but the 12mm buzzer sounded just fine on the old FPGA breadboard. It's not a big problem though I do wish I'd used the correct footprint.

The final bit, for now, of hardware assembly involved the V9958 VDC:


Though I have a reasonable level of experience with this part, I was still a little apprehensive about the transistor amplifier section. The only difficulty I encountered was in soldering the actual transistors. The TO-92 footprint I used had the 3 terminals in a line. This made soldering them needlessly difficult with the chisel tip that was fine for soldering the rest of the board. Next time I will use a footprint with splayed pads.

Once the construction was completed, and the ICs inserted into their sockets, all that was left to do was modify MuDdy's VHDL to get it to generate the /VDCREAD and /VDCWRITE signals, and modify the monitor to look for the VDC at its new IO address.

The first thing I tried worked first time - my old Snake game. I had to modify the game to read the joystick position from the new joystick port instead of reading it from the old AY-8912, but otherwise the game code is unchanged from before.

I am very happy and relieved that MAXI09 has working sound, video and keyboard!

There remains some more hardware work to be done but before getting on with that I have made a start at the task of implementing the DMA Controller. I previously, about a year ago now, hacked a DMAC into the old board, with reasonable results. With the resources available in the EPF10K10 (PDF) I have now got a fairly useful DMAC implemented in MuDdy.

Because I have not yet tackled the MMU, my DMAC is currently, just like the rest of the computer, limited to the MPUs 16 bit address space. The following features are available:
  • 16 bit (arbitrary) source, destination and length registers
  • Increment control on source and destination
  • Invert source before writing (not very useful but fun)
  • Write only, don't read
The bits in the flags register are currently arranged as follows:
  • 7-4 Unused
  • 3 Write only
  • 2 Negate source
  • 1 Increment destination
  • 0 Increment source
The main purpose of the write only facility is to make the DMAC efficient at clearing memory.

Here's a screenshot of the DMAC being exercised to copy a grand total of 16 byes, from EEPROM to RAM:


First the original, pre DMA transfer, source and destination memory blocks are dumped out. Then the source, destination and length registers are set up. Finally the flags register is written to, which triggers the transfer. After its completed the MPU is un-halted and execution resumes. The new destination memory block is dumped out, showing that the transfer has been successful.

Perhaps more interesting is a look at the key signals in the system whilst this is going on:


This shows the E clock, /HALT, BA, BS MPU lines, as well as /READ and /WRITE as generated by MuDdy. When BA and BS are high, the MPU has relinquished the busses and the DMA Controller can begin reading and writing bytes. The machine cycles before and after the DMA transfer is occurring are "dead" cycles; neither the MPU or the DMA Controller are owning the busses. This is an unfortunate facet of how the 6809 manages the busses.

The speed of the transfer is a byte copied every two machine cycles, or one cycle if the controller is only filling memory. This is significantly faster then 6809 code could carry out the same task.

Whilst working on the construction of the MAXI09 board, I found another weakness in the circuit. I had planned to be able to swap in a 6309 at some point, so I could experiment with the part. However, after I'd submitted the PCB design for manufacture, I found a small but significant difference between the 6309 and 6809: the EXTAL pin, when the MPU is being clocked by an external oscillator, needs to be left floating instead of being tied to ground as it is with the 6809. If I'd know this I would have included a jumper between the pin and ground. Whilst there are "dirty" workarounds for this problem, such as pin removal, I think I will stick to using the 6809 in the board.

I'm now in the process of tidying up my somewhat rushed VHDL. One of the things I have struggled with is writing "nice" designs, designs which aren't riddled with cut and paste and other nasties. I'm getting there though. Hopefully soon it will be presentable enough to put on github...