• Please review our updated Terms and Rules here

Z80 Intel hex loader

CP/M has LOAD.COM or HEXCOM.COM that will convert Intel HEX to binary, and there is also a GENHEX.COM (with source code) in MP/M that will convert a binary file to Intel HEX (you can specify the base address, too).

The reason one might use Intel HEX (as is still done by many DOWNLOAD functions today) is that it has error detection built-in. Otherwise, you'll need to build a protocol around the binary stream to be able to have any idea if the binary file resembles the original. Or else resign yourself to wondering when things don't work exactly as expected.
First thing I need to do is get the hardware & software to actually work. I'm still trying to nuke that issue out. I have some ideas about how I can troubleshoot it. I'm just going to have to get inventive.
CP/M has LOAD.COM or HEXCOM.COM that will convert Intel HEX to binary, and there is also a GENHEX.COM (with source code) in MP/M that will convert a binary file to Intel HEX (you can specify the base address, too).

The reason one might use Intel HEX (as is still done by many DOWNLOAD functions today) is that it has error detection built-in. Otherwise, you'll need to build a protocol around the binary stream to be able to have any idea if the binary file resembles the original. Or else resign yourself to wondering when things don't work exactly as expected.
Once having a reliable rs-232 connection, I've never had a bad or lost data, never. I did design an industrial setup and used rs-485. They were on power that started 5+ hp motors. I never bothered to even try rs-232.
At home, I've transferred many megabytes without issues. As for keep files, yes, that is different. Even text is worth having some type of check sum.
One common thing that keeps bnawing at me is that both of the ports on the card display the same results with any of the tests I have performed so far; failure to transmit, incorrect status data (85h & 84h) before and after an attempt to transmit, and obviously no data coming in (pins 2 & 3 tied together on the DB9 connector). One this that struck me last night is that the Clock that drives both 8251A chips is the 1.8432 MHz (divided down to 153 KHz for both XMT & RCV clocks at 16x), but the system bus clock is 2.00 MHZ. so I'm wondering if my issues could be that the clock that drives the CPU to do what is should, is not the same as the clock that drives the 8251A's to do what they do. All of the schematics I have for old S-100 boards that use the 8251A use the overall system clock and not a derived clock from what is used to set the baud rate.....
The Heath H8/H89 computers used the 8251 for the cassette interface (in async mode), and the early H8 console port was 8251. The code I have as an example is testing bit 0 of the status word and looping while that is '0', then outputs the character. That corresponds to your 85h and 84h, if I understand correctly those to be before and after sending a byte to the data port. In other words, this code checks TxRDY and ignores TxE.

We've also noticed some subtle differences between certain vintages/manufacturers of 8251. This affected the handling of external control pins and made certain models unusable for the cassette port. Just to make the point that not all 8251 are equal and there may be other differences not yet discovered.
Well, as I do not have a logic analyzer, I decided to build a little wrap around test circuit. A '374 to latch the output data to the serial port board, and a '244 to be able to read it back in. Both controlled by the same circuitry that controls the 8251A's. Turn out that there was a bad '245 bus transceiver on the serial card as the first problem. I'm now looking at a bit 6 being stuck low. Once I run that issue down and get it fixed, I suspect my code may just actually work; correctly. Imagine that, bad hardware causing the software to not function. But a good mental exercise none the less....
I highly recommend the SALAE Logic Analyzer on ebay - It goes up to all the speeds that will interest anyone working with z80 and costs about $10... Great value - I keep a few spare in the drawer in case I can't find one when I need it.

I don't see anything with the SALAE name on ebay for $10. Are you talking about one of those cheap knock-off things?
Well, I'm sure not seeing any for around $10. But even the cheap ones that use Sigrok might come in handy. Back before I retired, we used to have this beast called a RatTrap for 32 bit NTDS interface testing, I was thinking of something similar that would grab the state of the address buss, data bus, and all the control lines, on the rising or falling edge of each clock pulse. Clock pulse goes low, the data gets written, the clock goes high the next memory address is selected. But you'd need one huge amount of RAM to get a few seconds worth of data. But a fun project none the less. I continuity checked all the various paths and found no shorts. And I swapped out the two TIL-311 displays and the '374, so I suspect the input gate on the '244 for bit 6 may be shorted to ground. That is my next test tomorrow. I attached the test jig schematic I wired up to connect to the two 8251A's (removed for test).


  • Testv3.pdf
    15.7 KB · Views: 2
Hi Doug, Sorry, I meant SALEAE - I missed a character. Just searching SALEAE should bring up some of the logic analysers they make - or they might be knockoffs. They make much better ones lately, and I'll get one some time. The ones I got a while back were branded, but I think there are knockoffs around also or at least I do recall the company mentioning this in the past.

