• Please review our updated Terms and Rules here

How to get output from SIO with Intel 8251A USART

The 8251 is a bit tricky to initialize. (Vary from different manufacturers)
Important is, that you initialalize the 8251 quickly after the reset (Hardware-Reset).
The time between the OPs for the initializing must be short.
Send about three 00H befor going on.
The code underneath works for me well (For two 8251s).
Have a try.
Frank
Code:
CCOM	.EQU    0B1H            ;8251 COMMAND PORT.
RCOM	.EQU    0F1H	     ;CONSOLE COMMAND PORT.
	MVI  	A,00H		;INITIALIZE UART.
	OUT  	CCOM
	OUT	RCOM
	MVI  	A,00H		;INITIALIZE UART.
	OUT  	CCOM
	OUT	RCOM
	MVI  	A,00H		;INITIALIZE UART.
	OUT  	CCOM
	OUT	RCOM
	MVI  	A,40H		;reset command
	OUT  	CCOM
	OUT	RCOM
	MVI  	A,0CEH		;Mode register 8,2,n /16/64 (CE=9600; CF=2400)
	OUT  	CCOM
	MVI  	A,0CFH		;Mode register 8,2,n /16/64 (CE=9600; CF=2400)
	OUT  	RCOM
        MVI  	A,37H		;Command register
	OUT  	CCOM
	OUT	RCOM
 
Last edited:
Hi again.

Right, I am happy with your program. Keep using that every time!

You software appears to initialise the 8251 in Asynchronous, 8N1 x16 clock mode, wait for a character to be received and echo it back to whoever sent it - repeat for infinity. If this is loaded at zero and executed I would expect it to work (with one exception - that I will discuss in a second).

I agree with Chuck. If you stick an LED on any (active low) signal line to monitor it - it will normally be ON (assuming HIGH = logical '1' = LED ON) and will only pulse low very briefly.

Your transmitter will not, however, still transmit anything!

Check out the 8251 data sheet "http://www.zmitac.aei.polsl.pl/ui/instrukcje/smiw7,9/INT8251.pdf" on page 4 under "Transmit Buffer". In order to transmit anything, the 8251 needs to see /CTS low. You said in a previous post that you have only wired up pins 2, 3 and 7 (Tx, Rx and GND). What have you done with /CTS? The usual 'trick' is to wire /RTS to /CTS and /DTR to /DSR. This 'fools' the 8251 into thinking that everything is OK and it will quite happily transmit and receive characters.

Well done for sticking with it though!

Dave
 
Chuck,

And I mentioned it back in post #10 as well - but that was a while ago and the OP may have forgotten by now.

As far as I can see (barring hardware faults) the software should now work - the OP should (hopefully) just need to jumper /RTS and /CTS to make their hardware set-up work; so why not mention it here again to make life simple?

Dave
 
On a 25-way D connector, link 4-5 (RTS-CTS) and 6-8-20 (DSR-CD-DTR). Pins 2, 3 and 7 are then the data lines (2 and 3) and ground (7). The 'sense' of the signals may change depending upon whether the end is "Data Terminal Equipment" (DTE) or "Data Communication Equipment" (DCE).

To be safe, undertake the links on both ends of the cable just to make sure that both the terminal and the SIO UART are happy.

Dave
 
UPDATE

I got an another IMSAI SIO board, now I'm able to echo characters from the keyboard back to the screen.
For this I use the ECHO program from the manual.

Unfortunately I can't get a continuous stream of characters on the screen, and I dont know why because
the ECHO program works just fine.
 
Echo:

0000 3e 4e
0002 d3 03
0004 3e 37
0006 d3 03
0008 db 03
000a e6 02
000c ca 08 00
000f db 02
0011 d3 02
0013 c3 08 00

stream:

0000 db ff
0002 d3 03
0004 c3 00 00
 
Try this for both SIO cards.
The success depends on the correct initialization of the 8251.

