-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdisk_util.lst
352 lines (272 loc) · 4.79 KB
/
disk_util.lst
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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
STACK_TOP .equ 0x300
LF .equ 10 ; line feed ( V )
CR .equ 13 ; carriage return ( <- )
NUL .equ 0 ; NUL character
TTS .equ 03h ;SIO channel A command port
TTI .equ 02h ;SIO channel A data port (yes input=output)
TTO .equ 02h ;SIO channel A data port
TTYDA .equ 02h ;tty data available (ready to receive?)
TTYTR .equ 01h ;tty terminal ready (ready to transmit?)
DWAIT .equ 0fch
DEXT .equ 0fch
DCOM .equ 0f8h
DDATA .equ 0fbh
DSTAT .equ 0f8h
DSECT .equ 0fah
DISK_BUF .equ 0x400
DISK_BUF_END .equ 0x480
SERIAL_BUF .equ 0x500
.org 0
start:
; init stack
LXI H, STACK_TOP
sphl
call serial_init ; init serial
lxi H, TEXT_WELCOME
call swrite_line
; select drive
mvi a, 2
cma
ani 3
ral
ral
ral
ral
ori 2
out DEXT
; done
jmp loop2
foo_loop:
call sread_line
lxi H, SERIAL_BUF
call swrite_line
jmp foo_loop
hlt
; foobar2:
; call sread_byte
; call swrite_byte
; jmp foobar2
labal:
mvi a, 65
call swrite_byte
; jmp labal
lxi H, TEXT_LOC
call swrite_str
hlt
mvi d, 0
loop:
in 0ffh
cmp d
jz loop_end
mov d, a
call dseek
call dwait_loop
jmp loop2 ; uncomment to read
lxi H, DISK_BUF
mvi a, 128
wr_loop:
dcr a
mov m, a
inx H
jnz wr_loop
mvi a, 1
lxi H, DISK_BUF
call dsector_write
hlt
loop2:
mvi e, 255 ; track num
outer_foo:
inr e
mov a, e
call dseek
mvi d, 0
foo:
inr d
mov a, d
call dsector_read
in DSTAT
ani 0x10
jnz foo_end
lxi H, DISK_BUF
mvi a, 128
call swrite_bytes
jmp foo
foo_end:
mov a, d
cma
out 0xff
mov a, e
cpi 76 ; last track
jnz outer_foo
hlt
loop_end:
in DSTAT
cma
out 0ffh
jmp loop
; Serial init
serial_init:
mvi a,0
out TTS
out TTS
out TTS
mvi a, 040h
out TTS
mvi a, 04eh ; 8,1,n
out TTS
mvi a, 037h
out TTS
ret
; Read byte from serial
; A = returned byte
;
sread_byte: ; loop until data available
in TTS
ani TTYDA
jz sread_byte
in TTO ; read
ret
; Write byte to serial
; A = byte
;
swrite_byte: ; loop until terminal ready
push D
mov d, a
swrite_byte_wait:
in TTS
ani TTYTR
jz swrite_byte_wait
mov a, d
out TTO
pop D
ret
; Write bytes to serial
; A = num bytes
; HL = address of bytes
;
swrite_bytes:
push D
mov d, a ; bytes left counter
swrite_bytes_loop:
mov a, d
ora a
jz swrite_bytes_end ; zero bytes left, exit
dcr d
mov a, m
inx H
call swrite_byte
jmp swrite_bytes_loop
swrite_bytes_end:
pop D
ret
; Write null-terminated string to serial
; HL = address of string
;
swrite_str:
mov a, m
cpi 0
jz swrite_str_end ; exit if we hit NUL
call swrite_byte ; echo to serial
inx H
jmp swrite_str
swrite_str_end:
ret
; Write string to serial and go to next line
swrite_line:
call swrite_str
lxi H, TEXT_ENDL
call swrite_str
ret
; Read a line from serial. Line end indicated by LF (\n) which is stripped.
; Result is null-terminated string in SERIAL_BUF
;
sread_line:
push H
lxi H, SERIAL_BUF
sread_line_loop:
call sread_byte
cpi LF
jz sread_line_end
cpi 0
jz sread_line_end
mov m, a
inx H
jmp sread_line_loop
sread_line_end:
mvi a, 0
mov m, a
pop H
ret
; Wait until disk is ready
dwait_loop:
in DSTAT
cma
out 0ffh
cma
ani 1
jnz dwait_loop
ret
; Seek to track
; A = track
dseek:
push D
mvi d, 76
cmp d
jp dseek_end
out DDATA
mvi a, 013h
out DCOM
dseek_end:
pop D
ret
; Read sector of disk into DISK_BUF
; A = sector number
dsector_read:
push H
lxi H, DISK_BUF
out DSECT
mvi a, 8ch
out DCOM
dsector_read_loop:
in DWAIT
ora a
jp dsector_read_done
in DDATA
mov m, a ; (H) <- a
inx H
jmp dsector_read_loop
dsector_read_done:
pop H
ret
; Write a sector of disk
; A = sector number
; HL = address of data to copy to disk
dsector_write:
out DSECT
mvi a, 0adh
out DCOM
dsector_write_loop:
in DWAIT
ora a
jp dsector_write_done
mov a, m
out DDATA
inx H
jmp dsector_write_loop
dsector_write_done:
mov a, l
cma
out 0xff
ret
TEXT .equ TEXT_LOC
; * * * * * * * * * * ;
; Strings ;
; * * * * * * * * * * ;
TEXT_WELCOME:
db CR, LF, LF, LF, LF, "Welcome to Disk Dumper 1000", NUL
TEXT_ENDL:
db CR, LF, NUL
TEXT_LOC:
db 'Wow this is great!', NUL
total time: 0.0033 sec.
no errors