; RA0: Demux A
; RA1: Demux B
; RA2: Demux C
; RA3: Demux D
; RA4: Button in
; RB0:
; RB1:
; RB2:
; RB3: Latch clock
; RB4: Shift register clock
; RB5: Shift register data
; RB6: Programmer
; RB7: Programmer

list p=16f84a
	__CONFIG 0x3FF2
r_tmr0   equ 0x01
r_pcl    equ 0x02
r_porta  equ 0x05
r_portb  equ 0x06
r_trisa  equ 0x05
r_trisb  equ 0x06
r_status equ 0x03
r_intcon equ 0x0B	; bank1 and 2
r_option equ 0x01	; bank2

; memory from 0x0C->0x4F
m_curchar equ 0x0C
m_currow  equ 0x0D
m_curdata equ 0x0E
m_st_temp equ 0x0F
m_w_temp  equ 0x10
m_count1  equ 0x11
m_count2  equ 0x12

st_rp0   equ 5
st_z     equ 2
op_t0cs  equ 5
op_t0se  equ 4
op_psa   equ 3
op_ps2   equ 2
op_ps1   equ 1
op_ps0   equ 0
ic_t0ie  equ 5
ic_t0if  equ 2
ic_gie   equ 7
	
	org	0x000
	goto	Boot

	org	0x004
	goto	Interrupt
	