ECHO-Routine
Code:
0001 0000 	CDAT 	.EQU 02H 	;8251 DATA PORT
0002 0000 	CCOM 	.EQU 03H 	;8251 COMMAND PORT.
0003 0000 3E 00 	MVI 	A,00H 	;INITIALIZE UART.
0004 0002 D3 03 	OUT 	CCOM
0005 0004 D3 03 	OUT 	CCOM
0006 0006 D3 03 	OUT 	CCOM
0007 0008 3E 40 	MVI 	A,40H 	;reset command
0008 000A D3 03 	OUT 	CCOM
0009 000C 3E 4E 	MVI 	A,04EH 	;Mode register 8,1,n 
0010 000E D3 03 	OUT 	CCOM
0011 0010 3E 37 	MVI 	A,37H 	;Command register
0012 0012 D3 03 	OUT 	CCOM
0013 0014 DB 03 LOOP: 	IN 	CCOM
0014 0016 E6 02 	ANI 	02
0015 0018 CA 14 00 	JZ 	LOOP
0016 001B DB 02 	IN 	CDAT
0017 001D D3 02 	OUT 	CDAT
0018 001F C3 14 00 	JMP 	LOOP
0019 0022
0020 0022 		.END

SENSE-Switch SIO Out Routine
Code:
0001 0000 	CDAT 	.EQU 	02H 	;8251 DATA PORT
0002 0000 	CCOM 	.EQU 	03H 	;8251 COMMAND PORT.
0003 0000 	SENSE 	.EQU 	0FFH
0004 0000 3E 00 	MVI 	A,00H 	;INITIALIZE UART.
0005 0002 D3 03 	OUT 	CCOM
0006 0004 D3 03 	OUT 	CCOM
0007 0006 D3 03 	OUT 	CCOM
0008 0008 3E 40 	MVI 	A,40H 	;reset command
0009 000A D3 03 	OUT 	CCOM
0010 000C 3E 4E 	MVI 	A,04EH 	;Mode register 8,1,n 
0011 000E D3 03 	OUT 	CCOM
0012 0010 3E 37 	MVI 	A,37H 	;Command register
0013 0012 D3 03 	OUT 	CCOM
0014 0014 DB FF LOOP: 	IN 	SENSE
0015 0016 D3 02 	OUT 	CDAT
0016 0018 C3 14 00 	JMP 	LOOP
0017 001B
0018 001B .END

Frank
 
Last edited:
The difference should be obvious--in the sense switch routine doesn't poll for ready before sending a character. The result is that you're firing out characters before the previous one can be sent, which overruns the USART.

Try adding the poll-for-ready code to your loop:

Code:
LOOP: 	IN 	CCOM
        ANI 	02
        JZ 	LOOP
 
Also the OP had a "D3 03" (OUT COMMAND_PORT) instead of a "D3 02" (OUT DATA_PORT) so all the bytes coming from the sense switches were being set to the command side of the UART instead of the data side.

