Hi Jim,
I've taken the original program and added line numbers with comments below:
1 init: mvi A, 003 ; Reset the 2SIO port 1
2 out 020
3 mvi A, 021 ; Set port 1 to 8,2,n
4 out 020
5
6 loop: in 020 ; wait for a character to arrive
7 rrc
8 jnc loop
9
10 in 021 ; get the character
11 out 021 ; send it back out
12 jmp loop ; continue forever
The first 2SIO port on the Altair 8800 Clone is set to addresses 020 and 021 (octal) by default. I assume that you have not changed this. These addresses are 0x10 and 0x11 respectively in hexadecimal. The first address, 020, is a status register when read. It is a control register when written.
The second address, 021, is a receive data register when read. It is a transmit data register when written.
lines 1 & 2: Reference the Motorola ACIA MC6850 datasheet. The lower two bits of the control register are CR1 and CR0. When the lower two bits are set to '1', the MC6850 performs a master reset.
Background:3 = 0000 0011 (in hex. I think in hex better than octal). 3 = 00 000 011 (in octal)
lines 3 & 4: 21 = 00 010 001 (octal). This will set bits 4 and 0 to a '1'. Bit 4 is CR4. This along with CR3 and CR2 (both zero) from the data sheet means set the port for 8 data bits plus 2 stop bits. Bit 0 is CR0. That along with CR1 which is zero, selects 'divide by 16' mode for the baud clock. Take the master clock going to the MC6850, divide by 16, this should yield the bit clock for 9600 baud (about 104 microseconds? My memory may be a little off...)
lines 6, 7, & 8: This is the heart of your issue with changing the program. Line 6 reads the status register into A. Bit 0 of the status register is Receive Data Register Full (RDRF). This bit will be a '1' when a character has been received. Line 7 is a fast way to check if bit 0 is set. The instruction 'rrc' rotate right through carry will shift all bits in A right 1 bit, and put bit 0 into the Carry Flag. Line 8 contains a jump no carry back to the wait loop. So, if there was no character ready, then A's bit 0 would be '0'. After the 'rrc' instruction, the carry would also be '0'. The jump in line 8 would be executed in this case.
line 10: Read the received character from the Receive Data Register into A.
line 11: Write the character in A to the Transmit Data Register.
NEW PROGRAM:
- Code: Select all
0100 org 100h
0100 C30B01 jmp loop ; if running from CP/M, don't init the port
0103 3E21 init: mvi A, 33 ; Reset the 2SIO port 1
0105 D310 out 020Q
0107 3E11 mvi A, 021Q ; Set port 1 to 8,2,n
0109 D310 out 020Q
010B DBFF loop: in 377Q ; read sense switches
010D FE00 cpi 0 ; all zeroes?
010F CA0B01 jz loop
0112 47 mov b, a ; save the switches in B
0113 DB10 wait: in 020Q ; check status register
0115 E602 ani 002 ; transmit data register empty?
0117 CA1301 jz wait ; if not, wait
011A 78 mov a, b ; get the switches back in A
011B D311 out 021Q ; write the value to the serial port
011D FEFF cpi 377Q ; all ones?
011F C8 rz ; gracefully return to CP/M if all sense switches A15-A8 are 1's
0120 C30B01 jmp loop
I hope this helps.
John