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