And (emphasising what Chuck has already posted), before sending a character to the UART you must make sure that the last character has been transmitted before you try to send another one (unless the UART contains internal buffering within the silicon - but I wouldn't rely on this except in very time-critical and high speed applications). Although I think ANI 02 tests the "received character flag" not the "transmitter empty flag" which (I think) should be ANI 04 (although I am working from memory here without access to reference material).

The echo program waited for a received character and then echoed it to the transmitter irrespective of the transmitter state. If we want to transmit a stream of character as fast as possible - you need to check the state of the transmitter empty flag and loop if it is still busy.

Dave
 
Chuck,thats right.
I corrected the code for checking the BIT 0 of the 8251 Status register for beeing empty.

SENSE-Switch SIO Out Routine
Code:
0001 0000 	CDAT 	.EQU 	02H 	;8251 DATA PORT
0002 0000 	CCOM 	.EQU 	03H 	;8251 COMMAND PORT.
0003 0000 	SENSE 	.EQU 	0FFH
0004 0000 3E 00 	MVI 	A,00H 	;INITIALIZE UART.
0005 0002 D3 03 	OUT 	CCOM
0006 0004 D3 03 	OUT 	CCOM
0007 0006 D3 03 	OUT 	CCOM
0008 0008 3E 40 	MVI 	A,40H 	;reset command
0009 000A D3 03 	OUT 	CCOM
0010 000C 3E 4E 	MVI 	A,04EH 	;Mode register 8,1,n 
0011 000E D3 03 	OUT 	CCOM
0012 0010 3E 37 	MVI 	A,37H 	;Command register
0013 0012 D3 03 	OUT 	CCOM
0014 0014 DB FF 	LOOP: 	IN 	SENSE
0015 0016 E6 01 	ANI 	01H
0016 0018 CA 14 00 	JZ 	LOOP
0017 001B DB FF 	IN 	SENSE
0018 001D D3 02 	OUT 	CDAT
0019 001F C3 14 00 	JMP 	LOOP
0020 0022
0021 0022 		.END

Frank
 
Still no succes, only the ECHO routine will work.

With my previous routine, not Franks one, I get a stream of question marks.
I don't know why, because the SENSE switches were all in the down postion??
 
Hello Matt,
please explain a little bit more detailed, what is working and what do you get for results.
I make an mistake yesterday evening in the code.
Try the code below.
Frank

Code:
0001   0000             CDAT	.EQU	02H		;8251 DATA PORT
0002   0000             CCOM	.EQU    03H             ;8251 COMMAND PORT.
0003   0000             SENSE	.EQU	0FFH
0004   0000 3E 00       	MVI  	A,00H		;INITIALIZE UART.
0005   0002 D3 03       	OUT  	CCOM
0006   0004 D3 03       	OUT  	CCOM
0007   0006 D3 03       	OUT  	CCOM
0008   0008 3E 40       	MVI  	A,40H		;reset command
0009   000A D3 03       	OUT  	CCOM
0010   000C 3E 4E       	MVI  	A,04EH		;Mode register 8,1,n
0011   000E D3 03       	OUT  	CCOM
0012   0010 3E 37               MVI  	A,37H		;Command register
0013   0012 D3 03       	OUT  	CCOM
0014   0014 DB FF       LOOP:	IN	SENSE
0015   0016 D3 02       	OUT	CDAT
0016   0018 DB 03       LOOP1:	IN 	CCOM
0017   001A E6 01       	ANI	01H
0018   001C CA 18 00    	JZ	LOOP1
0019   001F C3 14 00    	JMP	LOOP	
0020   0022             	
0021   0022             	.END
 
Last edited:
Chuck,thats right.
I corrected the code for checking the BIT 0 of the 8251 Status register for beeing empty.

SENSE-Switch SIO Out Routine
Code:
0001 0000 	CDAT 	.EQU 	02H 	;8251 DATA PORT
0002 0000 	CCOM 	.EQU 	03H 	;8251 COMMAND PORT.
0003 0000 	SENSE 	.EQU 	0FFH
0004 0000 3E 00 	MVI 	A,00H 	;INITIALIZE UART.
0005 0002 D3 03 	OUT 	CCOM
0006 0004 D3 03 	OUT 	CCOM
0007 0006 D3 03 	OUT 	CCOM
0008 0008 3E 40 	MVI 	A,40H 	;reset command
0009 000A D3 03 	OUT 	CCOM
0010 000C 3E 4E 	MVI 	A,04EH 	;Mode register 8,1,n 
0011 000E D3 03 	OUT 	CCOM
0012 0010 3E 37 	MVI 	A,37H 	;Command register
0013 0012 D3 03 	OUT 	CCOM
0014 0014 DB FF 	LOOP: 	IN 	SENSE  <--------------- *** shouldn't this be CCOM? ***
0015 0016 E6 01 	ANI 	01H
0016 0018 CA 14 00 	JZ 	LOOP
0017 001B DB FF 	IN 	SENSE
0018 001D D3 02 	OUT 	CDAT
0019 001F C3 14 00 	JMP 	LOOP
0020 0022
0021 0022 		.END

Frank

It seems to me that the input instruction at the LOOP: label should be IN CCOM, not IN SENSE, or am I hallucinating?

smp
 
I'm sorry, I was a bit hurry.

Anyway, the ECHO routine works flawless, any key which I press on the console (Hazeltine 1410) gets displayed on the screen.

With the SENSE routine, I get a continous stream of question marks without hitting any switch on the frontpanel.
When I hit an switch (switches A8 through A15) the stream stops or changes to an "@" sign.

I can't generate any other character than these.

@smp: I changed that several hours before, without luck.
 
Anyway, the ECHO routine works flawless, any key which I press on the console (Hazeltine 1410) gets displayed on the screen.

And this with both SIOs you have?

Frank
@smp: No, you are not hallucinating. I correct the code above.;)
 
Back
Top