-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathz80com
323 lines (323 loc) · 6.27 KB
/
z80com
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
.PAGE 'INTERPROCESS COMMUNICATION'
;--------------------------------------------------------------
;
; SEND A REQUEST
; ENTER: IPB BUFFER IS INITIALIZED TO HOLD THE
; COMMAND
; #INPUT, #OUTPUT BYTES
; INPUT PARAMETER BYTES
;
; EXIT: IPB BUFFER HOLDS
; OUTPUT PARAMETER BYTES
; ALL OTHER BYTES IN IPB UNCHANGED
;
;---------------------------------------------------------------
IPRQST
LDA #SEM88 ;CHECK 8088 SEMAPHORE
AND IPCIA+PRB
BNE IPRQST ;LOCKED OUT BY OTHER PROCESSOR
LDA #SEM65
ORA IPCIA+PRB ;LOCK 6509 SEMAPHORE
STA IPCIA+PRB
NOP ;A PAUSE
;
LDA IPCIA+PRB ;COLLISIONS WITH 8088?
TAX
AND #SEM88
BEQ IPR100 ;OK...
TXA
EOR #SEM65
STA IPCIA+PRB ;NOPE, CLEAR 6509 SEMAPHORE
TXA ;KILL SOME TIME
NOP
NOP
NOP
BNE IPRQST ;TRY AGAIN (BR ALWAYS)
;
; SEND CMD BYTE AND CAUSE IRQ
;
IPR100
LDA #$FF
STA IPCIA+DDRA ;PORT DIRECTION = OUT
LDA IPB+IPCCMD
STA IPCIA+PRA ;WRITE CMD BYTE TO PORT
;; CAUSE IRQ
JSR FREBUS ;GIVE UP BUS
LDA IPCIA+PRB ;PB6 := 0
AND #$BF
STA IPCIA+PRB
ORA #$40 ;KEEP LOW FOR 4US (8 CYCLES)
CLI
NOP
NOP
NOP
STA IPCIA+PRB ;PB6 := HIGH
;
JSR WAITHI ;SEM8088 -> HI (CMD BYTE RECVD)
LDA #$00
STA IPCIA+DDRA ;PORT DIRECTION = IN
JSR ACKLO ;SEM6509 -> LO (ACK)
JSR WAITLO ;SEM8088 -> LO (ACK ACK)
;
; SEND DATA BYTES, IF ANY
;
LDY #0
BEQ IPR250 ;ALWAYS
IPR200
LDA #$FF
STA IPCIA+DDRA ;PORT DIRECTION = OUT
LDA IPB+IPCDAT,Y ;GET NEXT DATA BYTE
STA IPCIA+PRA ;WRITE CMD OUT
JSR ACKHI ;SEM6509 -> HI (DATA READY)
JSR WAITHI ;SEM8088 -> HI (DATA RECVD)
LDA #$00
STA IPCIA+DDRA ;PORT DIRECTION = IN
JSR ACKLO ;SEM6509 -> LO (ACK)
JSR WAITLO ;SEM8088 -> LO (ACK ACK)
INY ;BUMP INDEX TO NEXT DATA BYTE
IPR250 CPY IPB+IPCIN ;ANY MORE ??
BNE IPR200 ;YES...
;
; RECEIVE DATA BYTES, IF ANY
;
LDY #0
BEQ IPR350 ;ALWAYS
IPR300
JSR ACKHI ;SEM6509 -> HI (RDY TO RECEIVE)
JSR WAITHI ;SEM8088 -> HI (DATA AVAILABLE)
LDA IPCIA+PRA ;GET DATA FROM PORT
STA IPB+IPCDAT,Y ;STUFF IT AWAY
JSR ACKLO ;SEM6509 -> LO (DATA RECVD)
JSR WAITLO ;SEM8088 -> LO (ACK)
INY
IPR350
CPY IPB+IPCOUT ;MORE?
BNE IPR300 ;YES...
RTS ;DONE!!
.PAGE
;-------------------------------------------------------------------
;
; SERVICE AN 8088 REQUEST
;
;-------------------------------------------------------------------
IPSERV
LDY #IPBSIZ-1 ;COPY IP BUFFER TO STACK
IPS050 LDA IPB,Y
PHA
DEY
BPL IPS050
;
LDA #0
STA IPCIA+DDRA ;PORT DIR=IN, JUST IN CASE...
LDA IPCIA+PRA ;READ CMD FROM PORT
STA IPB+IPCCMD ;STORE CMD AND DECODE IT
AND #$7F ;MASK OFF BUS BIT
TAY
LDA IPPTAB,Y ;BREAK APART NIBBLES
PHA
AND #$0F
STA IPB+IPCIN ;#INPUT BYTES
PLA
LSR A
LSR A
LSR A
LSR A
STA IPB+IPCOUT ;#OUTPUT BYTES
TYA ;ADJUST OFFSET FOR JUMP TABLE
ASL A
TAY
LDA IPJTAB,Y ;JUMP ADDRESS(LO)
STA IPB+IPCJMP
INY
LDA IPJTAB,Y ;JUMP ADDRESS (HI)
STA IPB+IPCJMP+1
JSR ACKHI ;SEM6509 -> HI (CMD RECVD)
JSR WAITLO ;SEM8088 -> LO (ACK)
;
; RECEIVE INPUT BYTES, IF ANY
;
LDY #0
IPS100
CPY IPB+IPCIN ;ANY MORE?
BEQ IPS200 ;NO...
JSR ACKLO ;SEM6509 ->LO (ACK ACK)
JSR WAITHI ;SEM8088 -> HI (DATA AVAILABLE)
LDA IPCIA+PRA ;READ DATA BYTE
STA IPB+IPCDAT,Y ;STORE IT
JSR ACKHI ;SEM6509 -> HI (DATA RECVD)
JSR WAITLO ;SEM8088 -> LO (ACK)
INY
BNE IPS100 ;ALWAYS...
;
; PROCESS CMD
;
IPS200
BIT IPB+IPCCMD ;CMD REQUIRES BUS?
BMI IPS500 ;YES...
LDA #>IPSRET ;PUSH RETURN
PHA
LDA #<IPSRET
PHA
JMP (IPB+IPCJMP) ;GONE!!!
;
; SEND RETURN BYTES, IF ANY
;
IPS300
IPSRET=IPS300-1
JSR ACKLO ;SEM6509 -> LO
LDY #0
BEQ IPS350 ;ALWAYS
IPS310
JSR WAITHI ;SEM8088 -> HI (8088 RDY TO RECV)
LDA #$FF
STA IPCIA+DDRA ;PORT DIRECTION = OUT
LDA IPB+IPCDAT,Y
STA IPCIA+PRA ;WRITE DATA TO PORT
JSR ACKHI ;SEM6509 -> HI (DATA AVAILABLE)
JSR WAITLO ;SEM8088 -> LO (DATA RECVD)
LDA #0
STA IPCIA+DDRA ;PORT DIRECTION = IN
JSR ACKLO ;SEM6509 -> LO (ACK)
INY
IPS350 CPY IPB+IPCOUT ;ANY MORE?
BNE IPS310 ;YES, REPEAT...
;
IPS400
LDY #0
IPS450 PLA ;RESTORE IP BUFFER
STA IPB,Y
INY
CPY #IPBSIZ
BNE IPS450
RTS ;DONE!
.SKI 3
; SPECIAL, FOR COMMANDS REQUIRING THE BUS
IPS500 LDA #>BURET
PHA
LDA #<BURET
PHA ;PUSH RETURN
JSR GETBUS ;GRAB BUS
JMP (IPB+IPCJMP) ;GONE!
;
IPS600
BURET=IPS600-1
JSR FREBUS ;GIVE UP BUS
LDA IPB+IPCOUT ;#BYTES TO RETURN
STA IPB+IPCIN
STA IPB+IPCCMD ;RETURN OP=#BYTES TO RETURN
LDA #0
STA IPB+IPCOUT ;JUST SEND TO 8088
JSR IPRQST
JMP IPS400 ;DONE!
.PAGE
;
; WAITLO - WAIT UNTIL SEM88 GOES LOW
;
WAITLO
LDA IPCIA+PRB
AND #SEM88
BNE WAITLO
RTS
.SKI 3
;
; WAITHI - WAIT UNTIL SEM88 GOES HIGH
;
WAITHI
LDA IPCIA+PRB
AND #SEM88
BEQ WAITHI
RTS
.SKI 3
;
; ACKLO - ACKNOWLEGDE SEM65 LOW
;
ACKLO
LDA IPCIA+PRB
AND #$FF-SEM65
STA CIA+PRB
RTS
.SKI 3
;
; ACKHI - ACKNOWLEDGE SEM6509 HI
;
ACKHI
LDA #SEM65
ORA IPCIA+PRB
STA IPCIA+PRB
RTS
.SKI 3
;
; FREBUS - GIVE UP BUS
; GETBUS - GRAB BUS
;
FREBUS
LDA TPI1+PB ;PB4 := 0
AND #$EF
STA TPI1+PB
RTS
;
GETBUS
LDA IPCIA+PRB ;CHECK NBUSY2
AND #$02
BEQ GETBUS ;2ND PROC NOT OFF
;
LDA TPI1+PB ;PB4 := 1
ORA #$10
STA TPI1+PB
RTS
.PAGE
; NOTE RETURN OPCODE IS 00-0FH
.SKI
IPJTAB ;JUMP TABLE
*=*+32 ;RETURN 0-0FH
.WORD GETIN ;CMD10
.WORD BASIN ;CMD11
.WORD BSOUT ;CMD12
.WORD MONON ;CMD13 (NEEDS BUS)
.WORD MJS1 ;CMD14 (NEEDS BUS)
.WORD MJS2 ;CMD15 (NEEDS BUS)
;
IPPTAB ;PARAM SPECS
.BYTE $00 ;RET0-0F PARAMS
.BYTE $01
.BYTE $02
.BYTE $03
.BYTE $04
.BYTE $05
.BYTE $06
.BYTE $07
.BYTE $08
.BYTE $09
.BYTE $0A
.BYTE $0B
.BYTE $0C
.BYTE $0D
.BYTE $0E
.BYTE $0F
.BYTE $10 ;CMD10 PARAMS
.BYTE $10 ;CMD11 PARAMS
.BYTE $01 ;CMD12 PARAMS
.BYTE $00 ;CMD13 PARAMS
.BYTE $00 ;CMD14 PARAMS
.BYTE $10 ;CMD15 PARAMS
;
MJS1 LDA #'A' ;FILL WITH A'S
LDX #$40 ;$4000-4100
MJS40 LDY #0
STY RIBUF
STX RIBUF+1
LDX #2 ;SEGMENT 2
STX I6509
MJS50 STA (RIBUF)Y
INY
BNE MJS50
LDX #$0F
STX I6509
RTS
;
MJS2 LDA #'B' ;FILL WITH B'S
LDX #$50 ;$5000-$5100
JSR MJS40
STA IPB+IPCDAT ;RETURN 'B'
RTS
.END