--- /dev/null
+; 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
+
+ code
+
+ goto initialise_serial
+
+
+; interrupt routine call - this needs to be at 000018h (low priority interrupt)
+
+ goto interrupt_check
+
+
+initialise_serial
+
+; 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)
+ bsf 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
+ bsf PIE1,5,0 ; enable USART receive interrupt (p85)
+ bsf IPR1,5,0 ; set to low-priority interrupt
+
+
+; LED pin (21) initialisation
+ bcf TRISE,4,0 ; turn off PSPMODE (Data Sheet p100/101)
+
+
+; timer0 initial config
+ bcf T0CON,6,0 ; p107 Timer0 -> 16bit mode
+ bcf T0CON,5,0 ; timer0 use internal clock
+ bcf INTCON,5,0 ; clear TMR0IE => mask interrupt
+ bcf T0CON,3,0 ; use prescaler
+ bcf T0CON,2,0 ; }
+ bsf T0CON,1,0 ; } prescale value 1:8 (13ms x 8)
+ bcf T0CON,0,0 ; }
+
+
+main
+ call led_green
+ call waiting
+ call led_black
+ call waiting
+ goto main
+
+
+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
+
+
+waiting
+ bcf INTCON,2,0 ; clear timer0 interrupt bit (p109)
+ clrf TMR0H,0 ; p107 set high bit of timer0 to 0 (buffered,
+ ; so only actually set when write to tmr0l occurs)
+ clrf TMR0L,0 ; set low bit o timer0 - timer now set to 0000h
+loop
+ btfss INTCON,2,0 ; check whethr tiomer0 interrupt has been set -
+ ; skip next instruction if so
+ bra loop
+ return
+
+
+
+
+interrupt_check
+ btfss PIR1,5,0 ; check whether serial receive interrupt bit set
+ retfie ; return from interrupt to main if spurious interrupt
+ call led_red
+ clrf WREG ; clear working register
+ movff RCREG,WREG ; read data out of serial receive buffer -> WREG
+ incf WREG ; increment WREG
+ movff WREG,TXREG ; write data out of WREG -> serial transmit buffer
+ retfie
+
+
+ end