chiark / gitweb /
clock speed varies
[trains.git] / detpic / panic.asm
1 ;======================================================================
2 ; panic.asm
3 ;
4 ; This file implements panic_routine, which is called by the
5 ; `panic' macro in panic.inc.  See panic.inc for the functionality
6 ; of `panic'.
7
8         include common.inc
9
10 ;---------------------------------------------------------------------------
11 ; reserved access bank locations
12
13         udata_acs
14
15 ; used in panic routine for temporary storage:
16
17 flash_pattern           res     1
18 morse_counter           res     1
19 register_counter        res     1
20 bit_counter             res     1
21
22 panic_address   res     1       ; condensed form of message start addr.
23 panic_morse     res     1       ; # bytes of morse msg in panic readout
24 panic_regs      res     1       ; # registers in panic readout
25
26 t0l_count       res     1
27 t0h_count       res     1
28
29 ;****************************************************************************
30
31         code
32
33 ;****************************************************************************
34
35 panic_routine
36 ; switch off interrupts and power
37 ; reconfigure timer0 for writing diagnostic msg to the LED
38
39         clr_f    INTCON        ; disable all interrupts EVER
40         bc_f     PORTC,1       ; switch off booster
41
42 ; now we have time to copy the panic message address out of WREG
43 ; (turning off interrupts is urgent (we might get interrupted while
44 ;  panicing which would be bad because we might forget to panic).
45
46         mov_wf   panic_address
47         clr_f    STKPTR         ; avoids stack overruns
48
49 ; re-initialise timer0 config
50         call    read_pic_no
51         bra_z   panic_setup_if_master
52 panic_setup_if_slave
53         morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
54         bra     panic_setup_endif_masterslave
55 panic_setup_if_master
56         morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
57 panic_setup_endif_masterslave
58
59 ; get # bytes of morse msg, # registers in panic readout, message start addr.
60 ; back from condensed message start addr. stored in panic_address
61
62 panic_loop
63         mov_lw  4 ; size of each message's details
64         mul_wf  panic_address
65         mov_ff  PRODL,TBLPTRL           
66         mov_ff  PRODH,WREG
67         add_lw  (morse_messages_start)/256
68         mov_wf  TBLPTRH
69         clr_f   TBLPTRU
70
71         tblrd   *+              ; read 1st byte of error message
72                                 ; (gives # bytes morse, # bytes registers)
73         dw      0xffff ; silicon errata: B4 issue 4
74
75         mov_ff  TABLAT,panic_morse
76         mov_lw  00001111b
77         and_wff panic_morse     ; panic_morse now contains # bytes of morse msgs
78
79         mov_ff  TABLAT,panic_regs
80         mov_lw  01110000b
81         and_wff panic_regs
82         swap_f  panic_regs      ; panic_regs now contains # registers to read
83
84         call    led_black
85         rcall   waiting16
86         rcall   morsemsg        ; transmit morse in red
87         call    led_black
88         rcall   waiting8
89         rcall   waiting4
90         rcall   registermsg     ; transmit contents of registers in 
91                                 ; red(=low) and blue(=high)
92         rcall   waiting16
93         bra     panic_loop
94
95 ;****************************************************************************
96 ; PANIC SUBROUTINES
97
98 morsemsg
99 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
100
101 morse_msg_start
102         clr_f           morse_counter           ; clear loop counter
103
104 morse_loop
105         mov_fw          panic_morse
106         cmp_fw_ifge     morse_counter           ; if loop counter >=panic_morse
107         return                                  ; return to panic
108
109         tblrd           *+
110         mov_ff          TABLAT,flash_pattern
111         rcall           morse_readout
112         inc_f           morse_counter
113         bra             morse_loop
114
115
116 ;--------------------------
117 morse_readout
118
119 ; Flashes the per-pic led and black in a specified pattern.
120 ;
121 ; The pattern is specified as the state for 8 identically-long time
122 ; periods each as long as a morse `dot', encoded into a byte with
123 ; most significant bit first.
124 ;                       On entry                On exit
125 ; W                     any                     undefined
126 ; flash_pattern         flash pattern           preserved
127 ; bit_counter           any                     undefined
128
129         mov_lw          9
130         mov_wf          bit_counter
131         rr_f            flash_pattern
132
133 morse_readout_loop
134         dec_f_ifz       bit_counter             ; done all the bits yet ?
135         return
136         ; No:
137
138         rl_f            flash_pattern           ; top bit goes into N, 
139                                                 ;ie Negative if 1
140         bra_n           morse_readout_if_led_1
141
142 morse_readout_if_led_0
143         call            led_black
144         bra             morse_readout_endif_led
145
146 morse_readout_if_led_1
147         call            led_red
148
149 morse_readout_endif_led
150         rcall           waiting
151         bra             morse_readout_loop
152
153 ;--------------------------
154 ;--------------------------
155 registermsg
156
157 register_msg_start
158         clr_f           register_counter        ; clear loop counter
159
160 register_loop
161         mov_fw          panic_regs
162         cmp_fw_ifge     register_counter        ; if loop counter >=panic_regs
163         return                                  ; return to panic
164
165         tblrd           *+
166
167         mov_fw          TABLAT          ; TABLAT has the 8-bit version
168         mov_wf          FSR0L           ; of the address.  So, 8 bits
169                                         ; go straight into FSR0L.
170
171         mov_lw          0x0f            ; For FSR0H, we see if the
172         mov_fw          FSR0H           ; address XX is >=0x60.
173                                         ; If it is then we meant 0xfXX;
174         mov_lw          0x5f            ; if not then we meant 0x0XX.
175         cmp_fw_ifle     FSR0L           ; (This is just like PIC does
176         clr_f           FSR0H           ; for insns using Access Bank)
177
178         mov_ff          INDF0,flash_pattern
179         rcall           register_readout
180
181         inc_f           register_counter        ;increment loop counter
182
183         rcall           waiting8
184         bra             register_loop
185
186 ;--------------------------
187
188 register_readout
189
190 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
191 ; (black gap between each bit)
192 ;
193 ; The pattern is specified as the state for 8 identically-long time
194 ; periods each as long as a morse `dot', encoded into a byte with
195 ; most significant bit first.
196 ;                       On entry                On exit
197 ; W                     any                     undefined
198 ; flash_pattern         flash pattern           preserved
199 ; bit_counter           any                     undefined
200
201         clr_f   bit_counter             ; clear loop counter
202         rr_f    flash_pattern
203
204
205 register_readout_loop
206         mov_lw          8
207         cmp_fw_ifge     bit_counter             ; if loop counter >=8 (register 
208                                                 ; length), return
209         return
210
211         mov_lw          4
212         cmp_fw_ifne     bit_counter     ; if loop counter !=4 (nybble length), 
213                                         ; skip insertion of extra black space
214         bra             not_nybble_boundary
215         rcall           waiting4
216
217 not_nybble_boundary
218         rl_f            flash_pattern           ; top bit goes into N flag, 
219                                                 ; ie Negative if 1
220         bra_n           register_readout_if_led_1
221
222 register_readout_if_led_0
223         call            led_red
224         bra             register_readout_endif_led
225
226 register_readout_if_led_1
227         call            led_green
228
229 register_readout_endif_led
230         inc_f           bit_counter       ; increment loop counter
231         rcall           waiting
232         call            led_black
233         rcall           waiting
234         bra             register_readout_loop
235
236
237 ;****************************************************************************
238 ; GENERAL SUBROUTINES
239
240 ;----------------------------------------
241 waiting16       rcall   waiting8
242 waiting8        rcall   waiting4
243 waiting4        rcall   waiting2
244 waiting2        rcall   waiting
245 waiting
246 ; waits for a fixed interval, depending on the configuration of TMR0
247
248         bc_f    INTCON,2        ; clear timer0 interrupt bit (p109)
249 ; Interrupt happens on overflow.  So start at 65535-morse_t0cycles:
250         mov_fw  t0h_count
251         mov_wf  TMR0H           ; p107 set high byte of timer0 (buffered,
252                                 ; only actually set when write to tmr0l occurs)
253         mov_fw  t0l_count
254         mov_wf  TMR0L           ; set timer0 low byte - timer now set
255 waiting_loop
256         bt_f_if0 INTCON,TMR0IF          
257         bra     waiting_loop    ; wait for timer0 interrupt
258         return
259
260
261 ;****************************************************************************
262
263         include final.inc