--- /dev/null
+; This program copies the values of flash memory bytes 20 0000h and
+; 20 0001h into program memory an then transmits them over the
+; serial port
+
+
+; pin 21 (per-pic-led, RD2/PSP2/C1IN) states:
+; high H = green, low L = red, float Z = black
+
+
+
+ include /usr/share/gputils/header/p18f458.inc
+
+
+; reserved for NMRA:
+NMRACTRL equ 0x4 ; byte 4: state relevant to NMRA control
+TRANSMITBIT equ 0x7 ; bit 7: 0/1 bit currently being transmitted
+NEXTACTION equ 0x6 ; bit 6: change polarity on next interrupt y/n
+
+FROMSERIAL equ 0x1 ; byte 1: from-serial buffer location (in BSR5)
+TOTRACK equ 0x2 ; byte 2: to-track buffer location (in BSR5)
+TOTRACKBIT equ 0x3 ; byte 3: bit location of pointer within byte
+
+NMRA_BUFF_PAGE equ 5
+
+; flash locations for PIC-dependent info:
+
+F_PIC_NO_U equ 20h ; flash location of PIC number
+F_PIC_NO_H equ 00h
+F_PIC_NO_L equ 00h
+
+F_I2C_CTRL_U equ 20h ; flash location of i2c control byte
+F_I2C_CTRL_H equ 00h
+F_I2C_CTRL_L equ 01h
+
+; i2c specifit stuff
+
+I2C_BUFF_PAGE equ 4 ; put i2c relevant stuff into buffer page 4
+PIC_NO equ 00h ; pic no goes to 400h
+I2C_CTRL equ 01h ; i2c ctrl bit goes to 401h
+
+
+
+
+ ifdef SLOW_VERSION
+ messg "hello this is the slow version"
+ endif
+
+ ifndef SLOW_VERSION
+ messg "hello this is the fast version"
+ endif
+
+ ifdef SLOW_VERSION
+ messg "with an if"
+ else
+ messg "and an else"
+ endif
+
+ org 0
+ goto initialise
+
+;****************************************************************************
+
+; high priority interrupt
+
+ org 000008h
+ goto interrupt_high
+
+; low priority interrupt
+
+ org 000018h
+ goto interrupt_low
+
+;****************************************************************************
+
+ code
+
+;****************************************************************************
+
+macros
+
+; macro to call subroutine to transmit over serial port for debugging
+; takes 8-bit value, puts in W, invokes debug_serial_transmit
+
+ ifndef SLOW_VERSION
+debug macro debugvalue
+ endm
+ endif
+
+ ifdef SLOW_VERSION
+debug macro debugvalue
+ movlw debugvalue
+ call debug_serial_transmit
+ endm
+ endif
+
+debug_serial_transmit
+ movwf TXREG,0 ; move contents of W (i.e. debugvalue)
+ ; to TXREG for transmission
+waitfortsr
+ btfss TXSTA,1,0
+ bra waitfortsr
+ return
+
+;****************************************************************************
+
+initialise
+
+; serial set-up
+
+; initial config - TXSTA register p181
+ bcf TXSTA,6,0 ; p181, set 8-bit mode
+ bsf TXSTA,5,0 ; transmit enable
+ bcf TXSTA,4,0 ; asynchronous mode
+ bsf TXSTA,2,0 ; set high baud rate
+
+; initial config - RCSTA register p182
+ bsf RCSTA,7,0 ; serial port enable (p182)
+ bcf RCSTA,6,0 ; 8-bit reception
+ bsf RCSTA,4,0 ; enable continuous receive
+
+; set SPBRG to get correct baud rate according to table top right p186
+; (Tosc = 20MHz, desired baud rate = 9600)
+ bsf SPBRG,7,0
+ bsf SPBRG,0,0
+
+
+; interrupt set-up for serial receive
+ bcf IPR1,5,0 ; set to low-priority interrupt
+
+
+;----------------------------------------------------------------------------
+
+; copy PIC-dependent info out of flash memory
+
+ movlw F_PIC_NO_U ; set table pointer to point to
+ movwf TBLPTRU ; PIC number in flash
+ movlw F_PIC_NO_H
+ movwf TBLPTRH
+ movlw F_PIC_NO_L
+ movwf TBLPTRL
+
+ tblrd *+ ; read then increment pointer
+ ; (now points to i2c control byte)
+
+ movlb I2C_BUFF_PAGE ; ser BSR=i2c BSR (4)
+ movf TABLAT,0,0 ; move pic number into normal memory
+ movwf PIC_NO,1
+
+ tblrd * ; read i2c
+
+ movff TABLAT, I2C_CTRL ; move i2c_ctrl byte into normal memory
+
+; now have: PIC number in 400h, i2c control byte in 401h
+
+
+;----------------------------------------------------------------------------
+
+; interrupt set-up
+
+; globally enable interrupts - p77
+ bsf RCON,7,0 ; enable priority levels
+ bsf INTCON,7,0 ; enable high-priority interrupts
+ bsf INTCON,6,0 ; enable low-priority interrupts
+ bsf PIE1,5,0 ; enable USART receive interrupt (p85)
+
+
+;****************************************************************************
+
+ call led_green
+main_loop_led
+ movlb I2C_BUFF_PAGE ; ser BSR=i2c BSR (4)
+ movf PIC_NO,0,1
+ movwf TXREG,0
+ call waitfortsr
+ movf I2C_CTRL,0,1
+ movwf TXREG,0
+ call waitfortsr
+ goto main_loop_led
+
+
+;****************************************************************************
+
+interrupt_high
+ debug 'H'
+ goto panic
+
+
+;****************************************************************************
+
+interrupt_low
+
+; check which interrupt.
+ debug 'L'
+ goto panic
+; serial only?
+
+
+;****************************************************************************
+
+serial_receive
+ debug 'S'
+ goto panic
+
+;****************************************************************************
+
+
+led_green
+ bcf TRISD,2,0 ; make pin RD2 an output (DS100)
+ bsf LATD,2,0 ; set pin RD2 H (green)
+ return
+
+led_black
+ bsf TRISD,2,0 ; make pin RD2 an input (i.e. set Z, black)
+ ; (DS100)
+ return
+
+led_red
+ bcf TRISD,2,0 ; make pin RD2 an output (DS100)
+ bcf LATD,2,0 ; set pin RD2 L (red)
+ return
+
+
+panic
+ debug 'x'
+ clrf INTCON,0 ; disable all interrupts EVER
+ debug 'y'
+ bcf PORTC,1,0 ; switch off booster
+ debug 'z'
+ call led_red
+panic_loop
+ goto panic_loop
+
+;****************************************************************************
+
+ end