Ah, the infamous 8251. I've been programming those recently to do support for the Heath H8/H89 cassette tape board. I thought that PCs used the 8250, though... which has a very different software interface. Maybe the earliest PCs used the 8251? I thought they were even getting hard to come by. The 8250 designs live on in modern chips, even having 2 and 4 complete 8250's on a die.
Just a note about polling vs. interrupts. Contrary to popular belief, interrupts are not the fastest way to receive data over a serial port. If it is time constrained (i.e. high bauds), you need to use a dedicated poll loop to get the best throughput. I see you have hard-wired the baud to 9600, which may be fairly slow depending on your CPU clock. But, the nagging problem with downloads is unexpected interrupts from other sources causing the receive to fall behind. This includes the "fire hose" protocol if trying to periodically write data to disk. If your system has spontaneous interrupts (like the Heath systems "2mS Clock") you may have issues keeping up.
So, this is what I have to start. I am fiddling with some test code using BASIC just to get some concepts. But the attached is the start of what I have found is somewhat common in several 8251 driver code modules I have looked at. Not sure where I read the part about sending 00 three times to start with though. I did read it many years ago. It may be redundantly wasteful....
/code/
;
; STD Bus Serial Board Addresses
SACR EQU 025H ;2SIO port A control register
SADR EQU 024H ;2SIO port A data register
SBCR EQU 027H ;2SIO port B control register
SBDR EQU 026H ;2SIO port B data register
;
;------------------------------------------------------
;8251A UART Initialization routine
;------------------------------------------------------
;Port 24H is Read/Write Data for 8251A UART 0
;Port 25H is Control & Status Port for 8251A UART 0
;Port 26H is Read/Write Data for 8251A UART 1
;Port 27H is Control & Status Port for 8251A UART 1
;------------------------------------------------------
;8251A UART Initialization
;When power is first applied, the 8251A may come up
;in the Mode, Sync character, or Command format. To
;guarantee that the device is in the Command Instruction
;format before the Reset command is issued,
;it is safest to execute the worst-case initialization
;sequence (sync mode with two sync characters).
;Loading three 00Hs consecutively into the de-
;vice with C/*D=1 configures sync operation and
;writes two dummy 00H sync characters.
LD A,00H ;First of UART init commands
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
;
;8251A UART Reset Command
;Issuing a 40H command returns the 8251A to the 'idle' state
;and to the Mode Instruction format.
LD A,40H ;UART reset command
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
;
;Mode instruction byte breakdown
;Baud rate selector - data bits 0 & 1
;bit0=0 & bit1=0 - Sync mode
;bit0=1 & bit1=0 - 1X mode
;bit0=0 & bit1=1 - 16X mode (THIS IS SELECTED)
;bit0=1 & bit1=1 - 64X mode
;Character length selector
;bit2=0 & bit3=0 - 5 bits
;bit2=1 & bit3=0 - 6 bits
;bit2=0 & bit3=1 - 7 bits
;bit2=1 7 bit3=1 - 8 bits (THIS IS SELECTED)
;Parity enable
;bit4=0 - disable (THIS IS SELECTED)
;bit4=1 - enabled
;Even parity generator/check
;bit5=0 - odd (THIS IS SELECTED)
;bit5=1 - even
;Number of stop bits
;bit6=0 & bit7=0 - invalid
;bit6=1 & bit7=0 - 1 bit (THIS IS SELECTED)
;bit6=0 & bit7=1 - 1-1/2 bits
;bit6=1 & bit7=1 - 2 bits
; B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0
; 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0
LD A,4EH ;UART mode instruction
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
;
;Command instruction breakdown
;Transmit enable
;bit0=0 - disabled
;bit0=1 - enabled (THIS IS SELECTED)
;Date Terminal Ready
;bit1=0 - DTR set high
;bit1=1 - DTR set low (THIS IS SELECTED)
;Receive enable
;bit2=0 - disabled
;bit2=1 - enabled (THIS IS SELECTED)
;Send break character
;bit3=0 - normal operation (THIS IS SELECTED)
;bit3=1 - set TxD low
;Error reset
;bit4=0 - do not reset error flags
;bit4=1 - reset error flags (THIS IS SELECTED)
;Request to send
;bit5=0 - RTS set high
;bit5=1 - RTS set low (THIS IS SELECTED)
;Internal reset
;bit6=0 - normal operation (THIS IS SELECTED)
;bit6=1 - sets 8251 to Mode instruction Format
;Enter hunt mode (no effect in async mode)
;bit7=0 - disabled (THIS IS SELECTED)
;bit7=1 - enabled
; B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0
; 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1
LD A,37H ;UART command instruction
OUT (SACR),A ;Output to serial0 control port
OUT (SBCR),A ;Output to serial1 control port
/code/