Understanding bus signals

87 views
Skip to first unread message

Matthew Brugman

unread,
Apr 1, 2026, 12:04:02 PMApr 1
to Altair-Duino
I've read page 37 of `Documentation.docx` regarding interfacing external hardware via data/address buses to help me get my custom Experimenter bus card going.  I'm looking for a bit of feedback to be sure my assumptions on how this all works is correct.

To start with, I put together a very small test program:
   mvi a,255
   out 255
   nop
   in 255
   nop
   hlt
...which I hand compiled to switches 076, 377, 232, 377, 000, 333, 377, 000, 166 and entered starting at address 0x0000.  (This was from a fresh default power-up, so nothing else running).  I used address 255 so I could verify it was working as expected by watching the LEDs on the register output card.

I hooked up a logic analyzer to the pins on my bus card (see previous posts about that), and here's what I see when I run it:
Screenshot from 2026-04-01 09-26-54.png
For reference, the channels are:
  • A0 - address line 0
  • A1 - address line 1
  • Select - address lines 2 through 7 AND-ed together (so it will go high on any bus address from 252 to 255)
  • Bus INP - the 'INPUT' bus line
  • Bus OUT - the 'OUTPUT' bus line
  • WAIT - the 'WAIT' bus line
So, it's pretty straight forward as the lil' program runs: first comes the `OUT` command, the select and A0/A1 are high, so it's addressed to port 255 all as expected.  The OUT line is high for about 940ns (consistent for a number of runs).  The address is set at the same time as the OUT line goes high.  

Next, the INPUT line goes high.  I see there's a small (250ns) delay before the INPUT line goes high after address is set, which is a good thing.  The INPUT line is high for just under 3.19us (again consistent over a number of runs)
 
The WAIT line is low, as expected, throughout the whole run.  (It goes high when we hit the HLT instruction).

My questions about all of this:
First: that tight timing from the address setting to setting output line high.  I see this in the code for Altail8800.ino:
Screenshot from 2026-04-01 10-00-37.png
It doesn't look like the 4 additional `host_set_data_leds()` are adding any time as described in the comment.  I need to check the compiler listing - I wonder if the compiler is optimizing those additional calls out, or is it just that writing to the output register is  so fast that 4 extra calls don't add significant time?

Second:  The sequence of the INPUT handling; the flow is to the set the address lines and check the WAIT line.  If WAIT is low, then set the INPUT line high, read the data, then set INPUT low. 
Screenshot from 2026-04-01 10-03-35.png
 If the WAIT was high, turn INPUT on, read data, set INPUT low, do a little housekeeping, and loop through that until WAIT is low:  
Screenshot from 2026-04-01 10-40-56.png

Either way, the WAIT line is checked *before* the INPUT line goes high, so it seems like a bus device would have no chance to assert WAIT to force a wait state to be sure it's data is ready - does that seem legit?

Third question (related to question 2 for INPUT) - if somehow the WAIT line was asserted by the bus device before the INPUT line went high, the code continually toggles the INPUT line which might be a problem for the bus device.  Is that right?

Seems like I'm just missing the point on the INPUT handling?

Last question - the duration of the INPUT is longer than the max 1500ns time in the document, but it's consistently longer at around 3.19us.  This isn't a big deal, but differs from doc, and I'm not sure where I see where the extra time is coming from in the code.

I'd really appreciate it if anyone has anything comments on my questions or to let me know I'm off base on this.  :)

Thanks much!
Matt


da...@hansels.net

unread,
Apr 1, 2026, 3:07:13 PMApr 1
to Altair-Duino
The timings in the documentation were taken back when I wrote that code. Unfortunately with the compiler
evolving and generating code differently it is possible that the timings have changed. It is very difficult to
force exact timings when both the C compiler and the processor itself try to optimize the code execution.
Did you compile the code yourself or are you using Chris' pre-compiled version?

I'll take some measurements in the coming days and will report what I find.

Regarding the INPUT handling, there are actually two different functions in host_due.h for querying the WAIT state:
host_read_status_led_WAIT() - returns the current setting for the WAIT LED as set by the emulator, i.e. it will return TRUE if the emulator is in STOP mode and FALSE if it is in RUN mode
host_read_status_wait() - returns the incoming value on the WAIT line as asserted by the external hardware (i.e. cards)

The "if( host_read_status_led_WAIT() )" you were looking at just checks whether we are in STOP mode and
if so loops until the user enters RUN mode again (or single-steps forward). This allows to monitor the input
data when single-stepping through an INP instruction (works the same on a real Altair).

The actual reading of the input value happens in function io_inp() in file io.cpp:
which is called AFTER setting the INP signal high.
In there you can see a loop waiting for host_read_status_wait()==FALSE which is the actual place
where the emulator waits until the WAIT input is LOW.

