OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [sw/] [tb/] [soc_tb/] [soc_tb.asm] - Blame information for rev 74

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 74 ja_rd
;*******************************************************************************
2
; soc_tb.asm -- light8080 SoC basic test bench.
3
;*******************************************************************************
4
; Should be used with SoC core test bench entity vhdl\test\l80soc_tb.vhdl.
5
; Assembler format compatible with TASM for DOS and Linux.
6
;*******************************************************************************
7
; This program will send a few bytes over a looped-back UART, using the UART
8
; interrupt capability and verifying that received and transmitted data match.
9
; It will then try one of the external interrupts, connected to one of the
10
; general purpose outputs.
11
; This minimal test bench relies on an already tested CPU core to do a
12
; This program does not deserve to even be called a 'test' but if if works it
13
; will at least rule out many obvious bug in the SoC core.
14
;*******************************************************************************
15
 
16
; DS pseudo-directive; reserve space in bytes, without initializing it
17
#define ds(n)    \.org $+n
18
 
19
MASK_RX_IRQ:  .equ 20h
20
MASK_TX_IRQ:  .equ 10h
21
MASK_RX_RDY:  .equ 02h
22
MASK_TX_RDY:  .equ 01h
23
 
24
UART_DATA:    .equ 80h
25
UART_STATUS:  .equ 81h
26
UART_BAUDL:   .equ 82h
27
UART_BAUDH:   .equ 83h
28
IRQ_ENABLE:   .equ 88h
29
 
30
P1IN:         .equ 84h
31
P2OUT:        .equ 86h
32
 
33
 
34
;*******************************************************************************
35
 
36
          .org  0H              ; Reset entry point
37
          jmp   start           ; Skip the rst address area
38
 
39
        ;***** Interrupt vectors in area 0008h-0038h *****************
40
 
41
          .org  0h+(1*8)        ; interrupt vector 1 (IRQ0)
42
          jmp   isr0
43
          .org  0h+(2*8)        ; interrupt vector 2
44
          ei
45
          ret
46
          .org  0h+(3*8)        ; interrupt vector 3 (IRQ1)
47
          jmp   isr1
48
          .org  0h+(4*8)        ; interrupt vector 4
49
          ei
50
          ret
51
          .org  0h+(5*8)        ; interrupt vector 5 (IRQ2)
52
          ei
53
          ret
54
          .org  0h+(6*8)        ; interrupt vector 6
55
          ei
56
          ret
57
 
58
          .org  0h+(7*8)        ; interrupt vector 7 (IRQ3, UART)
59
int38h:   jmp   irq_uart        ; UART interrupt
60
 
61
          ;***** program entry point *******************************************
62
 
63
start:    .org  60H
64
          lxi   sp,stack
65
 
66
          ; Initialize UART RX and TX buffers
67
          lxi   h,void_buffer
68
          shld  ptr_tx
69
          lxi   h,rx_buffer
70
          shld  ptr_rx
71
          mvi   a,00h
72
          sta   len_rx
73
 
74
          ; Clear all P2 output lines (used to simulate external interrupts)
75
          mvi   a,00h
76
          out   P2OUT
77
 
78
          ; Set up interrupts
79
          mvi   a,0bh           ; Enable UART irq plus IRQ0 and IRQ1...
80
          out   IRQ_ENABLE
81
          ei                    ; ...and enable interrupts in the CPU
82
 
83
          ; print hello message to console
84
          lxi   h,msg_hello
85
          call  print_string
86
          ; Ok, now the message is being transferred through the looped back
87
          ; UART, using the UART interrupts, which have the lowest priority.
88
          ; We have plenty of time to make a few tests on the external interrupt
89
          ; lines before the message transmission is finished.
90
 
91
          ; The irq routines will leave some data at 'irq_data, each routine a
92
          ; different value and all non-zero. This is how we know what irq
93
          ; routines have executed and in which order.
94
 
95
          ; Test IRQ0 alone
96
          mvi   a,01h           ; Initialize irq data
97
          sta   irq_data
98
          mvi   a,01h           ; Trigger IRQ0
99
          out   P2OUT
100
test_irq0:
101
          lda   irq_data
102
          cpi   004h            ; Do we see the IRQ test data?
103
          jz    done_irq0       ; If we do, proceed to next test
104
          cpi   001h            ; Do we see some other IRQ test data instead?
105
          jnz   test_fail       ; If we do, there's trouble with the irqs
106
          jmp   test_irq0       ; Keep waiting for some IRQ test data
107
done_irq0:
108
          mvi   a,00h           ; Deassert all interrupt lines
109
          out   P2OUT
110
 
111
          ; Test IRQ1 alone
112
          mvi   a,01h           ; Initialize irq data
113
          sta   irq_data
114
          mvi   a,02h           ; Trigger IRQ1
115
          out   P2OUT
116
test_irq1:
117
          lda   irq_data
118
          cpi   002h            ; Do we see the IRQ test data?
119
          jz    done_irq1       ; If we do, proceed to next test
120
          cpi   001h            ; Do we see some other IRQ test data instead?
121
          jnz   test_fail       ; If we do, there's trouble with the irqs
122
          jmp   test_irq1       ; Keep waiting for some IRQ test data
123
done_irq1:
124
          xra   a               ; Deassert all interrupt lines
125
          out   P2OUT
126
 
127
          ; Test IRQ0 and IRQ1 simultaneously
128
          mvi   a,01h           ; Initialize irq data
129
          sta   irq_data
130
          mvi   a,03h           ; Trigger IRQ0 and IRQ1
131
          out   P2OUT
132
 
133
          ; Sequence IRQ0->IRQ1 will result in (1 << 2) + 1 = 5