; 6 byte numerals
table
numbers	addwf	r_pcl, f
; number 0			[76543210]
	retlw	0x78	;	[ **** XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x78	;	[ **** XX]
; number 1			[76543210]
	retlw	0x30	;	[  **  XX]
	retlw	0x50	;	[ * *  XX]
	retlw	0x10	;	[   *  XX]
	retlw	0x10	;	[   *  XX]
	retlw	0x10	;	[   *  XX]
	retlw	0xFC	;	[******XX]
; number 2			[76543210]
	retlw	0xF8	;	[***** XX]
	retlw	0x04	;	[     *XX]
	retlw	0x18	;	[   ** XX]
	retlw	0x60	;	[ **   XX]
	retlw	0x80	;	[*     XX]
	retlw	0xFC	;	[******XX]
; number 3			[76543210]
	retlw	0xF8	;	[***** XX]
	retlw	0x04	;	[     *XX]
	retlw	0x38	;	[  *** XX]
	retlw	0x04	;	[     *XX]
	retlw	0x04	;	[     *XX]
	retlw	0xF8	;	[***** XX]
; number 4			[76543210]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0xFC	;	[******XX]
	retlw	0x04	;	[     *XX]
	retlw	0x04	;	[     *XX]
	retlw	0x04	;	[     *XX]
; number 5	"		[76543210]
	retlw	0xFC	;	[******XX]
	retlw	0x80	;	[*     XX]
	retlw	0xF8	;	[***** XX]
	retlw	0x04	;	[     *XX]
	retlw	0x04	;	[     *XX]
	retlw	0xF8	;	[***** XX]
; number 6			[76543210]
	retlw	0x7C	;	[ *****XX]
	retlw	0x80	;	[*     XX]
	retlw	0xF8	;	[***** XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x78	;	[ **** XX]
; number 7			[76543210]
	retlw	0xFC	;	[******XX]
	retlw	0x04	;	[     *XX]
	retlw	0x08	;	[    * XX]
	retlw	0x10	;	[   *  XX]
	retlw	0x20	;	[  *   XX]
	retlw	0x40	;	[ *    XX]
; number 8			[76543210]
	retlw	0x78	;	[ **** XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x78	;	[ **** XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x78	;	[ **** XX]
; number 9			[76543210]
	retlw	0x78	;	[ **** XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x84	;	[*    *XX]
	retlw	0x7C	;	[ *****XX]
	retlw	0x04	;	[     *XX]
	retlw	0xF8	;	[***** XX]
; number 10			[76543210]
	retlw	0x98	;	[*  ** XX]
	retlw	0xA4	;	[* *  *XX]
	retlw	0xA4	;	[* *  *XX]
	retlw	0xA4	;	[* *  *XX]
	retlw	0xA4	;	[* *  *XX]
	retlw	0x98	;	[*  ** XX]

Boot
	; Set up porta/portb 
	bsf	r_status, st_rp0
	movlw	0x10			;; Button in, and that's it
	movwf	r_trisa
	movlw	0x00			;; All outputs
	movwf	r_trisb
	bcf	r_status, st_rp0
	
	; Set up TMR0
	bsf	r_status, st_rp0
	bcf	r_option, op_t0cs	; select 'timer' mode from int clk
	bcf	r_option, op_psa	; prescale enable
	bsf	r_option, op_ps2	; prescale 255
	bsf	r_option, op_ps1	; prescale 255
	bsf	r_option, op_ps0	; prescale 255
	; Fosc:		20000000
	; /4:		/4
	; Prescaler:	/256
	; ______________________
	;               19531.25 Hz
	; Counter1:	76.29hz
	bcf	r_status, st_rp0
	movlw	0x00
	movwf	r_tmr0
	bsf	r_intcon, ic_t0ie
	bcf	r_intcon, ic_t0if
	bsf	r_intcon, ic_gie
	

	movlw	d'10'
	movwf	m_curchar
	movlw	6
	movwf	m_currow
Loop
	movfw	m_currow
	addlw	d'255'			;; that's a euphemism for 'subtract 1'
	movwf	m_currow
	call	BlitRow
	movfw	m_currow
	addlw	0
	btfsc	r_status, 2		;; bit 2 is st_z
	movlw	0x06			;; ok reset it if we hit zero
	movwf	m_currow
	goto	Loop			;; done

BlitRow
	movfw	m_curchar		;; Every char is 6 rows long
	addwf	m_curchar,w
	addwf	m_curchar,w
	addwf	m_curchar,w
	addwf	m_curchar,w
	addwf	m_curchar,w
	addwf	m_currow,w
	call	numbers			;; Row data now in w
	movwf	m_curdata		;; ... and in curdata
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f

	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x00
	btfsc	m_curdata, 7
	movlw	0x20
	movwf	r_portb
	addlw	0x10
	movwf	r_portb
	rlf	m_curdata,f
	
	movlw	0x08	;; Latch
	movwf	r_portb
	movlw	0x00	;; latch
	movwf	r_portb
	
	movfw	m_currow
	movwf	r_porta
	return

Interrupt
	movwf	m_w_temp
	swapf	r_status, w
	movwf	m_st_temp
	
	bcf	r_status, st_rp0
	
	; Fosc:		20000000
	; /4:		/4
	; Prescaler:	/256
	; ______________________
	;               19531.25 Hz
	; Counter1:	76.29hz
	btfss	r_intcon, ic_t0if
	goto	Intret
	
	bcf	r_intcon, ic_t0if
	bsf	r_intcon, ic_t0ie
	
	movlw	1		; Increment the counter
	addwf	m_count1, f	; """"""""" """ """""""
	movfw	m_count1
	addlw	d'-76'		; And test it against '76'
	movlw	d'-1'		; Prepare to subtract one from the cur char
	btfsc	r_status, st_z	; Skip following instr if count2 wasn't 76:
	addwf	m_curchar, f	;   Decrement the cur char
	movfw	m_curchar	; And read back the curchar
	addlw	d'-255'		; Test it against -1
	btfsc	r_status, st_z	; Skip following instr if curchar wasn't -1:
	movwf	m_curchar	;   Set curchar to 0
	movfw	m_count1	; Test count against 76
	addlw	d'-76'
	btfsc	r_status, st_z
	movwf	m_count1
	
Intret
	btfss	r_intcon, ic_gie
	swapf	m_st_temp,w
	movwf	r_status
	swapf	m_w_temp,f
	swapf	m_w_temp,w
	retfie
	
	end
