Regarding COMTX and shift register - there is more than two bits duration available for cpu processing in between two Tx bytes. After first byte is sent to COMTX it is copied to shift register and after some time (much shorter than duration of sending byte) THRE will indicate it is ready for next byte. That is my observation based on empirical testing. Similar situation is regarding Rx side. Note that it is not valid to write COMTX twice (fast) even if TEMT shows that both - COMTX and shift reg are empty. So there is more than simple copy COMTX to shift reg. I did not dig dipper.
I found strange behavior when stress testing Uart module. When testing just Rx or just Tx part everything works fine but when start duplex test after short period of time (couple of seconds) transmit buffer empty interrupt (COMIID0) miss to inform COMTX empty status.
I was able to mask out problem with checking COMSTA0 for THRE in interrupt routine but I am afraid that I have just mask out problem but will show in different scenario. I was not able to determine what i going out.
I am working on silicon revision I31.
Test project is very simple. Something like this
unsigned char interruptId = COMIID0;
if((interruptId & 0x01) == 0)
// interrupt pending
if(interruptId == 0x02)
// Transmit buffer empty
COMTX = '-'; // Tx dummy data
else if(interruptId == 0x04)
// New byte received
b = COMRX;
else if(interruptId == 0x06)
// receive line status
b = COMSTA0;
// Tx works fine only if this uncommented
//if((COMSTA0 & (1 << 5)) == (1 << 5)) // check is COMTX empty
// COMTX = 'X';