134
          ; Sequence IRQ1->IRQ0 would result in (1 + 1) << 2 = 6
135
          ; We expect IRQ0->IRQ1, since IRQ0 has higher priority
136
test_irq01:
137
          lda   irq_data
138
          cpi   005h            ; Do we see the IRQ0->IRQ1 test data?
139
          jz    done_irq01      ; If we do, proceed to next test
140
          cpi   001h            ; Do we see some other IRQ test data instead?
141
          jnz   test_fail       ; If we do, there's trouble with the irqs
142
          jmp   test_irq01      ; Keep waiting for some IRQ test data
143
done_irq01:
144
          xra   a               ; Deassert all interrupt lines
145
          out   P2OUT
146
 
147
          ; Ok, the external interrupts have been tested (well, 'tested'). Now
148
          ; wait for the UART looped-back transmission to end and compare
149
          ; the data.
150
 
151
          ; Wait until the number of UART received characters equals the length
152
          ; of the test message.
153
wait_for_message:
154
          lda   len_rx
155
          cpi   msg_len
156
          jnz   wait_for_message
157
 
158
          ; Compare the TX and RX strings
159
          lxi   h,rx_buffer
160
          lxi   d,msg_hello
161
compare_loop:
162
          ldax  d
163
          cpi   '$'
164
          jz    test_ok
165
          cmp   m
166
          jnz   test_fail
167
          inx   h
168
          inx   d
169
          jmp   compare_loop
170
 
171
 
172
 
173
 
174
 
175
test_ok:
176
          mvi   a,80h           ; Raise 'success' output flag...
177
          out   P2OUT
178
done:     di                    ; ...and block here.
179
          hlt
180
 
181
test_fail:
182
          mvi   a,40h           ; Raise 'failure' flag...
183
          out   P2OUT
184
          jmp   done            ; ...and block.
185
 
186
 
187
 
188
msg_hello: .text "\n\r\nHello World!$"
189
msg_end:  .equ $
190
          ; compute message length (-1 for the '$' that does not get TX'd)
191
msg_len:  .equ msg_end - msg_hello - 1
192
 
193
          ; IRQ0 routine will shift irq_data left twice
194
isr0:     push  psw
195
          lda   irq_data
196
          rlc
197
          rlc
198
          sta   irq_data
199
          pop   psw
200
          ei
201
          ret
202
 
203
          ; IRQ1 routine will increment irq_data
204
isr1:     push  psw
205
          lda   irq_data
206
          adi   1
207
          sta   irq_data
208
          pop   psw
209
          ei
210
          ret
211
 
212
;irq_uart: UART interrupt processing
213
irq_uart:
214
          push  h
215
          push  psw
216
 
217
          ; Deal with RX interrupt (if any) first and then the TX interrupt.
218
          in    UART_STATUS     ; Is there new data in the RX register?
219
          ani   MASK_RX_IRQ
220
          jz    irq_uart_rx_done ; If there isn't, process TX interrupt.
221
 
222
          ; Process UART RX interrupt
223
irq_uart_rx:
224
          mvi   a,MASK_RX_IRQ   ; Clear IRQ flag.
225
          out   UART_STATUS
226
          in    UART_DATA       ; Get RX byte...
227
          lhld  ptr_rx          ; ...and store it in the rx buffer.
228
          mov   m,a
229
          inx   h
230
          shld  ptr_rx          ; Update the rx buffer pointer.
231
          lda   len_rx          ; Update RX buffer length
232
          inr   a
233
          sta   len_rx
234
 
235
          ; Note there's no check for RX buffer overrun! we shouldn't need it
236
          ; here, a runaway condition would be readily apparent in the
237
          ; simulation, anyway.
238
 
239
irq_uart_rx_done:
240
          ; Ok, RX is done. Now deal with TX irq, if any
241
          in    UART_STATUS     ; Is the TX buffer re new data in the RX register?
242
          ani   MASK_TX_IRQ
243
          jz    irq_uart_end    ; If there isn't, we're done.
244
 
245
          ; process UART TX interrupt
246
irq_uart_tx:
247
          mvi   a,MASK_TX_IRQ   ; Clear IRQ flag.
248
          out   UART_STATUS
249
          lhld  ptr_tx          ; Get next byte from the TX buffer
250
          mov   a,m
251
          cpi   '$'             ; Did we reach the end of the buffer?
252
          jz    irq_uart_tx_done ; If we did, we're done here...
253
          inx   h               ; ...otherwise increment the TX pointer...
254
          shld  ptr_tx
255
          out   UART_DATA       ; ...and transmit the data byte.
256
 
257
irq_uart_tx_done:
258
 
259
irq_uart_end:
260
          pop   psw             ; Done, quit.
261
          pop   h
262
          ei
263
          ret
264
 
265
;print_string: print $-terminated string at HL
266
print_string:
267
          ; We don't check if there's a transmission going on
268
          mov   a,m             ; Get first character from string...
269
          inx   h               ; ...and move updated string pointer to TX
270
          shld  ptr_tx          ; buffer pointer.
271
          cpi   '$'             ; Kickstart transmission by sending 1st byte...
272
          jz    print_string_end; ...unless its the end of string marker.
273
          out   UART_DATA       ;
274
print_string_end:
275
          ret
276
 
277
 
278
          ; data space, placed immediately after object code in memory
279
irq_data:     ds(1)
280
void_buffer:  .text "$"
281
ptr_tx:       ds(2)
282
ptr_rx:       ds(2)
283
len_rx:       ds(1)
284
rx_buffer:    ds(32)
285
              ds(64)
286
stack:        ds(2)
287
          .end
288
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.