summaryrefslogtreecommitdiff
path: root/cbios/fifo.180
blob: ded979a6db09cec39402a565fe16b22c5bafce48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	public	bufinit
	public	ff_empty,ff_get,ff_full,ff_put
	public	ff_puth,ff_cnt,ff_gech

	public	fifolst

	extrn	msg.sm,hwl2phy

	maclib z180reg.inc
	maclib config.inc


;--------------------------------------------------------------------

	dseg

fifolst:
	rept 4
	 dw	0
	endm

;--------------------------------------------------------------------

	dseg

bufinit:
	ld	(ix+o.in_idx),0		;reset pointers (empty fifo)
	ld	(ix+o.out_idx),0
	ld	a,(ix+o.id)
	ld	hl,fifolst
	ld	e,a
	ld	d,0
	add	hl,de
	add	hl,de
	push	ix
	pop	de
	cp	4
	jr	nc,bfi_skip

	ld	(hl),e
	inc	hl
	ld	(hl),d

bfi_skip:
	ex	de,hl
	call	hwl2phy			;get phys. address of fifo
	ld	c,a
	ld	a,(ix+o.id)		;fifo id
	or	a			;test if fifo 0
	ret	z

	cp	4
	ret	nc

; TODO: move to better place

	ld	b,a
	push	bc			;c: bank-addr, b: ignored
	push	hl			;address
	ld	c,0
	push	bc			;c: function, b:subf
	ld	b,5
	ld	h,c
	ld	l,c
	add	hl,sp
	call	msg.sm
	pop	hl
	pop	hl
	pop	hl
	ret

;--------------------------------------------------------------
; Check if characters in fifo
; Fifo is empty, if output index and input index are the same

ff_empty:
	ld	a,(ix+o.in_idx)		;
	sub	(ix+o.out_idx)		;
	ret	z
	or	0ffh
	ret

;--------------------------------------------------------------
; get character from fifo
; destroys hl,b
;
; return:
;	c,a: next character

ff_get:
	push	ix
	pop	hl
	ld	c,(ix+o.out_idx)	;
	ld	b,0
	add	hl,bc
	ld	a,c
bg.wait:
	cp	(ix+o.in_idx)		;
	jr	z,bg.wait
	inc	a
	and	(ix+o.mask)
	ld	c,(hl)
	ld	(ix+o.out_idx),a
	ld	a,c
	ret

;--------------------------------------------------------------
; get character and ramaining count from fifo
; halt cpu, while buffer is empty
; destroys hl
;
; return:
;	c,a: next character
;	b:   number of charachters in fifo

ff_gech:
	push	ix
	pop	hl
	ld	c,(ix+o.out_idx)	;
	ld	b,0
	add	hl,bc
gech.wait:
	ld	a,(ix+o.in_idx)		;
	sub	c
	jr	nz,gech.cont
	halt
	jr	gech.wait
gech.cont:
	and	(ix+o.mask)		;
	dec	a
	ld	b,a
	ld	a,c
	inc	a
	and	(ix+o.mask)
	ld	c,(hl)
	ld	(ix+o.out_idx),a
	ld	a,c
	ret

;--------------------------------------------------------------
; Check if room in fifo
; buffer is full, if output index is one behind input index
;
; return
;   a = 0 and z    if buffer full
;   a = ff and nz  if buffer not full

ff_full:
	ld	a,(ix+o.in_idx)		;
	inc	a			;
	and	(ix+o.mask)		;
	sub	(ix+o.out_idx)		;
	ret	z
	or	0ffh
	ret


;--------------------------------------------------------------
; put character in c in buffer
; destroys bc

ff_put:
	push	ix			;
	ex	(sp),hl			; get buffer start address

	ld	a,c			;
	ld	c,(ix+o.in_idx)		; add input index
	ld	b,0			;
	add	hl,bc			;
	ld	(hl),a			; one place is allways free
	pop	hl			; restore hl

	ld	a,c			; bump input index
	inc	a			;
	and	(ix+o.mask)		;
bp.wait:				; do
	cp	(ix+o.out_idx)		;
	jr	z,bp.wait		; while new input idx == ouput idx
	ld	(ix+o.in_idx),a		;
	ret				;

;--------------------------------------------------------------
; put character in c in buffer
; halt cpu, while buffer is is full
; destroys bc

ff_puth:
	push	ix			;
	ex	(sp),hl			; get buffer start address

	ld	a,c			;
	ld	c,(ix+o.in_idx)		; add input index
	ld	b,0			;
	add	hl,bc			;
	ld	(hl),a			; one place is allways free
	pop	hl			; restore hl

	ld	a,c			; bump input index
	inc	a			;
	and	(ix+o.mask)		;
	jr	$+3
bph.wait:				; do
	halt				;   halt cpu
	cp	(ix+o.out_idx)		;
	jr	z,bph.wait		; while new input idx == ouput idx
	ld	(ix+o.in_idx),a		;
	ret				;

;--------------------------------------------------------------
; Return number of characters in fifo
;

ff_cnt:
	ld	a,(ix+o.in_idx)		;
	sub	(ix+o.out_idx)		;
	and	(ix+o.mask)		;
	ret

;--------------------------------------------------------------

	end