Or more specific search would be: saleae logic analyzer 24MHz
I note that zmac also has the "phase/dephase" feature. Looks like a pretty comprehensive tool and even includes the "undefined" Z80 instructions.
Not to mention that the Phillips brothers are incredibly helpful and responsive to enhancement requests and bug reports.
So, after fixing a stuck bit issue, and a wiring design issue (wrong wire list for a '244 driver), I think I uncovered a bus control signal issue. I did some redesign and will rewire it to see if that helps. I could write data to the devices without error repeatedly, but I would sporadically get garbage data back. So that leads me to believe the read control signalling is at fault and causing a timing issue.
I looked at your circuit, and there's not enough decode logic there to fully understand how it's interfacing with the z80. I initially assumed RD and WR come from the z80, but with negative combinatorial logic used for most selects and with using the AND gate line that, I figured that what was showing wasn't necessarily the case. Do you have a more complete schematic showing all the control lines going back to the z80?
The Bus Driver card gets driven directly from the CPU board with no buffering or control. The Bus Driver does a couple of things; drives the signals for the Front Panel card to display data and address values, and show the status of the various control lines. The Serial card only handles the two 8251A USART chips. The circuits in magenta on the Serial card is an update I am getting ready to implement. I put that circuit in LogiSim to make sure there were no conflicts. Hopefully I get it wired up soon and can test it this weekend. Writing data to the Serial card seems to be without error. But reading data back seems to fail about 5% of the time and give weird data. Thanks for taking a peek.


  • BusDriver.pdf
    29.7 KB · Views: 2
  • SerialCardv5.pdf
    57.8 KB · Views: 3
One thing that bares mentioning; the CPU card contains the 64K or memory, the Monitor ROM, the primary serial console port, and the disk interface. Since those only contain the minimal port address decoding, I only have the port addresses from 04H to 77H available. Thus the 74138 shown on the Bus Driver card and why the only thing the 74245 Bus Transceiver is used for on the Bus Driver card is for inputting from those addresses.
Hi Myke, I already gathered that there must be some strict address requirements given the architecture of the '138 in decoding.

In examining your diagrams, I noticed your glue logic was a little "complicated" compared to typical z80 application notes and their implementation - Generally Read and Write and directional signals come straight from the z80 read/write lines whether buffered or otherwise, and the chip select is performed with the IORQ and Address lines. I guessed already with the additional OR gate in the address lines that you needed more selector options to enable the 138 to decode - But you could simplify the logic and reduce the possibility of race conditions by included the IORQ to the 138, using the 138 outputs to drive CS directly, taking RD and WR straight through to the Serial chip RD/WR and the direction of the 245, and then just using a single or gate to combine the two selection options and enable the 245 when either serial chip is selected. Then you might be able to simplify the glue logic to a single LS138 and LS32 and ensure that the signals to the chip enables and read/write lines are timed correctly to when the bus is open. I noticed you're adding to the propagation delay for the select in your circuit, but that shouldn't be necessary - What is more important IMO is to establish the correct data on the bus while the signal is low as soon as possible and the z80 latches it before the rd/wr/IORQ signal changes.

Was there a specific reason for the glue logic being the way it was for this project?
I looked at this and I think this is as minimal as I can get. I know there are some wasted gates, but I've got lots of chips. In the morning I'll run it through LogiSim to see if I missed something, somewhere.... Thanks for looking at it and for your help. I appreciate it.


  • SerialCardv6.pdf
    58.5 KB · Views: 7
Always happy to help others - something I learned from being helped so much myself :)
BTW, you got DIR and EN switched around on the 74ls245 in your diagram - RD goes to DIR and the output from the AND gate to Enable.


p.s. Just noticed - If you use a 74LS00, you can use it for the reset inversion by connecting the inputs to make an inverter of a gate, and use the other gate into a second gate as an inverter to replace the single AND gate.
Then you could eliminate the 74LS06 hex inverter entirely, and if you still wanted to buffer RD/WR you could use the remaining OR gates as buffers...
It's not much but saves a chip and some board space.
Last edited:
Well, I have 'finally' had some time to sit and fiddle with his thing some more. Two things I have discovered is that if I do not send the three '0's to the command ports of the USARTs, then over-run errors come back when I read the status, even before sending or receiving anything. The second thing is that the CTS (pin 17) was staying high preventing the USART from actually transmitting. I suspect it may be external, since pulling the 1489 receiver stopped the issue. Swapped the chip and same thing.

Anyway, I'm back to trying to debug the thing. I have a few code bugs that I need to figure out, and my progress is a tad slow. Oh well.....


  • SerialCardv6.pdf
    56.6 KB · Views: 2
  • 2SIO.txt
    11.9 KB · Views: 4
The issue I'm trying to work through now is that, while the code does (supposedly) print the character that comes back after a transmit & receive cycle, no character gets printed. Hmmmm. The character I enter to use for the cycle gets printed though. So, I wondering if anything is actually going out the wires. I have the transmit and receive pins jumpered....