; Template for Implantable Stimulator-Transponder (A3041) User Program.

; The user program must end with a ret instruction. All registers have
; been pushed onto the stack before execution, so the user program does
; not have to push or pop any of them. Upon first execution of the 
; user program, the User Program Initialize flag (UPinit) will be set,
; allowing the program to perform initialization before clearing the flag.
; The user program variable memory range is given by the CPU address map.
; The user program executes in the user program interrupt, which occurs
; with period written to mmu_it3p. The initial value of the period is
; uprog_tick. The user program can change its execution period, but if
; we set the period to less than min_int_p, the device will hand up 
; executing the user program and be unable to respond to commands.

; This example program displays the extinguish counter value on an 
; SCT channel. We can view this counter at the same time as the
; synchronizing signal and while executing stimuli.

; CPU Address Map Boundary Constants
const mmu_vmem 0x0000 ; Base of Main Program Variable Memory
const mmu_sba  0x0100 ; Stack Base Address
const mmu_umem 0x0200 ; Base of User Program Variable Memory
const mmu_ctrl 0x0400 ; Base of Control Space
const mmu_prog 0x0800 ; Base of user program memory window

; Address Map Locations
const mmu_sdb  0x0400 ; Sensor Data Byte (Write)
const mmu_scr  0x0401 ; Sensor Control Register (Write)
const mmu_irqb 0x0402 ; Interrupt Request Bits (Read)
const mmu_imsk 0x0403 ; Interrupt Mask Bits (Read/Write)
const mmu_irst 0x0404 ; Interrupt Reset Bits (Write)
const mmu_dva  0x0405 ; Device Active (Write)
const mmu_stc  0x0406 ; Stimulus Current (Write)
const mmu_rst  0x0407 ; System Reset (Write)
const mmu_xhb  0x0408 ; Transmit HI Byte (Write)
const mmu_xlb  0x0409 ; Transmit LO Byte (Write)
const mmu_xch  0x040A ; Transmit Channel Number (Write)
const mmu_xcr  0x040B ; Transmit Control Register (Write)
const mmu_etc  0x040D ; Enable Transmit Clock (Write)
const mmu_tcf  0x040E ; Transmit Clock Frequency (Write)
const mmu_tcd  0x040F ; Transmit Clock Divider (Write)
const mmu_bcc  0x0410 ; Boost CPU Clock (Write)
const mmu_dfr  0x0411 ; Diagnostic Flag Register (Read/Write)
const mmu_sr   0x0412 ; Status Register (Read)
const mmu_cmp  0x0413 ; Command Memory Portal (Read)
const mmu_cpr  0x0415 ; Command Processor Reset (Write)
const mmu_i1ph 0x0416 ; Interrupt Timer One Period HI (Write)
const mmu_i1pl 0x0417 ; Interrupt Timer One Period LO (Write)
const mmu_i2ph 0x0418 ; Interrupt Timer Two Period HI (Write)
const mmu_i2pl 0x0419 ; Interrupt Timer Two Period LO (Write)
const mmu_i3p  0x041A ; Interrupt Timer Three Period (Write)
const mmu_i4p  0x041B ; Interrupt Timer Four Period (Write)
const mmu_idh  0x041C ; Device ID HI (Read)
const mmu_idl  0x041D ; Device ID LO (Read)
const mmu_ver  0x041E ; Device Version (Read)

; Status Bit Masks, for use with status register
const sr_cmdrdy  0x01 ; Command Ready Flag
const sr_entck   0x02 ; Transmit Clock Enabled
const sr_saa     0x04 ; Sensor Access Active Flag
const sr_txa     0x08 ; Transmit Active Flag
const sr_cpa     0x10 ; Command Processor Active
const sr_boost   0x20 ; Boost Flag
const sr_cme     0x40 ; Command Memory Empty

; Transmit Control Masks, for use with tansmit control register
const tx_txi     0x01 ; Assert transmit initiate
const tx_txwp    0x02 ; Assert transmit warm-up

; Auxiliary message types.
const at_id         1 ; Identification
const at_ack        2 ; Acknowledgements
const at_batt       3 ; Battery Measurement
const at_conf       4 ; Confirmation
const at_ver        5 ; Version

