;----------------------------------------------------------------------
; COMMON INCLUDES and BOILERPLATE
- include /usr/share/gputils/header/p18f458.inc
+ include p18f458.inc
radix dec
include panic.inc
include morse+auto.inc
include ../iwjpictest/insn-aliases.inc
-clock equ -1
include ../iwjpictest/clockvaries.inc
include variables+vars.inc
include pindata.inc
+ include program+clocks.inc
+ include i2clib.incm
+
+tickdiv equ 16
+tickdiv_us equ tick_us * tickdiv
;----------------------------------------------------------------------
; Common conventions for function register notation:
-; Master Slave
+; Master Slave
; Registers etc.
-; W Trashed Trashed
-; STATUS Trashed Trashed
-; BSR Not used Not used
-; t Low ISR Low ISR
-; TBLPTR*,TABLAT Low ISR Low ISR
-; FSR0 Low ISR Low ISR
-; FSR1 Low ISR High ISR (detect[1])
-; FSR2 Low ISR High ISR (detect[1])
+; W Trashed Trashed
+; STATUS Trashed Trashed
+; BSR Not used Not used
+; t,u,v Low ISR Low ISR
+; TBLPTR*,TABLAT Low ISR Low ISR
+; PROD* Low ISR Low ISR
+; FSR0 Low ISR Low ISR
+; PCLATU Always set to 0 Not used
+; PCLATH Low ISR Not used
+; t_dolocal Low ISR High ISR
+; FSR1 Low ISR High ISR (detect[1])
+; FSR2 High ISR (nmra[1]) High ISR (detect[1])
+; PORTB Special read handling[2] Used normally
+;
+; Main loop detection scan detection scan
+; High ISR NMRA output I2C service
+; Low ISRs everything else everything else
;
; Trashed May be trashed by any routine anywhere. Saved
; during every ISR entry/exit.
;
-; Low ISR May be used/traashed by any routine run in low-priority
+; Low ISR May be used/trashed by any routine run in low-priority
; interrupt, or any routine run during initialisation.
; May therefore not be used in background loop with
; interrupts enabled. May not be used by high-priority
-; ISR (unless explicitly saved).
+; ISR (unless explicitly saved, eg isrh_fsr0_{save,restore}).
;
; High ISR May be used/trashed by any routine run in high-priority
; interrupt, or any routine run during initialisation.
; saves that register for the benefit of its callers.
;
; [1] FSR1 and FSR2 on slave pics are reserved exclusively for the
-; I2C response and detection code (detect.asm), after det_slave_init.
+; I2C response and detection code (detect.asm), after
+; detect_slave_init. Likewise FSR2 is reserved exclusively
+; for the NMRA output ISR after nmra_init.
+;
+; [2] On the master PIC we the interrupt-on-change feature of PORTB.
+; This means that routines mustn't casually read PORTB. Instead,
+; they should call portb_read from serout.asm.
;
; General-purpose hardware allocation:
;
; Master Slave
; Timer 0 nmra Disabled
-; Timer 2 - -
-; Timer 1 1ms tick, int. low 1ms tick, int. low
-; CCP1 1ms tick, int. low 1ms tick, int. low
+; Timer 2 tick, int. low -
+; Timer 1 - -
+; CCP1 - -
; Timer 3 point fire timer point fire timer
; ECCP - -
+;
+; (...) indicates that this is a projected use, NYI
;----------------------------------------------------------------------
; Conventional routine names:
;
; <periph>_local_do Process a master-to-slave command to activate
-; a local peripheral (also called on master to
-; activate its own local peripherals)
+; a local peripheral, in High ISR. Also called
+; on master in Low ISR to activate its own
+; local peripherals. NB strange calling convention!
;
; <periph>_local_init Initialises RAM tables for local peripheral
; and arranges for pins to be set in appropriate
; quiescent state. Configures pic built-in
; peripherals.
-;
-; <periph>_local_intr Low ISR service routine.
-; Checks for, and clears, any relevant interrupt,
-; and returns with `return'.
;
-; <periph>_master_do Called when an appropriate message has been
+; <periph>_local_intrl Low ISR service routine for peripheral (see below).
+;
+; command_<periph> Called when an appropriate message has been
; received from the host.
;
+; <something>_intrl Low ISR service routine.
+; Checks for any relevant interrupt.
+; If not, just returns
+; If found, services it and then does either
+; intrl_handled or intrl_handled_nostack
+; neither of which return; the latter is
+; faster but implies a promise
+;
;----------------------------------------------------------------------
; MACROS
+@ macro
+ endm
+
+;----------------------------------------
+; For adding a byte to the debug buffer.
+; Not for use in High ISR. In all cases:
+;
+; STATUS any trashed
+; all others any preserved
+
+ ifdef DEBUG
+;----------
+Dv macro ; sorry, but assembler's dw directive isn't case-sensitive
+;
+; W message byte preserved
+;
+ call debugbyte
+ endm
+
+;----------
+Dl macro debug_literal_value
+;
+; W any literal value as specified
+;
+ mov_lw debug_literal_value
+ Dv
+ endm
+
+;----------
+Df macro debug_register_file_address
+;
+; W any value from specified memory location
+;
+ mov_fw debug_register_file_address
+ Dv
+ endm
+ else
+Dv macro
+ endm
+Dl macro debug_literal_value
+ endm
+Df macro debug_register_file_address
+ endm
+ endif
+
;----------------------------------------
; For entering and leaving Low ISR, saving and restoring STATUS and W
+; See above under <something>_intrl, and {master,slave}_interrupt_low
enter_interrupt_low macro
mov_ff STATUS, isr_low_save_status
mov_wf isr_low_save_w
+ mov_ff STKPTR, isr_low_save_stkptr
+ endm
+
+intrh_fsr0_save macro
+ mov_ff FSR0L, isr_high_save_fsr0
+ mov_ff FSR0H, isr_high_save_fsr0+1
endm
-return_interrupt_low macro
+intrh_fsr0_restore macro
+ mov_ff isr_high_save_fsr0, FSR0L
+ mov_ff isr_high_save_fsr0+1, FSR0H
+ endm
+
+intrl_handled_core macro ; for internal use only
mov_fw isr_low_save_w
mov_ff isr_low_save_status, STATUS
retfie
endm
+intrl_handled_nostack macro
+ pop ; undo the `call' from the original ISR
+ intrl_handled_core
+ endm
+
+intrl_handled macro
+ goto intrl_handled_routine
+ endm
+
;----------------------------------------
; For disabling all interrupts, to make a critical section:
; (for use from main program and Low ISR only)
+;
+; GIEH modified appropriately
+; everything else preserved
-mask_int_high macro
+intrh_mask macro
bc_f INTCON,GIEH
endm
-unmask_int_high macro
+intrh_unmask macro
bs_f INTCON,GIEH
endm
;----------------------------------------
; For the fix specified in the silicon errata:
; silicon revision B4 issue 4
+;
+; Before After
+; TABLAT any data from flash
+; TBLPTR* correct incremented/decremented
+; everything else any preserved
tblrd_postinc_fixup macro
tblrd *+
endm
;----------------------------------------
-; For setting up TBLPTR according to the picno
+; For setting up TBLPTR
+
+load_tblptr macro value
+;
+; Before After
+; TBLPTR* any set
+; W, STATUS any undefined
+;
+ mov_lw value & 0xff
+ mov_wf TBLPTRL
+
+ mov_lw value >> 8
+ mov_wf TBLPTRH
+
+ if value > 0xffff
+ mov_lw value >> 16
+ mov_wf TBLPTRU
+ else
+ clr_f TBLPTRU
+ endif
+ endm
load_perpic_tblptr macro flash_map_base, perpic_entry_size
- movlw perpic_entry_size
+;
+; Before After
+; TBLPTR* any set
+; W, STATUS, PROD* any undefined
+; everything else any preserved
+;
+ mov_lw perpic_entry_size
mul_wf picno
mov_lw flash_map_base & 0xff
; and <port> is 0 1 2 3 4 5 6 7. Generally p<picno>_<subsystem>_<pin>
; are equ'd for this.
- radix hex
+ radix hex
p0_cdu_enable equ 5b
p0_rs232_fcin equ 4b
p0_booster_shutdown equ 2b
p0_spare0 equ 0a
p0_booster_dirn equ 0c
p0_booster_pwm equ 1c
- radix dec
+ radix dec
+
+;
+; LAT* may be subject to read-modify-write, see below
+; TRIS* may be subject to read-modify-write, see below
+; PORT* may be read, see below
+; everything else untouched
+;
+; LAT*<bit> TRIS*<bit> PORT*
+; pin_z untouched set untouched
+; pin_h set cleared untouched
+; pin_l cleared cleared untouched
+; pin_nz untouched cleared untouched
+; pin_vh set untouched untouched
+; pin_vl cleared untouched untouched
+; pin_ifh untouched untouched read
+; pin_ifl untouched untouched read
pin_z macro pinspec
bs_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
bc_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
endm
+pin_znz macro pinspec
+ btg_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
+ endm
+
pin_vh macro pinspec
bs_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
endm
bc_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
endm
+pin_vhl macro pinspec
+ btg_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
+ endm
+
pin_h macro pinspec
pin_vh pinspec
pin_nz pinspec
bt_f_if0 PORTA + (PORTB-PORTA)*((pinspec-0xa) & 15), pinspec >> 4
endm
+pinlat_ifh macro pinspec
+ bt_f_if1 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
+ endm
+
+pinlat_ifl macro pinspec
+ bt_f_if0 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
+ endm
+
+pin_inw_ifh macro pinspec
+ bt_w_if1 pinspec >> 4
+ endm
+
+pin_inw_ifl macro pinspec
+ bt_w_if0 pinspec >> 4
+ endm
+
;----------------------------------------------------------------------