chiark / gitweb /
undo broken deletion
[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         call    led_green ; we're transmitting
68         bs_f    PIE1, TXIE
69         return
70
71 ;----------
72 txfc_disable
73         bc_f    PIE1, TXIE
74         goto    led_red ; flow control forces us not to transmit
75
76 ;----------------------------------------------------------------------
77 serialtxfc_intrl @
78         bt_f_if0 INTCON, RBIF
79         return
80         ; yes, it's us:
81
82         rcall   portb_read ; check flow control
83         intrl_handled_nostack
84
85 ;----------------------------------------------------------------------
86 serialtxfc_init @
87         bc_f    INTCON2, RBIP
88         bs_f    INTCON, RBIE
89         rcall   portb_read
90         pin_l   p0_rs232_fcout ; set outgoing RTS/CTS active
91         return
92
93 ;======================================================================
94 ; ACTUAL TRANSMISSION
95
96 ;----------------------------------------------------------------------
97 serialtx_intrl @
98         ; are we ready to transmit ?
99         bt_f_if0 PIR1, TXIF
100         return
101         bt_f_if0 PIE1, TXIE
102         return
103         ; yes, it's us:
104
105         mov_lfsr outbuf, 0
106         mov_fw  outmsg_begin
107         mov_wf  FSR0L
108         xor_wfw outmsg_end
109         bra_z   tx_bufempty
110
111         mov_fw  INDF0
112         mov_wf  TXREG
113         bra_n   tx_justsent_noacknmra
114         ; we've just sent the last byte of some message:
115         ; maybe we push an NMRADONE message on the front
116         mov_fw  acknmra
117         bra_nz  tx_acknmra_insert
118 tx_justsent_noacknmra
119         inc_f   outmsg_begin
120         bc_f    outmsg_begin, outbuf_szln2
121         call    i2c_consider_restartread
122 tx_alliswell
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         return
152
153 ;======================================================================
154   include final.inc