1
2	list	p=16f871
3        include <p16f871.inc>
4        include <coff.inc>
5
6  __CONFIG _WDT_OFF
7
8
9        ;; The purpose of this program is to test gpsim's ability to simulate
10        ;; the Parallel Slave port (PSP)  functionality.
11        ;;
12        ;; Portb and portd form the PSP bus and porta pins 0, 1, and 2
13        ;; drive the, active low, bus control signals RD, WR and CS respectively
14
15
16        errorlevel -302
17
18; Printf Command
19.command macro x
20  .direct "C", x
21  endm
22
23;----------------------------------------------------------------------
24;----------------------------------------------------------------------
25GPR_DATA                UDATA_SHR
26
27x  RES  1
28t1 RES  1
29t2 RES  1
30avg_lo RES  1
31avg_hi RES  1
32w_temp RES  1
33status_temp RES  1
34
35
36;----------------------------------------------------------------------
37;   ********************* RESET VECTOR LOCATION  ********************
38;----------------------------------------------------------------------
39RESET_VECTOR  CODE    0x000              ; processor reset vector
40        movlw  high  start               ; load upper byte of 'start' label
41        movwf  PCLATH                    ; initialize PCLATH
42        goto   start                     ; go to beginning of program
43
44	;;
45	;; Interrupt
46	;;
47INT_VECTOR   CODE    0x004               ; interrupt vector location
48	movwf	w_temp
49	swapf	STATUS,W
50	movwf	status_temp
51
52	bcf	STATUS,RP0	;bank 0
53
54	btfsc	PIR1,PSPIF
55	goto	done
56
57  .assert "'FAILED 16F871 unexpected interupt'"
58	nop
59check:
60	swapf	status_temp,w
61	movwf	STATUS
62	swapf	w_temp,F
63	swapf	w_temp,W
64	retfie
65
66
67
68;----------------------------------------------------------------------
69;   ******************* MAIN CODE START LOCATION  ******************
70;----------------------------------------------------------------------
71MAIN    CODE
72start:
73
74   .sim "node pspRD"
75   .sim "attach pspRD porta0 porte0"
76   .sim "node pspWR"
77   .sim "attach pspWR porta1 porte1"
78   .sim "node pspCS"
79   .sim "attach pspCS porta2 porte2"
80   .sim "node p0"
81   .sim "attach p0 portb0 portd0"
82   .sim "node p1"
83   .sim "attach p1 portb1 portd1"
84   .sim "node p2"
85   .sim "attach p2 portb2 portd2"
86   .sim "node p3"
87   .sim "attach p3 portb3 portd3"
88   .sim "node p4"
89   .sim "attach p4 portb4 portd4"
90   .sim "node p5"
91   .sim "attach p5 portb5 portd5"
92   .sim "node p6"
93   .sim "attach p6 portb6 portd6"
94   .sim "node p7"
95   .sim "attach p7 portb7 portd7"
96
97;
98; The test relies on porta being digital I/O, and porte being PSP, so it's
99; necessary to disable all ADC channels
100	bsf     STATUS,RP0      ; bank 1
101	movlw	0x07
102	movwf	ADCON1
103	bcf	STATUS,RP0      ; bank 0
104
105
106;
107; First test portd operates in normal mode
108
109	bsf     STATUS,RP0      ; bank 1
110	clrf    TRISD           ; PortD output
111	bcf	STATUS,RP0      ; bank 0
112	movlw	0x55
113	movwf	PORTD
114  .assert "portd == 0x55, 'FAILED, Portd put value OK'"
115	nop
116  .assert "portb == 0x55, 'FAILED, Portd drives Portb'"
117	nop
118	movf	PORTD,W		; check read Portd
119  .assert "W == 0x55, 'FAILED, Read portd OK'"
120	nop
121	bsf     STATUS,RP0      ; bank 1
122	clrf    TRISB           ; PortB output
123	movlw	0xff
124	movwf	TRISD		; PortD input
125	bcf	STATUS,RP0      ; bank 0
126	movwf	PORTB
127  .assert "portd == 0xff, 'FAILED, Read portd as input'"
128	nop
129
130
131;
132; Now test PSP in bus RD mode
133;
134	movlw	0x07		; set bits high
135	movwf	PORTA
136	bsf	STATUS,RP0	; bank 1
137	movlw   0xff
138	movwf   TRISB
139        movlw   0xf8
140        movwf   TRISA
141	movlw	0x17
142	movwf	TRISE
143	bcf	STATUS,RP0	; bank 0
144	movlw	0xf0
145	movwf	PORTD		; Output should not change in PSP mode
146  .assert "(trise & 0xe0) == 0x40, 'FAILED, OBF set on portd write'"
147	nop
148  .assert "portb != 0xf0, 'FAILED, Output not changed'"
149	nop
150	bcf	PORTA,0		; Drive RD low to put data on bus
151	bcf	PORTA,2		; Drive CS low to select
152  .assert "(trise & 0xe0) == 0x00, 'FAILED, OBF cleared on PSP RD'"
153	nop
154  .assert "portb == 0xf0, 'FAILED, Output on bus'"
155	nop
156  .assert "(pir1 & 0x80) == 0, 'FAILED, PSPIF not set until RD off'"
157	nop
158	bsf	PORTA,0		; Turn off RD
159  .assert "(pir1 & 0x80) == 0x80, 'FAILED, PSPIF set for RD'"
160	nop
161;
162; test PSP WR function
163;
164	bsf	STATUS,RP0      ; bank 1
165	clrf	TRISB		; set B as output
166	bcf	STATUS,RP0      ; bank 0
167	movlw	0x0f
168	movwf	PORTB		; drive bus
169	bcf	PORTA,1		; Turn on WR (CS already on)
170  .assert "(trise & 0xe0) == 0x00, 'FAILED, IBF not set yet'"
171	nop
172	bsf	PORTA,2		; Turn off CS
173  .assert "(trise & 0xe0) == 0x80, 'FAILED, IBF now set'"
174	nop
175	movf	PORTD,W
176  .assert "W == 0x0f, 'FAILED, Value read from bus'"
177	nop
178  .assert "(trise & 0xe0) == 0x00, 'FAILED, IBF cleared on read of portd'"
179	nop
180	bcf	PORTA,2		; Turn on CS
181	bsf	PORTA,2		; Turn off CS
182	bcf	PORTA,2		; Turn on CS
183	bsf	PORTA,2		; Turn off CS
184  .assert "(trise & 0xe0) == 0xa0, 'FAILED, IBF, IBOV both set '"
185	nop
186
187	bsf	STATUS,RP0      ; bank 1
188	movlw   0x17
189	movwf	TRISE		; set B as output
190  .assert "(trise & 0xe0) == 0x80, 'FAILED, IBOV cleared, but not IBF '"
191	nop
192	movlw	0x07		; turn off PSP
193	movwf	TRISE		; set B as output
194  .assert "(trise & 0xf0) == 0x00, 'FAILED, IBF & PSPMODE claered'"
195	nop
196;
197; test interupts
198;
199	movlw	0x17
200	movwf	TRISE
201	bsf	PIE1,PSPIE
202	movlw	0xc0
203	movwf	INTCON		; Enable interupts
204	bcf	STATUS,RP0      ; bank 0
205
206	bcf	PIR1,PSPIF
207	bcf	PORTA,2		; Turn on CS
208	bsf	PORTA,2		; Turn off CS
209   .assert "'FAILED, interrupt'"
210	nop
211	goto $-1
212
213
214
215done:
216  .assert  "'*** PASSED 16F871 PSP test'"
217
218	goto	$-1
219
220
221	end
222