;======================================================================
+; SERIAL PORT - TRANSMISSION TO HOST
+
+ include common.inc
+ code
+
+;======================================================================
+; QUEUEING MESSAGES FOR TRANSMISSION
+
+;----------
+addbyte_toomany panic morse_HB
;----------------------------------------
-serial_addbyte
-; W byte for transmission to host trashed
-; FSR0 any set for serial_addbyte_another
-; outmsg_* buffer not full adjusted appropriately
-; STATUS any trashed
-; all others any not interfered with
+serial_addbyte @
+; W byte to xmit to host trashed
+; FSR0 any set for serial_addbyte_another
+; outbuf, outmsg_* buffer not full adjusted appropriately
+; STATUS any trashed
+; all others any not interfered with
;
mov_lfsr outbuf, 0
mov_ff outmsg_end, FSR0L
;...
-serial_addbyte_another
-; W byte for transmission to host trashed
-; FSR0 from serial_addbyte[_another] set for serial_addbyte_another
-; outmsg_* buffer not full adjusted appropriately
-; STATUS any trashed
-; all others any not interfered with
+;----------------------------------------
+serial_addbyte_another @
+; W byte to xmit to host trashed
+; FSR0 from _addbyte[_another] updated for ..._another again
+; outbuf, outmsg_* buffer not full adjusted appropriately
+; STATUS any trashed
+; all others any not interfered with
;
- mov_wf POSTIN0C
+ mov_wf POSTINC0
bc_f FSR0L, 7
mov_fw FSR0L
mov_wf outmsg_end
xor_wfw outmsg_begin
- bra_z serial_addbyte_toomany
+ bra_z addbyte_toomany
+ ; no, we're ok:
+
+ bt_f_if1 PIE1, TXIE
+ return ; don't bother messing about if tx is already enabled
+
+; we fall through to portb_read to reenable TXIE if appropriate
+;...
+;======================================================================
+; FLOW CONTROL BY HOST OF OUR TRANSMISSIONS
+
+;...
+;----------------------------------------
+portb_read @
+;
+; W undefined value from PORTB
+; TXIE any enabled iff host allows us to xmit
+;
+; Note that this will reenable TXIE even if the serial buffer is empty,
+; every time portb_read is called. This doesn't matter very much
+; because the serialtx_intrl routine will disable it again straight
+; away.
+;
+ mov_fw PORTB
+ bc_f INTCON, RBIF
+
+ bt_w_if1 p0_rs232_fcin >> 4
+ bra txfc_disable
+ ; tx enable:
+
+ call led_green ; we're transmitting
+ bs_f PIE1, TXIE
return
-;-----
-serial_addbyte_toomany panic morse_HB
+;----------
+txfc_disable
+ bc_f PIE1, TXIE
+ goto led_red ; flow control forces us not to transmit
+
+;----------------------------------------------------------------------
+serialtxfc_intrl @
+ bt_f_if0 INTCON, RBIF
+ return
+ ; yes, it's us:
+
+ rcall portb_read ; check flow control
+ intrl_handled_nostack
+
+;----------------------------------------------------------------------
+serialtxfc_init @
+ bc_f INTCON2, RBIP
+ bs_f INTCON, RBIE
+ rcall portb_read
+ pin_l p0_rs232_fcout ; set outgoing RTS/CTS active
+ return
+
+;======================================================================
+; ACTUAL TRANSMISSION
+
+;----------------------------------------------------------------------
+serialtx_intrl @
+ ; are we ready to transmit ?
+ bt_f_if0 PIR1, TXIF
+ return
+ bt_f_if0 PIE1, TXIE
+ return
+ ; yes, it's us:
+
+ mov_lfsr outbuf, 0
+ mov_fw outmsg_begin
+ mov_wf FSR0L
+ xor_wfw outmsg_end
+ bra_z tx_bufempty
+
+ mov_fw INDF0
+ mov_wf TXREG
+ bra_n tx_justsent_noacknmra
+ ; we've just sent the last byte of some message:
+ ; maybe we push an NMRADONE message on the front
+ mov_fw acknmra
+ bra_nz tx_acknmra_insert
+tx_justsent_noacknmra
+ inc_f outmsg_begin
+ bc_f outmsg_begin, outbuf_szln2
+ call i2c_consider_restartread
+tx_alliswell
+ intrl_handled_nostack
+
+;----------
+tx_acknmra_insert
+ sub_wff acknmra ; we're acking these now
+ mov_wf INDF0 ; write it over the message we just sent
+ bra tx_alliswell
+
+;----------
+tx_acknmra_send
+ sub_wff acknmra ; we're acking these now
+ mov_wf TXREG
+ bra tx_alliswell
+
+;----------
+tx_bufempty
+ ; maybe we send an NMRADONE
+ mov_fw acknmra
+ bra_nz tx_acknmra_send
+ ; nothing at all to do:
+ bc_f PIE1, TXIE
+ call led_black ; we're not transmitting
+ intrl_handled_nostack
+
+;----------------------------------------------------------------------
+serialtxbuf_init @
+ clr_f outmsg_end
+ clr_f outmsg_begin
+ return
+
+;======================================================================
+ include final.inc