chiark / gitweb /
set TXIE in PIE not IPR or PIR(!) also get sense of flow control right
[trains.git] / detpic / serout.asm
1 ;======================================================================
2 ; SERIAL PORT - TRANSMISSION TO HOST
3
4   include common.inc
5   code
6
7 ;======================================================================
8 ; QUEUEING MESSAGES FOR TRANSMISSION
9
10 ;----------
11 addbyte_toomany panic morse_HB
12
13 ;----------------------------------------
14 serial_addbyte @
15 ;  W                    byte to xmit to host    trashed
16 ;  FSR0                 any                     set for serial_addbyte_another
17 ;  outbuf, outmsg_*     buffer not full         adjusted appropriately
18 ;  STATUS               any                     trashed
19 ;  all others           any                     not interfered with
20 ;
21         mov_lfsr outbuf, 0
22         mov_ff  outmsg_end, FSR0L
23 ;...
24 ;----------------------------------------
25 serial_addbyte_another @
26 ;  W                    byte to xmit to host    trashed
27 ;  FSR0                 from _addbyte[_another] updated for ..._another again
28 ;  outbuf, outmsg_*     buffer not full         adjusted appropriately
29 ;  STATUS               any                     trashed
30 ;  all others           any                     not interfered with
31 ;
32         mov_wf  POSTINC0
33         bc_f    FSR0L, 7
34         mov_fw  FSR0L
35         mov_wf  outmsg_end
36         xor_wfw outmsg_begin
37         bra_z   addbyte_toomany
38         ; no, we're ok:
39
40         bt_f_if1 PIE1, TXIE
41         return ; don't bother messing about if tx is already enabled
42
43 ; we fall through to portb_read to reenable TXIE if appropriate
44 ;...
45 ;======================================================================
46 ; FLOW CONTROL BY HOST OF OUR TRANSMISSIONS
47
48 ;...
49 ;----------------------------------------
50 portb_read @
51 ;
52 ;  W                    undefined       value from PORTB
53 ;  TXIE                 any             enabled iff host allows us to xmit
54 ;
55 ; Note that this will reenable TXIE even if the serial buffer is empty,
56 ; every time portb_read is called.  This doesn't matter very much
57 ; because the serialtx_intrl routine will disable it again straight
58 ; away.
59 ;
60         mov_fw  PORTB
61         bc_f    INTCON, RBIF
62
63         bt_w_if1  p0_rs232_fcin >> 4
64         bra     txfc_disable
65         ; tx enable:
66
67         bs_f    PIE1, TXIE
68         return
69
70 ;----------
71 txfc_disable
72         bc_f    PIE1, TXIE
73         goto    led_red ; flow control forces us not to transmit
74
75 ;----------------------------------------------------------------------
76 serialtxfc_intrl @
77         bt_f_if0 INTCON, RBIF
78         return
79         ; yes, it's us:
80
81         rcall   portb_read ; check flow control
82         intrl_handled_nostack
83
84 ;----------------------------------------------------------------------
85 serialtxfc_init @
86         bc_f    INTCON2, RBIP
87         bs_f    INTCON, RBIE
88         rcall   portb_read
89         pin_l   p0_rs232_fcout ; set outgoing RTS/CTS active
90         return
91
92 ;======================================================================
93 ; ACTUAL TRANSMISSION
94
95 ;----------------------------------------------------------------------
96 serialtx_intrl @
97         ; are we ready to transmit ?
98         bt_f_if0 PIR1, TXIF
99         return
100         bt_f_if0 PIE1, TXIE
101         return
102         ; yes, it's us:
103
104         mov_lfsr outbuf, 0
105         mov_fw  outmsg_begin
106         mov_wf  FSR0L
107         xor_wfw outmsg_end
108         bra_z   tx_bufempty
109
110         mov_fw  INDF0
111         mov_wf  TXREG
112         bra_n   tx_justsent_noacknmra
113         ; we've just sent the last byte of some message:
114         ; maybe we push an NMRADONE message on the front
115         mov_fw  acknmra
116         bra_nz  tx_acknmra_insert
117 tx_justsent_noacknmra
118         inc_f   outmsg_begin
119         bc_f    outmsg_begin, outbuf_szln2
120         call    i2c_consider_restartread
121 tx_alliswell
122         call    led_green ; we're transmitting
123         intrl_handled_nostack
124
125 ;----------
126 tx_acknmra_insert
127         sub_wff acknmra ; we're acking these now
128         mov_wf  INDF0 ; write it over the message we just sent
129         bra     tx_alliswell
130
131 ;----------
132 tx_acknmra_send
133         sub_wff acknmra ; we're acking these now
134         mov_wf  TXREG
135         bra     tx_alliswell
136
137 ;----------
138 tx_bufempty
139         ; maybe we send an NMRADONE
140         mov_fw  acknmra
141         bra_nz  tx_acknmra_send
142         ; nothing at all to do:
143         bc_f    PIE1, TXIE
144         call    led_black ; we're not transmitting
145         intrl_handled_nostack
146
147 ;----------------------------------------------------------------------
148 serialtxbuf_init @
149         clr_f   outmsg_end
150         clr_f   outmsg_begin
151         mov_lw  b'00001001'
152         goto    serial_addbyte
153
154 ;======================================================================
155   include final.inc