Note that there is very practically nothing happening between the INP signal going HIGH and the emulator
checking the WAIT line. So cards must react instantly to raise WAIT if they need it.
In the disk controller card this is done by U4 which immediately pulls WAIT high if the card is addressed
and keeps it high until the ATMega says it's ok to continue:

David

Matthew Brugman

unread,
Apr 1, 2026, 3:36:38 PMApr 1
to Altair-Duino
On Wednesday, April 1, 2026 at 2:07:13 PM UTC-5 da...@hansels.net wrote:
The timings in the documentation were taken back when I wrote that code. Unfortunately with the compiler
evolving and generating code differently it is possible that the timings have changed. It is very difficult to
force exact timings when both the C compiler and the processor itself try to optimize the code execution.
Did you compile the code yourself or are you using Chris' pre-compiled version?

I'm using Chris' pre-compiled version, it shows "Firmware compiled on: Jan  1 2026, 13:15:10"  I totally get what you mean about specific timings; I'm retired from a career mostly in embedded systems and controllers were real-time and determinant response was critical.

I'll take some measurements in the coming days and will report what I find.

Regarding the INPUT handling, there are actually two different functions in host_due.h for querying the WAIT state:
host_read_status_led_WAIT() - returns the current setting for the WAIT LED as set by the emulator, i.e. it will return TRUE if the emulator is in STOP mode and FALSE if it is in RUN mode
host_read_status_wait() - returns the incoming value on the WAIT line as asserted by the external hardware (i.e. cards)

The "if( host_read_status_led_WAIT() )" you were looking at just checks whether we are in STOP mode and
if so loops until the user enters RUN mode again (or single-steps forward). This allows to monitor the input
data when single-stepping through an INP instruction (works the same on a real Altair).

The actual reading of the input value happens in function io_inp() in file io.cpp:
which is called AFTER setting the INP signal high.
In there you can see a loop waiting for host_read_status_wait()==FALSE which is the actual place
where the emulator waits until the WAIT input is LOW.
 
OK, that makes a lot more sense - I was sure that I was missing something there :)   I'll peek into those methods when I get back to code.

Note that there is very practically nothing happening between the INP signal going HIGH and the emulator
checking the WAIT line. So cards must react instantly to raise WAIT if they need it.
In the disk controller card this is done by U4 which immediately pulls WAIT high if the card is addressed
and keeps it high until the ATMega says it's ok to continue:

Yes, the timing is a matter of concern, and what got me to start down this road with the LA and such.  I'm using my "generic" proto board which doesn't have that TTL logic built in.  This was where I was getting concerned about things like triggering on INP or OUT rising edge and checking addresses in the ISR to decide what to do.  

Based on the logic analyzer results, I think I'll be safe in just asserting WAIT in an ISR for INP; just check the SELECT line and assert if true.  (Plan is to have 4 port addresses, so SELECT is just a hardware AND of A2 through A7).  That'll be trickier on OUT because addressing is almost simultaneous to OUT, but I'm not sure if I'll actually need to assert WAIT for OUT.
 
David
 
Thanks again for the quick and detailed reply!
Matt 

 

da...@hansels.net

unread,
Apr 4, 2026, 10:46:11 PMApr 4
to Altair-Duino
I did some timing measurements and I think the repeated host_set_data_leds() calls are actually
(still) doing what they were supposed to.

Here is an oscilloscope capture for the OUT instruction:

DS1Z_QuickPrint8.png

The yellow line is the OUT signal.
The light blue line is one of the address lines.
The dark blue signal is the output of the CD4068BE (which would be the "SELECT" signal on your board).

What you can see is that the address line change does occur (roughly) 200ns before SELECT goes high,
like it is described in the comment in the code.
However the SELECT signal lags about the same amount behind the address line switch.
That explains why SELECT and OUT look about simultaneous in your logic analyzer capture.

The delay roughly corresponds to what you can find in the data sheet for the CD4068BE:
Screenshot 2026-04-04 223608.png
It takes about 150ns for the 4068 to react to the change and then about 100ns for the transition, which is pretty slow.

I don't think that should be a problem for you. by the time your microcontroller has reacted to the OUT signal,
SELECT will long have been high (or vice versa).

But if you wanted a longer delay between SELECT and OUT then you could choose a faster IC.
I haven't tried it but the 74HCS30 (an 8-bit NAND gate) looks like a good candidate:
Screenshot 2026-04-04 223711.png

David

Matthew Brugman

unread,
Apr 6, 2026, 3:12:24 PMApr 6
to Altair-Duino
David,

Thanks for taking the time to check all of that out - I appreciate the feedback, sanity check, and information!

I wasn't taking prop delay into account with the 4068 - to be honest, I just lifted that part from the designs in your repo :)  As you say, I think I'll be OK with using interrupts on my end to watch/react to the select + IN/OUT lines.  I'll be getting back to it in a bit, and we'll see how it goes.

Thanks again!
Matt

Reply all
Reply to author
Forward
0 new messages