chiark / gitweb /
Send HELLO as a result of all slaves being online. Do not crash if slave is slow...
[trains.git] / detpic / serout.asm
index 4b3011a920482f82a197042bb8eb1005238fbd9f..16e545fa6074d456d7c7f9cfa757c000f0d6bccf 100644 (file)
@@ -1,10 +1,17 @@
 ;======================================================================
 ; SERIAL PORT - TRANSMISSION TO HOST
 
- include common.inc
- code
+  include common.inc
+  code
+
+;======================================================================
+; QUEUEING MESSAGES FOR TRANSMISSION
+
+;----------
+addbyte_toomany panic morse_HB
+
 ;----------------------------------------
-serial_addbyte
+serial_addbyte @
 ;  W                   byte to xmit to host    trashed
 ;  FSR0                        any                     set for serial_addbyte_another
 ;  outbuf, outmsg_*    buffer not full         adjusted appropriately
@@ -14,7 +21,8 @@ serial_addbyte
        mov_lfsr outbuf, 0
        mov_ff  outmsg_end, FSR0L
 ;...
-serial_addbyte_another
+;----------------------------------------
+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
@@ -25,10 +33,122 @@ serial_addbyte_another
        bc_f    FSR0L, 7
        mov_fw  FSR0L
        mov_wf  outmsg_end
-       cmp_fw_ifne outmsg_begin
+       xor_wfw outmsg_begin
+       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
+
+;----------
+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
-       ; too many
-       panic morse_HB
 
 ;======================================================================
- include final.inc
 include final.inc