Hello World program and questions about 2SIO output ready?

General discussions related to the Altair 8800 Clone

Hello World program and questions about 2SIO output ready?

Postby wearwolf » April 26th, 2021, 11:26 am

I've been working through a bunch of test programs to learn more about the Altair 8800 and the 8080 instruction set. I was working on one program to print a null-terminated string when I realized it could be turned into a hello world example. That's where you are supposed to start with any new programming environment right? So here's my take on a Hello World program for the Altair 8800.

This was all hand assembled to the listing may not be properly formatted

Code: Select all
0000                    ORG 0
0000   3E 03            MVI A, 03H   ;Rest 2SIO port
0002   D3 10            OUT 10H   
0004   3E 15            MVI A, 15H   ;Set 2SIO port to 8n1
0006   D3 10            OUT 10H
0008   21 FE 00         LXI H, MSG   ;Load message address
000B   DB 10   CHECK:   IN 10H      ;Check 2SIO output ready
000D   E6 02            ANI 02H
000F   CA 0B 00         JZ CHECK
0012   7E               MOV A, M   ;Load character
0013   FE 00            CPI 00H      ;Check if null found
0015   CA 1E 00         JZ END
0018   D3 11            OUT 11H      ;Ouput character
001A   23               INX H      ;Move to next character
001B   C3 0B 00         JMP CHECK
001E   76      END:     HLT

00FE   48 65 6C 6C      MSG:   Hell
0102   6F 2C 20 77            o, W
0106   6F 72 6C 64            orld
010A   21 0D 0A 00            !\r\n\0


I put the message at 00FE because I wanted it to go over the 1-byte address boundary to make sure it was incrementing the address correctly. Before I found the INX instruction I was thinking I was going to need to do a multi-byte add so I wanted to make sure that worked correctly when crossing that boundary.

Now my question is about this loop.

Code: Select all
CHECK:   IN 10H
         ANI 02H
         JZ CHECK


During an earlier test I was printing a CR and a LF character right after each other and it seemed like sometimes it worked and sometimes output would get missed/muddled. So I added this loop to check that the Transmit Data Register Empty flag is set before outputting a value.

My questions are
1. Is there a better way to check if output is ready? (I figure this has been done enough that people have likely found the best way to do it)
2. Are there any guidelines on when the output ready check is needed?
wearwolf
 
Posts: 6
Joined: April 11th, 2021, 2:41 pm

Re: Hello World program and questions about 2SIO output read

Postby TronDD » April 26th, 2021, 4:41 pm

There are smarter people here than I, but that's basically how to do the check. You could also RRC twice and JNC. Not sure the time difference between two RRC instructions and one ANI.

You should always do the check. The CPU is much faster than a 9600 baud UART.

Fun exercise. Put a counter in the loop and see how many times it has to check between sending 2 characters.
TronDD
 
Posts: 40
Joined: November 20th, 2018, 8:51 pm

Re: Hello World program and questions about 2SIO output read

Postby wearwolf » May 29th, 2021, 11:52 am

According to the 8080/8085 Assembly Language Programming manual an ANI instruction takes 7 states and the rotate instructions each take 4 states. So ANI is probably slightly faster but not by much. Both take up two bytes so there's no memory difference.

I tested the number of retries using this program.

Code: Select all
0000                     ORG 0
0000   3E 03             MVI A, 03H   ;Reset 2SIO port
0002   D3 10             OUT 10H
0004   3E 15             MVI A, 15H   ;Set 2SIO to 8n1
0006   D3 10             OUT 10H
0008   21 30 00          LXI H, 0030H ;Init output address
000B   06 00     LOOP:   MVI B, 00H   ;clear B
000D   3E 30             MVI A, 30H   ;set A = '0'
000F   D3 11             OUT 11H      ;output '0'
0011   DB 10      CHK:   IN 10H       ;read status byte
0013   04                INR B        ;increment B
0014   E6 02             ANI 02H      ;Check output ready
0016   CA 11 00          JZ CHK
0019   7D                MOV M, B     ;Write B to memory
001A   23                INX H        ;increment memory address
001B   C3 0B 00          JMP LOOP


Strangely the first character only goes through the loop once before the output is clear but all subsequent sends go through 60 or 61 times. So I guess the output check is much more important if you're going to be sending a lot of characters at once and less important if you are only sending one character occasionally.
wearwolf
 
Posts: 6
Joined: April 11th, 2021, 2:41 pm

Re: Hello World program and questions about 2SIO output read

Postby AltairClone » May 29th, 2021, 4:59 pm

The UART has the data register you actually write to and then a separate shift register that is used while the character is being serially transmitted. When the UART has been idle for at least two character times, then both registers are empty. A write to the data register is immediately transferred to the shift register for transmission. At this point, the data register is empty again and shows “ready” as soon as your software checks again. When you write the second character to the data register, that byte now has to remain in the data register until the 1st character is out of the shift register (about one character time at the chosen baud rate). From then on, until there is a pause in the output data, it will always take a character time until the UART shows ready for another character.

Mike
AltairClone
Site Admin
 
Posts: 632
Joined: April 5th, 2013, 10:55 am

Re: Hello World program and questions about 2SIO output read

Postby TronDD » May 29th, 2021, 5:06 pm

wearwolf wrote:Strangely the first character only goes through the loop once


Well, you just initialized everything so the UART and line are clear.

less important if you are only sending one character occasionally.


Well, "occasionally" is a bit squishy. If you send 1 character, go do some other stuff, then send 1 more character, you still should check to be sure because 61 loops of 4 instructions is quite a lot of stuff you can do. And that's not accounting for RTS possibly halting the transfer for an unknown length of time.
TronDD
 
Posts: 40
Joined: November 20th, 2018, 8:51 pm

Re: Hello World program and questions about 2SIO output read

Postby wearwolf » June 2nd, 2021, 12:32 pm

TronDD wrote:
wearwolf wrote:Strangely the first character only goes through the loop once


Well, you just initialized everything so the UART and line are clear.


I mean after you sent the first byte it immediately shows as empty. Unless you are saying there's some kind of pipelining going on where the first byte moves into the sending circuitry which frees up the buffer for the next byte.

And yeah building a full program you'd always want to have the check just to be safe. I was more thinking for testing it's useful to know when you can get away without including the check. Saving yourself having to enter in those 7 bytes.
wearwolf
 
Posts: 6
Joined: April 11th, 2021, 2:41 pm


Return to General Discussions

Who is online

Users browsing this forum: Google [Bot] and 14 guests

cron