I'd been putting this project off for a while because it is very complicated to get fully working and I have no known-good firmware specifically for it. I considered porting a monitor but a BASIC interpreter would be more impressive. Grant Searle's minimalist 6809 design has Microsoft BASIC and the same 6850 ACIA serial chip. I would still need to reassemble the firmware source code with different addresses for this chip.
Grant's source code uses Motorola style. Comments begin with an asterisk instead of a semicolon, or not at all if there is enough for the assembler to make valid instruction bytes already.
The assembler I use (https://www.asm80.com) uses the most common syntax it can for all processors. So I had to do a lot of editing to get it to assemble, and it is still not generating a hexfile identical to the one from Grant's site.
It occurred to me that I could program the GAL chips to put the memory map the same at Grant's design. I can then use Grant's ROM unmodified. Also, I don't have to get everything working at once. Just the CPU and serial port at first. Then the STEbus, which requires cycle stretching. The tricky bit is getting it back in sync with the ACIA and PTM chips, which require fixed cycle times.
If that proves too difficult for me then I may replace them with chips that have independent clocks, such as a real-time clock that can interrupt the CPU every second (for OS/9 and Flex operating systems), and the Zilog SCC which is a far more powerful serial chip.
Finally, I might also replace the serial chip with a USB module from FTDI. These have a really simple FIFO-like interface, and avoid the need for external RS323 to USB converter cables.
Inserting jumper links, I notice the manual and circuit diagram are both version 1 issue 5, applying to version 1 issue 2 boards. I have a version 1 issue 1 board, lacking link areas J21 and J22. I can work around the differences.
Finished porting Grant's code to use the online assembler syntax. Found one error, and other errors due to operator precedence which were fixed by brackets. Original source was all upper case, which make sense if the host machine only has upper case e.g. the 6809 CoCo and Dragon.
Had a look at some other 6809 machines to see what their memory maps look like. E.g. the CoCo, Dragon, and Acorn 6809 card. Looks like operating systems really need a counter/timer to interrupt them at least once per second. The CoCo and Dragon don't have this but seem to manage without. The Arcom SC09 has a 6850 programmable timer module. The Acorn 6809 card has a 6522 which can generate interrupts and as a bonus provide parallel I/O for driving a printer.
I think a proper real-time clock would be better, providing interrupts and a useful clock/calendar.
Stage 1, first attempt at programmable logic tried. E and Q signals running at a quarter of master clock - correct. Address, data and control signals flapping away, indicating the CPU is running even if it is garbage. Nothing coming out the serial port, because the Timer chip needs to programming to drive the Tx/RX clock of the ACIA chip. Grant clocks his ACIA from the E signal, at 1.8432 MHz. My board has a 16 MHz crystal and 2 MHz E signal. I need either a separate baud rate clock or change the 16 MHz master crystal to a 14.7456 MHz crystal.
14.7456 MHz crystal fitted. 6840 timer chip removed and E wired to TX/RX clock pins. Still no sign-on message. Looks like I need to get the logic analyser out to see what the signals are actually doing.
Logic probe showed the TX line was not valid TTL voltage. It was 0.9 volts. Dead buffer? Removed buffer, it raised to 5V. Replaced buffer, still 5V. Had it been in the wrong way round? Check the photo, yes it had. And my +/-12 source was dead.
Read and Write signals modified. Memory system runs in "early write" mode, R/!W lines set up before data is strobed in/out by the Chip Select signal. Now seems to be running instructions, reading the ACIA every 15.5 microseconds.
Sometimes it looks like it is running plausibly (reading ACIA regularly) and sometimes it looks like it is reading a block of ACIA accesses. CS1=A9 is a 1800 Hz square wave. Suspiciously regular, and also equal to 14.7456 MHz divided by 8192. Is this running NOP codes? All the address lines are square waves so it looks like the case. Put probes on RAM CS, ROM CS, A15. Straight away I saw that ROM is selected when A15 is low, RAM is selected in the top half of A15 high (A15 and A14 high). I've got the ROM and RAM pins swapped inside the GAL equations! It is a mistake but one that is easily spotted and fixed.
Scoping the data lines shows the data bus is hi-z when the RAM is addressed (A15 low) and A13 is low. Realised I have an 8K RAM fitted (pin 26 is enable high not A13). Fitted a 32K RAM which fixes that issue. Still just cycling through addresses though. The data bus is seeing bytes that are varied, which should produce some kind of irregular garbage program. Maybe the /RD line rises too soon after E falls. Looks almost simultaneous on scope. Minimum data hold time after E falling edge is 10ns for MC68B09E, 20ns for the HD63C09E. The RAM chip turn-off time is 0 to 35ns. I currently have !RD and !WR clocked, so they change on the same clock edge as E. I shall check the data bus hold timings tomorrow.
Still not starting reliably, often goes into a mode that looks like running a memory space full of nop codes. But it often looks like it is running the code that polls the 6850 ACIA, which is a lot more promising than it was a few days ago. It never actually responds to any characters though. I am driving the Tx/Rx clocks at the CPU clock speed of 1.8432 MHz, and should be working at 115200 baud. Maybe I have a duff 6850? I have ordered another.
I am inclined to change the design to use a FT245BL chip instead. These are more modern and easier to obtain. The price is about £5, which is similar or better than the increasingly rare 68B50 chips.
Replacement 68B50 has not improved things, so I don't think the serial chips are faulty. To test the firmware, I have ordered a PCB for the Grant Searle design as a known-good reference. It take less time to earn the money to buy one than to make one.
The Grant Searle board I bought had a serial port header incompatible with the FTDI cable, so I had to make up an adaptor and experiment to find the right connections. Along the way, it would look as if the whole board was malfunctioning, with characters completely or partly mangled.
I managed to get it working fairly well when plugged into the STEbus board (via wire wrap socket and DIL header plug) and drawing power from it. I used a 6809E, where Searle's board expected a 6809, but the STEbus board drives the E and Q signals so no problem.
Characters echoed to the terminal were often wrong, but had been received correctly because they were correct when listed. So reading the ACIA is reliable but writing to it is not.
I tried the Searle board with a 6809 running detached from the STEbus board. It now runs very robustly, all characters correct. This is good, as it proves it is a known-good system. It also tells me that the STEbus board has problems that are not related to memory/UART control signal timing because these are on the Searle board instead. Perhaps the bus capacitance is too much, or there is a component driving the bus when it should not. I think the next step is to depopulate the STEbus board until only the culprit remains. Which may be the PCB itself.
Discovered the missing characters were due to the FTDI cable sending up to 3 characters after CTS high, and the 6850 has only one byte of buffer. So copy-and-paste is never going to work. Apart from this, the Searle board is working well when plugged into the STEbus board. Now to move chips back to the main board until the system fails.
Moving the memory chips causes no problems, so it looks like my GAL equations for memory select signals are correct. Which leaves only the 6850 UART. My guess is the previous problems were due to handshaking issues. If wrong, communications may not work at all and look exactly as if the whole system is dead.
Next step is to wire the STEbus board UART to the FTDI cable in exactly the same way as the Searle board, and see if that works.
Meanwhile I will leave it running a "Hello World! " loop as a soak test.
Managed to get communications going with the 6850 on the main board but only when the Searle board is holding the 6809. There are no chips on it, so it must be some passive components pulling pins. Now it is just a matter of finding out which ones make the difference between working and not working.
Got it to start up without the Searle board - once. Haven't found out the magic solution. The reset circuit is producing a correct reset pulse. The tantalum reset capacitor was the right value.
Replaced CPU socket with a turned-pin socket. Added extra pull-up resistors, and a HCT04 to invert /IRQ to drive /CTS. No improvement. HCT04 getting hot despite spare inputs tied to 5V.
Snipping the extra components off the Searle board did not cause the system to fail, nor did adding them to the main board fix the problem. Maybe the extra capacitance of the Searle board is holding the data bus values for a little bit longer. The read cycle data minimum hold time is 10 ns for 68B09E and 20 ns for HD63C09E is abut the same as a logic gate or two. The Searle board has two 74LS00 NAND gate delays of 9 (typ) to 15 (max) ns. No minimum stated on data sheet. The HM62256LP-10 RAM has 0 to 50 ns turn-off time. The Winbond W27E257-12 EEPROM has 50 ns max but no minimum time to go hi-z. So Searle's circuit has should hold the chip select lines for 18 ns typically which is enough for a MC68B09E but not a HD63C09E. I'm using two ATF22V16CZ-15 GAL chips which have 3 to 15 ns delay. So worst case, I have 6 ns chip-select hold time. I could try adding a small RC delay. Maybe 470R-180pF to start with. 0.7*RC=59ns. A 16 MHz system clock rate has a 62.5 ns cycle, so perhaps I could delay it that way.
The board was designed in the late 1980s, so PAL and memory chips would have been slower then. I could try lower-speed memory chips.
The board was given to me as a scrapper, i.e. the test department couldn't figure out what was wrong with it in an economical amount of time. So checking for track breaks and shorts is worthwhile. The vias have holes that are not well-centred in their pads. While replacing the CPU socket, I checked the tracks were intact. Buzzing out the board will be time consuming but quicker than having to wire wrap one.
Thanks to a tip-off from a Facebook page, I now have reliable sign-on message. Hurrah! Handshaking inverter (HCT04) dead, but the board works if I turn handshaking off. Equations modified were:
MEM_READ = CPU_RNW & !CPU_RESET;
MEM_WRITE = !CPU_RNW & !CPU_RESET & CPU_Q;
ANDing with Q makes the write signal end in the middle of E high, rather than at the end of E high when there is very little data-holding time.
Handshake buffer fixed, now running correctly. I now have several possible ways to tackle the missing characters.
The first is replace the 6850 with a UART that has at least a 3-byte receiver FIFO. I favour the 16C552, because it is still made, cheap, has two serial channels and a Centronics printer port. The latter can only drive very old printers but can be used as a simple parallel I/O port.
The second is to replace the UART with a USB module, to avoid baud-rate bottleneck and buffer overflow issue. This is the option I will ultimately choose.
The third option is to implement interrupt-driven character input. Incoming characters cause an interrupt, and the service routine puts characters in a buffer. The processor then collects characters from the buffer. I'm willing to have a go, as solving this issue would benefit others using the 6850 (e.g. those using Grant Searle's design).
At 115200 baud, I estimate about 11520 characters per second, 87 microseconds per character. Example code I have says it takes 112 cycles to service an input interrupt, 148 cycles to service an output interrupt, 44 cycles to determine the interrupt is from another device. At 1.8432 MHz, that is 61 microseconds. So it is possible.
A look at Leventhal's routine revealed some serious flaws.
Firstly, when the buffer is full, it just discards characters, which is exactly what I want to avoid.
Secondly, it only detects when the buffer is completely full, so there is no room for the up-to-three characters the FTDI cable might send.
Thirdly, it does not operate any handshaking signals to tell the PC to stop sending characters when the buffer is full!
All the above does is changes the problem from a 1-byte buffer overflowing to an n-byte buffer overflowing.
At this point I feel it will be less work to replace the 6850 with a better device.
I found a chap called David Wood has made a 6809 board with a 68681 chip (see https://github.com/jbevren/6809v2). This has two channels, a crystal oscillator, a baud rate generator, a timer and some spare I/O pins.
The channels have 4-byte buffers, solving the FTDI cable problem.
The oscillator means I can give it a 3.684 MHz crystal and clock the CPU independently if I wish. I'm running it at 1.8432 MHz right now. The 63C09 is rated to 3 MHz but people have overclocked it to 3.684 MHz. The STEbus specifies a 16 MHz clock, so a 48 MHz oscillator is a multiple of 16 and 3. Division by 3 with 50% duty cycle is a little trickier than powers of two. 48 divided by 4 gives 12 MHz clock for 3 MHz CPU cycles. I could use 14.75 / 5 = 2.95 MHz to stay in rating. 16/5 = 3.2 MHz, 16/4 = 4 MHz.
The timer can be used for operating systems to get a regular interrupt. This means I can also discard the 6840 Programmable Timer Module.
Finally, the extra i/o pins can be used to manage an SD card containing an operating system!
So I have ordered one and will design a way to graft it into my project.
Circuit drawn, mostly D0-7 connections. Needs A0-3 so might be better plugged into a memory socket and the serial signals taken to 6-pin FTDI headers.
Ordered MC68681P from eBay.
Lashed up an adaptor to route D0-7 and ground to an FTDI FIFO modulehttps://www.waveshare.com/FT245-USB-FIFO-Board-mini.htm The control signals are on wires, to be soldered to interface logic and reset lines.
This is no harder than a 68681 adaptor, and it avoids the UART baud rate bottleneck.
I now have to design the logic to drive/read the control/status lines (read, write, transmit full, receiver empty) but that will be quicker for me to do than writing 68681 driver routines.
MC68681P from eBay arrives.
An unused SC09 just showed up on eBay! £80 starter price. I'll definitely be bidding for this and some other related bits. Auction ends tomorrow. If I win, reading the PAL chips will save me many hours of reverse engineering and I will be certain of having working logic. Thanks to Mike Miller for the tip-off on Facebook! I would have missed it otherwise.
Won the board and some other STE bus bits. No other bidders! Yay! Now the only hardware hack I have to design is a serial interface that I can copy-and-paste text at the terminal side. Time to cook a massive celebratory chicken curry! :-)
The goodies arrived today, well packaged and in mint condition. The project goal of having a working design is achieved, and the programmable logic can be read when I get a reader running. What next?
I can't transplant my Microsoft BASIC ROM directly, because the memory maps are not compatible. The I/O is at A000 in the Searle design, and at E000 in the SC09 design. The former allows simpler hardware, the latter allows bigger contiguous space for memory-hungry software like operating systems. The SC09 was designed with OS/9 in mind. So it is worth the effort of porting software to such a memory map.
First snag is that the SC09 uses a 4K ROM to boot, so either two ROMs are needed, or have two chip selects merged into one. The latter seems a better option.
Thinking about where to take the project next. I squeeze the most return from scarce personal time by making my projects hardware and software compatible with existing machines. The most common 6809 machines are the CoCo and the Dragon. Owners aspire to run NitrOS9. I now have a choice of porting software onto my board, or modifying my board to look like a CoCo/Dragon. The former needs to be done over and over again as new software is released, the latter only has to be done once. Cloning those machines would be a significantly different project. It would need the 6847 video chip, tightly-coupled memory for interleaved video access, fixed length memory cycles, etc. Such projects have already been done, and one can still buy real machines fairly easily.
An OS is useful for talking to storage devices and loading applications from them, but I can see myself wanting to run applications like word processors or spreadsheets on an 8-bit machine. I would edit programs on my PC and simply paste them into a terminal. I can only see my boards doing operating small control systems. All the board needs to do is download a program and run it, and it does that already. The next step is to replace the 6850 with USB slave communications, and the project will be completed to my satisfaction for now.