; 10 10 10 00 | 1110 1110 | 1110 00 10 | 10 10
include common.inc
+ include morse-auto.inc
+ include ../iwjpictest/insn-aliases.inc
+
+ extern led_green
+ extern led_red
+ extern led_black
;---------------------------------------------------------------------------
; reserved access bank locations
-WREG2 equ 00h ; a 2nd working reg :-)
-WREG3 equ 01h ; a 3rd working reg :-)
-WREG4 equ 02h ; a 4th working reg :-)
-BLANK equ 03h ; register full of zeros
-TESTFLASH equ 04h ; test LED flash pattern
+flash_pattern res 1
+morse_counter res 1
+register_counter res 1
+bit_counter res 1
+BLANK res 1 ; register full of zeros
+TESTFLASH res 1 ; test LED flash pattern
+; used in panic macro for temporary storage
+PANIC_ADDRESS res 1 ; stores condensed form of message start addr.
+PANIC_MORSE res 1 ; stores # bytes of morse msg in panic readout
+PANIC_REGS res 1 ; stores # registers in panic readout
;---------------------------------------------------------------------------
; memory location definitions
ERROR_BUF_PAGE equ 3 ; error codes on flash p3
-F_ERROR_U equ 30h ; upper part of error memory locations
-F_SOS_H equ 00h ; high (middle) part of SOS error memory loc.
+F_ERROR_U equ 00h ; upper part of error memory locations
+F_SOS_H equ 40h ; high (middle) part of SOS error memory loc.
F_SOS_L equ 00h ; lower part of SOS error memory loc.
-;---------------------------------------------------------------------------
-; error messages
+;****************************************************************************
-err_SOS equ 0 ; msg 0 = SOS
+ code
;****************************************************************************
- code
+; first, copy the panic message address out of WREG
+
+ mov_wf panic_address
+
+panic_routine
+; switch off interrupts and power
+; reconfigure timer0 for writing diagnostic msg to the LED
+
+ clr_f INTCON ; disable all interrupts EVER
+ bc_f PORTC,1 ; switch off booster
+
+
+; re-initialise timer0 config
+ bc_f T0CON,6 ; p107 Timer0 -> 16bit mode
+ bc_f T0CON,5 ; timer0 use internal clock
+ bc_f T0CON,3 ; use prescaler
+ bc_f T0CON,2 ; }
+ bs_f T0CON,1 ; } prescale value 1:16 (13ms x 16)
+ bs_f T0CON,0 ; }
+
+; get # bytes of morse msg, # registers in panic readout, message start addr.
+; back from condensed message start addr. stored in PANIC_ADDRESS
+
+panic_loop
+ mov_lw 4
+ mul_wf PANIC_ADDRESS
+ mov_ff PRODL,TBLPTRL
+ mov_ff PRODH,WREG
+ add_lw (morse_messages_start)/256
+ mov_wf TBLPTRH
+ clr_f TBLPTRU
+
+ tblrd *+ ; read 1st byte of error message
+ ; (gives # bytes morse, # bytes registers)
+
+ mov_ff TABLAT,PANIC_MORSE
+ mov_lw 00001111b
+ and_wff PANIC_MORSE ; PANIC_MORSE now contains # bytes of morse msgs
+
+ mov_ff TABLAT,PANIC_REGS
+ mov_lw 01110000b
+ and_wff PANIC_REGS
+ swap_f PANIC_REGS ; PANIC_REGS now contains # registers to read
+
+ call led_black
+ call waiting
+ call waiting
+ call waiting
+ call waiting
+ call morsemsg ; transmit SOS in red
+ call led_black
+ call waiting
+ call waiting
+ call waiting
+ call waiting
+ call registermsg ; transmit contents of TESTFLASH in
+ ; red(=low) and blue(=high)
+ goto panic_loop
+
;****************************************************************************
+; PANIC SUBROUTINES
-;----------------------------------------
-readout
-; Flashes the per-pic led red and black in a specified pattern.
+morsemsg
+; wrapper round readout to flash the per-pic led red for a
+; (currently 4-byte) morse msg
+
+morse_msg_start
+ clr_f morse_counter ; clear loop counter
+
+morse_loop
+ mov_fw PANIC_MORSE
+ cmp_fw_ifge morse_counter ; if loop counter >=PANIC_MORSE
+ return ; return to panic
+
+ tblrd *+
+ mov_ff TABLAT,flash_pattern
+ call morse_readout
+ inc_f morse_counter
+ goto morse_loop
+
+
+;--------------------------
+morse_readout
+
+; Flashes the per-pic led red(0) in a specified pattern.
+;
; The pattern is specified as the state for 8 identically-long time
; periods each as long as a morse `dot', encoded into a byte with
; most significant bit first.
-; On entry On exit
-; W any undefined
-; WREG2 flash pattern preserved
-; WREG4 any undefined
-;
- clrf WREG4,0 ; clear loop counter (WREG4)
- rrncf WREG2,1
+; On entry On exit
+; W any undefined
+; flash_pattern flash pattern preserved
+; bit_counter any undefined
-readout_loop
- movlw 8
- cpfslt WREG4,0 ; if loop counter >=8, return
+ clr_f bit_counter ; clear loop counter
+ rr_f flash_pattern
+
+morse_readout_loop
+ mov_fw PANIC_REGS
+ cmp_fw_ifge bit_counter ; if loop counter >=PANIC_REGS, return
return
- rlncf WREG2,1 ; top bit goes into N flag, ie Negative if 1
- bn readout_if_led_on
-readout_if_led_off
- call led_black
- bra readout_endif_led
+ rl_f flash_pattern ; top bit goes into N,
+ ;ie Negative if 1
+ bra_n morse_readout_if_led_1
-readout_if_led_on
- call led_red
-readout_endif_led
- incf WREG4,1,0 ; increment loop counter
- call waiting
- bra readout_loop
+morse_readout_if_led_0
+ call led_black
+ bra morse_readout_endif_led
+morse_readout_if_led_1
+ call led_red
-;****************************************************************************
-; this is what happens when we panic
+morse_readout_endif_led
+ inc_f bit_counter ; increment loop counter
+ call waiting
+ bra morse_readout_loop
-informative_panic
-; switch off interrupts and power
-; reconfigure timer0 for writing diagnostic msg to the LED
+;--------------------------
+;--------------------------
+registermsg
- clrf INTCON,0 ; disable all interrupts EVER
- bcf PORTC,1,0 ; switch off booster
+register_msg_start
+ clr_f register_counter ; clear loop counter
- movlw 10101100b
- movwf TESTFLASH
+register_loop
+ mov_fw PANIC_REGS
+ cmp_fw_ifge register_counter ; if loop counter >=PANIC_REGS
+ return ; return to panic
+ tblrd *+
+
+ mov_fw TABLAT ; TABLAT has the 8-bit version
+ mov_wf FSR0L ; of the address. So, 8 bits
+ ; go straight into FSR0L.
+
+ mov_lw 0x0f ; For FSR0H, we see if the
+ mov_fw FSR0H ; address XX is >=0x60.
+ ; If it is then we meant 0xfXX;
+ mov_lw 0x5f ; if not then we meant 0x0XX.
+ cmp_fw_ifle FSR0L ; (This is just like PIC does
+ clr_f FSR0H ; for insns using Access Bank)
+
+ mov_ff INDF0,flash_pattern
+ call register_readout
+
+ inc_f register_counter ;increment loop counter
+
+ call waiting
+ call waiting
+ goto register_loop
+
+;--------------------------
+
+register_readout
+
+; Flashes the per-pic led red(0) and green(1) in a specified pattern.
+; (black gap between each bit)
+;
+; The pattern is specified as the state for 8 identically-long time
+; periods each as long as a morse `dot', encoded into a byte with
+; most significant bit first.
+; On entry On exit
+; W any undefined
+; flash_pattern flash pattern preserved
+; bit_counter any undefined
+
+ clr_f bit ; clear loop counter
+ rr_f flash_pattern
+
+
+register_readout_loop
+ movlw 8
+ cmp_fw_ifge bit_counter ; if loop counter >=8 (register
+ ; length), return
+ return
+
+ movlw 4
+ cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
+ ; skip insertion of extra black space
+ goto not_nybble_boundary
+ call waiting
+
+not_nybble_boundary
+ rlncf flash_pattern,1 ; top bit goes into N flag,
+ ; ie Negative if 1
+ bn register_readout_if_led_1
+
+register_readout_if_led_0
+ call led_red
+ bra register_readout_endif_led
+
+register_readout_if_led_1
+ call led_green
+
+register_readout_endif_led
+ inc_f bit_counter,1 ; increment loop counter
+ call waiting
+ call led_black
+ call waiting
+ bra register_readout_loop
-; re-initialise timer0 config
- bcf T0CON,6,0 ; p107 Timer0 -> 16bit mode
- bcf T0CON,5,0 ; timer0 use internal clock
- bcf T0CON,3,0 ; use prescaler
- bsf T0CON,2,0 ; }
- bcf T0CON,1,0 ; } prescale value 1:32 (13ms x 32)
- bcf T0CON,0,0 ; }
-
- clrf BLANK,0
-panic_loop
-; errmsg err_SOS,0 ; transmit SOS in red
- movff TESTFLASH,WREG2
- rcall readout
-; readout BLANK,0 ; transmit blank buffer
- call led_green
- call waiting
- goto panic_loop
;****************************************************************************
; GENERAL SUBROUTINES
waiting
; waits for a fixed interval, depending on the configuration of TMR0
- bcf INTCON,2,0 ; clear timer0 interrupt bit (p109)
- clrf TMR0H,0 ; p107 set high byte of timer0 to 0 (buffered,
+ bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
+ clr_f TMR0H ; p107 set high byte of timer0 to 0 (buffered,
; only actually set when write to tmr0l occurs)
- clrf TMR0L,0 ; set timer0 low byte - timer now set to 0000h
+ clr_f TMR0L ; set timer0 low byte - timer now set to 0000h
loop
- btfss INTCON,2,0 ; check whether timer0 interrupt has been set -
- ; skip next instruction if so
- bra loop
+ bt_f_if0 INTCON,TMR0IF
+ bra loop ; wait for timer0 interrupt
return