; Bit Masks
const bit0_mask  0x01 ; Bit Zero Mask
const bit1_mask  0x02 ; Bit One Mask
const bit2_mask  0x04 ; Bit Two Mask
const bit3_mask  0x08 ; Bit Three Mask
const bit7_mask  0x80 ; Bit Seven Mask
const bit0_clr   0xFE ; Bit Zero Clear
const bit1_clr   0xFD ; Bit One Clear
const bit2_clr   0xFB ; Bit Two Clear
const bit3_clr   0xF7 ; Bit Three Clear

; Timing Constants.
const min_tcf       72 ; Minimum TCK periods per half RCK period
const tx_delay      50 ; Wait time for sample transmission, TCK periods
const sa_delay      30 ; Wait time for sensor access, TCK periods
const wp_delay     255 ; Warm-up delay for auxiliary messages
const num_vars      64 ; Number of vars to clear at start
const initial_tcd   15 ; Max possible value of TCK divisor
const uprog_tick   163 ; User program interrupt period
const id_delay      33 ; To pad id delay to 50 TCK periods
const min_int_p     25 ; Minimum transmit period
const shdn_rst     250 ; Shutdown counter reset value.

; Stimulus Control Variables
const Scurrent    0x0000 ; Stimulus Current
const Spulse1     0x0001 ; Pulse Length, HI
const Spulse0     0x0002 ; Pulse Length, LO
const Sint1       0x0003 ; Interval Length, HI
const Sint0       0x0004 ; Interval Length, LO
const Slen1       0x0005 ; Stimulus Length, HI
const Slen0       0x0006 ; Stimulus Length, LO
const Srand       0x0007 ; Random pulse timing
const Srun        0x0008 ; Run stimulus
const Spulse      0x0009 ; Stimulus Pulse Run Flag
const Sack_key    0x000A ; Acknowledgement key
const Sdly1       0x000B ; Stimulus Delay Byte One
const Sdly0       0x000C ; Stimulus Delay Byte Zero
const Sdelay      0x000D ; Stimulus Delay Run Flag
const Smaxdly1    0x000E ; Max Delay, HI
const Smaxdly0    0x000F ; Max Delay, LO

; Command Decode Variables
const ccmdb       0x0016 ; Copy of Command Byte

; Shutdown counter.
const shdncnt1    0x0019 ; Counter Byte One
const shdncnt0    0x001A ; Counter Byte Zero

; Random Number Variabls
const rand_1      0x0020 ; Random Number Byte One
const rand_0      0x0021 ; Random Number Byte Zero

; User Program Control Variables
const UPrun       0x0022 ; Running
const UPinit      0x0023 ; Initialize

; Transmission Control Variables
const xmit_p      0x0028 ; Transmit Period
const xmit_ch     0x0029 ; Telemetry Channel Number

; User Program Constants
const prog_usr    0x0800 ; User program location
const ret_code      0x0A ; Return from subrouting instruction

; Operation Codes
const op_stop        0 ; 0 operands
const op_start       1 ; 8 operands
const op_xon         2 ; 2 operand
const op_xoff        3 ; 0 operands
const op_batt        4 ; 0 operands
const op_id          5 ; 0 operands
const op_pgld        6 ; 1 operand, variable data
const op_pgon        7 ; 0 operands
const op_pgoff       8 ; 0 operands
const op_pgrst       9 ; 0 operands
const op_shdn       10 ; 0 operands
const op_ver        11 ; 0 operands

; Synchronization.
const synch_nostim  32 ; 
const synch_stim    96 ;

; Random Number Generator.
const rand_taps   0xB4 ; Determines which taps to XOR.

; ----------------------------------------------------
; START USER PROGRAM. MUST TERMINATE WITH "RET".
; ----------------------------------------------------

user_program:

const ch_num 65  ; Telemetry channel number for our use.

ld A,(mmu_dfr)   ; Load diagnostic flag register
or A,bit1_mask   ; and set bit one to
ld (mmu_dfr),A   ; drive TP2 high.

ld A,(shdncnt0)  ; Read low byte of shutdown counter
ld (mmu_xlb),A   ; and load into transmit low byte.
ld A,(shdncnt1)  ; Read high byte of shutdown counter
ld (mmu_xhb),A   ; and load into transmit high byte.
ld A,ch_num      ; Write channel number
ld (mmu_xch),A   ; to transmit register.
ld (mmu_xcr),A   ; Initiate transmission.

ld A,(mmu_dfr)   ; Load diagnostic flag register
and A,bit1_clr   ; and clear bit one to
ld (mmu_dfr),A   ; drive TP2 low.

ret              ; Return to calling process.
