· 7 years ago · Feb 08, 2019, 11:02 AM
1'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1
2
3
4 title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980'
5
6 .Z80
7 0000' aseg
8 org 100h
9 C maclib MEMCFG.LIB ; define configuration parameters
10 0040 C msize equ 64 ; adjust per installed system memory
11 C
12 C ; configuration parameters for BIOS
13 2000 C bioslen equ 2000h ; adjust as bios changes are made (if necessary)
14 0002 C nhdisks equ 2 ; total number of hard disks (set to 0
15 C ; if no hard disks desired)
16 0000 C needZ80 equ 0 ; 0 = 8080 is ok, 1 = Z80 is needed
17 0001 C patchOS equ 1 ; 0 = do not patch CCP and BODS
18 C ; 1 = patch orignal CCP and original BDOS
19 C
20 C ; common definitions and derived values - no change should be necessary below
21 0800 C ccplen equ 0800h ; cp/m constant
22 0E00 C bdoslen equ 0e00h ; cp/m constant
23 C
24 C ; cp/m image size (rounded up to next 1k boundary)
25 000E C cpmlen equ (ccplen + bdoslen + bioslen + 03ffh) / 0400h
26 C
27 C800 C ccpph equ (msize - cpmlen) * 1024 ; ccp start address
28 D000 C bdosph equ ccpph + ccplen ; bdos start address
29 DE00 C biosph equ ccpph + ccplen + bdoslen ; bios start address
30 .phase bdosph
31 DE00 bios equ biosph
32
33 ;*****************************************************************
34 ;*****************************************************************
35 ;** **
36 ;** B a s i c D i s k O p e r a t i n g S y s t e m **
37 ;** I n t e r f a c e M o d u l e **
38 ;** **
39 ;*****************************************************************
40 ;*****************************************************************
41
42 ; Copyright (c) 1978, 1979, 1980
43 ; Digital Research
44 ; Box 579, Pacific Grove
45 ; California
46
47
48 ; 20 january 1980
49
50 0018 ssize equ 24 ;24 level stack
51
52 ; low memory locations
53 0000 reboot equ 0000h ;reboot system
54 0003 ioloc equ 0003h ;i/o byte location
55 0006 bdosa equ 0006h ;address field of jp BDOS
56
57 ; bios access constants
58 DE00 bootf defl bios+3*0 ;cold boot function
59 DE03 wbootf defl bios+3*1 ;warm boot function
60'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-1
61
62
63 DE06 constf defl bios+3*2 ;console status function
64 DE09 coninf defl bios+3*3 ;console input function
65 DE0C conoutf defl bios+3*4 ;console output function
66 DE0F listf defl bios+3*5 ;list output function
67 DE12 punchf defl bios+3*6 ;punch output function
68 DE15 readerf defl bios+3*7 ;reader input function
69 DE18 homef defl bios+3*8 ;disk home function
70 DE1B seldskf defl bios+3*9 ;select disk function
71 DE1E settrkf defl bios+3*10 ;set track function
72 DE21 setsecf defl bios+3*11 ;set sector function
73 DE24 setdmaf defl bios+3*12 ;set dma function
74 DE27 readf defl bios+3*13 ;read disk function
75 DE2A writef defl bios+3*14 ;write disk function
76 DE2D liststf defl bios+3*15 ;list status function
77 DE30 sectran defl bios+3*16 ;sector translate
78
79 ; equates for non graphic characters
80 0003 ctlc equ 03h ;control c
81 0005 ctle equ 05h ;physical eol
82 0008 ctlh equ 08h ;backspace
83 0010 ctlp equ 10h ;prnt toggle
84 0012 ctlr equ 12h ;repeat line
85 0013 ctls equ 13h ;stop/start screen
86 0015 ctlu equ 15h ;line delete
87 0018 ctlx equ 18h ;=ctl-u
88 001A ctlz equ 1ah ;end of file
89 007F rubout equ 7fh ;char delete
90 0009 tab equ 09h ;tab char
91 000D cr equ 0dh ;carriage return
92 000A lf equ 0ah ;line feed
93 005E ctl equ 5eh ;up arrow
94
95 D000 00 00 00 00 db 0,0,0,0,0,0
96 D004 00 00
97
98 ; enter here from the user's program with function number in c,
99 ; and information address in d,e
100 D006 C3 D011 jp bdose ;past parameter block
101
102 ; ************************************************
103 ; *** relative locations 0009 - 000e ***
104 ; ************************************************
105 D009 D099 pererr: dw persub ;permanent error subroutine
106 D00B D0A5 selerr: dw selsub ;select error subroutine
107 D00D D0AB roderr: dw rodsub ;ro disk error subroutine
108 D00F D0B1 roferr: dw rofsub ;ro file error subroutine
109
110
111 D011 EB bdose: ex de,hl ;arrive here from user programs
112 D012 22 D343 ld (info),hl
113 D015 EB ex de,hl ;info=DE, DE=info
114 D016 7B ld a,e
115 D017 32 DDD6 ld (linfo),a ;linfo = low(info) - don't equ
116 D01A 21 0000 ld hl,0
117 D01D 22 D345 ld (aret),hl ;return value defaults to 0000
118 ;save user's stack pointer, set to local stack
119'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-2
120
121
122 D020 39 add hl,sp
123 D021 22 D30F ld (entsp),hl ;entsp = stackptr
124 D024 31 D341 ld sp,lstack ;local stack setup
125 D027 AF xor a
126 D028 32 DDE0 ld (fcbdsk),a
127 D02B 32 DDDE ld (resel),a ;fcbdsk,resel=false
128 D02E 21 DD74 ld hl,goback ;return here after all functions
129 D031 E5 push hl ;jmp goback equivalent to ret
130 D032 79 ld a,c
131 D033 FE 29 cp nfuncs
132 D035 D0 ret nc ;skip if invalid #
133 D036 4B ld c,e ;possible output character to C
134 D037 21 D047 ld hl,functab
135 D03A 5F ld e,a
136 D03B 16 00 ld d,0 ;DE=func, HL=.ciotab
137 D03D 19 add hl,de
138 D03E 19 add hl,de
139 D03F 5E ld e,(hl)
140 D040 23 inc hl
141 D041 56 ld d,(hl) ;DE=functab(func)
142 D042 2A D343 ld hl,(info) ;info in DE for later xchg
143 D045 EB ex de,hl
144 D046 E9 jp (hl) ;dispatched
145
146 ; dispatch table for functions
147 D047 functab:
148 D047 DE03 D2C8 dw wbootf, func1, func2, func3
149 D04B D190 D2CE
150 D04F DE12 DE0F dw punchf, listf, func6, func7
151 D053 D2D4 D2ED
152 D057 D2F3 D2F8 dw func8, func9, func10,func11
153 D05B D1E1 D2FE
154 000C diskf equ ($-functab)/2 ;disk funcs
155 D05F DC7E DC83 dw func12,func13,func14,func15
156 D063 DC45 DC9C
157 D067 DCA5 DCAB dw func16,func17,func18,func19
158 D06B DCC8 DCD7
159 D06F DCE0 DCE6 dw func20,func21,func22,func23
160 D073 DCEC DCF5
161 D077 DCFE DD04 dw func24,func25,func26,func27
162 D07B DD0A DD11
163 D07F D52C DD17 dw func28,func29,func30,func31
164 D083 DD1D DD26
165 D087 DD2D DD41 dw func32,func33,func34,func35
166 D08B DD47 DD4D
167 D08F DC0E DD53 dw func36,func37,func38,func39
168 D093 D304 D304
169 D097 DD9B dw func40
170 0029 nfuncs equ ($-functab)/2
171
172
173 ; error subroutines
174 D099 21 D0CA persub: ld hl,permsg ;report permanent error
175 D09C CD D0E5 call errflg ;to report the error
176 D09F FE 03 cp ctlc
177 D0A1 CA 0000 jp z,reboot ;reboot if response is ctlc
178'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-3
179
180
181 D0A4 C9 ret ;and ignore the error
182
183 D0A5 21 D0D5 selsub: ld hl,selmsg ;report select error
184 D0A8 C3 D0B4 jp wait$err ;wait console before boot
185
186 D0AB 21 D0E1 rodsub: ld hl,rodmsg ;report write to read/only disk
187 D0AE C3 D0B4 jp wait$err ;wait console
188
189 D0B1 rofsub: ;report read/only file
190 D0B1 21 D0DC ld hl,rofmsg ;drop through to wait for console
191
192 D0B4 wait$err: ;wait for response before boot
193 D0B4 CD D0E5 call errflg
194 D0B7 C3 0000 jp reboot
195
196 ; error messages
197 D0BA 42 64 6F 73 dskmsg: db 'Bdos Err On '
198 D0BE 20 45 72 72
199 D0C2 20 4F 6E 20
200 D0C6 20 3A 20 24 dskerr: db ' : $' ;filled in by errflg
201 D0CA 42 61 64 20 permsg: db 'Bad Sector$'
202 D0CE 53 65 63 74
203 D0D2 6F 72 24
204 D0D5 53 65 6C 65 selmsg: db 'Select$'
205 D0D9 63 74 24
206 D0DC 46 69 6C 65 rofmsg: db 'File '
207 D0E0 20
208 D0E1 52 2F 4F 24 rodmsg: db 'R/O$'
209
210
211 D0E5 E5 errflg: push hl ;report error to console, message address in HL
212 D0E6 CD D1C9 call crlf ;stack mssg address, new line
213 D0E9 3A D342 ld a,(curdsk)
214 D0EC C6 41 add a,'A'
215 D0EE 32 D0C6 ld (dskerr),a ;current disk name
216 D0F1 01 D0BA ld bc,dskmsg
217 D0F4 CD D1D3 call print ;the error message
218 D0F7 C1 pop bc
219 D0F8 CD D1D3 call print ;error mssage tail
220 ; jp conin ;to get the input character
221 ;(drop through to conin)
222 ; ret
223
224
225 ; console handlers
226 D0FB 21 D30E conin: ld hl,kbchar ;read console character to A
227 D0FE 7E ld a,(hl)
228 D0FF 36 00 ld (hl),0
229 D101 B7 or a
230 D102 C0 ret nz
231 ;no previous keyboard character ready
232 D103 C3 DE09 jp coninf ;get character externally
233 ; ret
234 D106 CD D0FB conech: call conin ;read character with echo
235 D109 CD D114 call echoc
236 D10C D8 ret c ;echo character?
237'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-4
238
239
240 ;character must be echoed before return
241 D10D F5 push af
242 D10E 4F ld c,a
243 D10F CD D190 call tabout
244 D112 F1 pop af
245 D113 C9 ret ;with character in A
246
247 D114 echoc: ;echo character if graphic
248 D114 FE 0D cp cr ;cr, lf, tab, or backspace
249 D116 C8 ret z ;carriage return?
250 D117 FE 0A cp lf
251 D119 C8 ret z ;line feed?
252 D11A FE 09 cp tab
253 D11C C8 ret z ;tab?
254 D11D FE 08 cp ctlh
255 D11F C8 ret z ;backspace?
256 D120 FE 20 cp ' '
257 D122 C9 ret ;carry set if not graphic
258
259 D123 conbrk: ;check for character ready
260 D123 3A D30E ld a,(kbchar)
261 D126 B7 or a
262 D127 C2 D145 jp nz,conb1 ;skip if active kbchar
263 ;no active kbchar, check external break
264 D12A CD DE06 call constf
265 D12D E6 01 and 1
266 D12F C8 ret z ;return if no char ready
267 ;character ready, read it
268 D130 CD DE09 call coninf ;to A
269 D133 FE 13 cp ctls
270 D135 C2 D142 jp nz,conb0 ;check stop screen function
271 ;found ctls, read next character
272 D138 CD DE09 call coninf ;to A
273 D13B FE 03 cp ctlc
274 D13D CA 0000 jp z,reboot ;ctlc implies re-boot
275 ;not a reboot, act as if nothing has happened
276 D140 AF xor a
277 D141 C9 ret ;with zero in accumulator
278 D142 conb0:
279 ;character in accum, save it
280 D142 32 D30E ld (kbchar),a
281 D145 conb1:
282 ;return with true set in accumulator
283 D145 3E 01 ld a,1
284 D147 C9 ret
285
286 D148 conout: ;compute character position/write console char from C
287 ;compcol = true if computing column position
288 D148 3A D30A ld a,(compcol)
289 D14B B7 or a
290 D14C C2 D162 jp nz,compout
291 ;write the character, then compute the column
292 ;write console character from C
293 D14F C5 push bc
294 D150 CD D123 call conbrk ;check for screen stop function
295 D153 C1 pop bc
296'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-5
297
298
299 D154 C5 push bc ;recall/save character
300 D155 CD DE0C call conoutf ;externally, to console
301 D158 C1 pop bc
302 D159 C5 push bc ;recall/save character
303 ;may be copying to the list device
304 D15A 3A D30D ld a,(listcp)
305 D15D B7 or a
306 D15E C4 DE0F call nz,listf ;to printer, if so
307 D161 C1 pop bc ;recall the character
308 D162 compout:
309 D162 79 ld a,c ;recall the character
310 ;and compute column position
311 D163 21 D30C ld hl,column ;A = char, HL = .column
312 D166 FE 7F cp rubout
313 D168 C8 ret z ;no column change if nulls
314 D169 34 inc (hl) ;column = column + 1
315 D16A FE 20 cp ' '
316 D16C D0 ret nc ;return if graphic
317 ;not graphic, reset column position
318 D16D 35 dec (hl) ;column = column - 1
319 D16E 7E ld a,(hl)
320 D16F B7 or a
321 D170 C8 ret z ;return if at zero
322 ;not at zero, may be backspace or end line
323 D171 79 ld a,c ;character back to A
324 D172 FE 08 cp ctlh
325 D174 C2 D179 jp nz,notbacksp
326 ;backspace character
327 D177 35 dec (hl) ;column = column - 1
328 D178 C9 ret
329
330 D179 notbacksp: ;not a backspace character, eol?
331 D179 FE 0A cp lf
332 D17B C0 ret nz ;return if not
333 ;end of line, column = 0
334 D17C 36 00 ld (hl),0 ;column = 0
335 D17E C9 ret
336
337 D17F ctlout: ;send C character with possible preceding up-arrow
338 D17F 79 ld a,c
339 D180 CD D114 call echoc ;cy if not graphic (or special case)
340 D183 D2 D190 jp nc,tabout ;skip if graphic, tab, cr, lf, or ctlh
341 ;send preceding up arrow
342 D186 F5 push af
343 D187 0E 5E ld c,ctl
344 D189 CD D148 call conout ;up arrow
345 D18C F1 pop af
346 D18D F6 40 or 40h ;becomes graphic letter
347 D18F 4F ld c,a ;ready to print
348 ;(drop through to tabout)
349
350 D190 tabout: ;expand tabs to console
351 D190 79 ld a,c
352 D191 FE 09 cp tab
353 D193 C2 D148 jp nz,conout ;direct to conout if not
354 ;tab encountered, move to next tab position
355'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-6
356
357
358 D196 0E 20 tab0: ld c,' '
359 D198 CD D148 call conout ;another blank
360 D19B 3A D30C ld a,(column)
361 D19E E6 07 and 111b ;column mod 8 = 0 ?
362 D1A0 C2 D196 jp nz,tab0 ;back for another if not
363 D1A3 C9 ret
364
365 D1A4 backup: ;back-up one screen position
366 D1A4 CD D1AC call pctlh
367 D1A7 0E 20 ld c,' '
368 D1A9 CD DE0C call conoutf
369 ; (drop through to pctlh)
370 D1AC pctlh: ;send ctlh to console without affecting column count
371 D1AC 0E 08 ld c,ctlh
372 D1AE C3 DE0C jp conoutf
373 ; ret
374 D1B1 crlfp: ;print #, cr, lf for ctlx, ctlu, ctlr functions
375 ;then move to strtcol (starting column)
376 D1B1 0E 23 ld c,'#'
377 D1B3 CD D148 call conout
378 D1B6 CD D1C9 call crlf ;column = 0, move to position strtcol
379 D1B9 3A D30C crlfp0: ld a,(column)
380 D1BC 21 D30B ld hl,strtcol
381 D1BF BE cp (hl)
382 D1C0 D0 ret nc ;stop when column reaches strtcol
383 D1C1 0E 20 ld c,' '
384 D1C3 CD D148 call conout ;print blank
385 D1C6 C3 D1B9 jp crlfp0
386
387 D1C9 0E 0D crlf: ld c,cr ;carriage return line feed sequence
388 D1CB CD D148 call conout
389 D1CE 0E 0A ld c,lf
390 D1D0 C3 D148 jp conout
391 ; ret
392 D1D3 0A print: ld a,(bc) ;print message until M(BC) = '$'
393 D1D4 FE 24 cp '$'
394 D1D6 C8 ret z ;stop on $
395 ;more to print
396 D1D7 03 inc bc
397 D1D8 C5 push bc
398 D1D9 4F ld c,a ;char to C
399 D1DA CD D190 call tabout ;another character printed
400 D1DD C1 pop bc
401 D1DE C3 D1D3 jp print
402
403 D1E1 read: ;read to info address (max length, current length, buffer)
404 D1E1 3A D30C ld a,(column)
405 D1E4 32 D30B ld (strtcol),a ;save start for ctl-x, ctl-h
406 D1E7 2A D343 ld hl,(info)
407 D1EA 4E ld c,(hl)
408 D1EB 23 inc hl
409 D1EC E5 push hl
410 D1ED 06 00 ld b,0
411 ;B = current buffer length,
412 ;C = maximum buffer length,
413 ;HL= next to fill - 1
414'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-7
415
416
417 D1EF readnx: ;read next character, BC, HL active
418 D1EF C5 push bc
419 D1F0 E5 push hl ;blen, cmax, HL saved
420 D1F1 CD D0FB readn0: call conin ;next char in A
421 D1F4 E6 7F and 7fh ;mask parity bit
422 D1F6 E1 pop hl
423 D1F7 C1 pop bc ;reactivate counters
424 D1F8 FE 0D cp cr
425 D1FA CA D2C1 jp z,readen ;end of line?
426 D1FD FE 0A cp lf
427 D1FF CA D2C1 jp z,readen ;also end of line
428 D202 FE 08 cp ctlh
429 D204 C2 D216 jp nz,noth ;backspace?
430 ;do we have any characters to back over?
431 D207 78 ld a,b
432 D208 B7 or a
433 D209 CA D1EF jp z,readnx
434 ;characters remain in buffer, backup one
435 D20C 05 dec b ;remove one character
436 D20D 3A D30C ld a,(column)
437 D210 32 D30A ld (compcol),a ;col > 0
438 ;compcol > 0 marks repeat as length compute
439 D213 C3 D270 jp linelen ;uses same code as repeat
440
441 D216 noth: ;not a backspace
442 D216 FE 7F cp rubout
443 D218 C2 D226 jp nz,notrub ;rubout char?
444 ;rubout encountered, rubout if possible
445 D21B 78 ld a,b
446 D21C B7 or a
447 D21D CA D1EF jp z,readnx ;skip if len=0
448 ;buffer has characters, resend last char
449 D220 7E ld a,(hl)
450 D221 05 dec b
451 D222 2B dec hl ;A = last char
452 ;blen=blen-1, next to fill - 1 decremented
453 D223 C3 D2A9 jp rdech1 ;act like this is an echo
454
455 D226 notrub: ;not a rubout character, check end line
456 D226 FE 05 cp ctle
457 D228 C2 D237 jp nz,note ;physical end line?
458 ;yes, save active counters and force eol
459 D22B C5 push bc
460 D22C E5 push hl
461 D22D CD D1C9 call crlf
462 D230 AF xor a
463 D231 32 D30B ld (strtcol),a ;start position = 00
464 D234 C3 D1F1 jp readn0 ;for another character
465
466 D237 note: ;not end of line, list toggle?
467 D237 FE 10 cp ctlp
468 D239 C2 D248 jp nz,notp ;skip if not ctlp
469 ;list toggle - change parity
470 D23C E5 push hl ;save next to fill - 1
471 D23D 21 D30D ld hl,listcp ;HL=.listcp flag
472 D240 3E 01 ld a,1
473'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-8
474
475
476 D242 96 sub (hl) ;True-listcp
477 D243 77 ld (hl),a ;listcp = not listcp
478 D244 E1 pop hl
479 D245 C3 D1EF jp readnx ;for another char
480
481 D248 notp: ;not a ctlp, line delete?
482 D248 FE 18 cp ctlx
483 D24A C2 D25F jp nz,notx
484 D24D E1 pop hl ;discard start position
485 ;loop while column > strtcol
486 D24E 3A D30B backx: ld a,(strtcol)
487 D251 21 D30C ld hl,column
488 D254 BE cp (hl)
489 D255 D2 D1E1 jp nc,read ;start again
490 D258 35 dec (hl) ;column = column - 1
491 D259 CD D1A4 call backup ;one position
492 D25C C3 D24E jp backx
493
494 D25F notx: ;not a control x, control u?
495 ;not control-X, control-U?
496 D25F FE 15 cp ctlu
497 D261 C2 D26B jp nz,notu ;skip if not
498 ;delete line (ctlu)
499 D264 CD D1B1 call crlfp ;physical eol
500 D267 E1 pop hl ;discard starting position
501 D268 C3 D1E1 jp read ;to start all over
502
503 D26B notu: ;not line delete, repeat line?
504 D26B FE 12 cp ctlr
505 D26D C2 D2A6 jp nz,notr
506 D270 linelen: ;repeat line, or compute line len (ctlh)
507 ;if compcol > 0
508 D270 C5 push bc
509 D271 CD D1B1 call crlfp ;save line length
510 D274 C1 pop bc
511 D275 E1 pop hl
512 D276 E5 push hl
513 D277 C5 push bc
514 ;bcur, cmax active, beginning buff at HL
515 D278 78 rep0: ld a,b
516 D279 B7 or a
517 D27A CA D28A jp z,rep1 ;count len to 00
518 D27D 23 inc hl
519 D27E 4E ld c,(hl) ;next to print
520 D27F 05 dec b
521 D280 C5 push bc
522 D281 E5 push hl ;count length down
523 D282 CD D17F call ctlout ;character echoed
524 D285 E1 pop hl
525 D286 C1 pop bc ;recall remaining count
526 D287 C3 D278 jp rep0 ;for the next character
527
528 D28A rep1: ;end of repeat, recall lengths
529 ;original BC still remains pushed
530 D28A E5 push hl ;save next to fill
531 D28B 3A D30A ld a,(compcol)
532'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-9
533
534
535 D28E B7 or a ;>0 if computing length
536 D28F CA D1F1 jp z,readn0 ;for another char if so
537 ;column position computed for ctlh
538 D292 21 D30C ld hl,column
539 D295 96 sub (hl) ;diff > 0
540 D296 32 D30A ld (compcol),a ;count down below
541 ;move back compcol-column spaces
542 D299 backsp: ;move back one more space
543 D299 CD D1A4 call backup ;one space
544 D29C 21 D30A ld hl,compcol
545 D29F 35 dec (hl)
546 D2A0 C2 D299 jp nz,backsp
547 D2A3 C3 D1F1 jp readn0 ;for next character
548
549 D2A6 notr: ;not a ctlr, place into buffer
550 D2A6 23 rdecho: inc hl
551 D2A7 77 ld (hl),a ;character filled to mem
552 D2A8 04 inc b ;blen = blen + 1
553 D2A9 rdech1: ;look for a random control character
554 D2A9 C5 push bc
555 D2AA E5 push hl ;active values saved
556 D2AB 4F ld c,a ;ready to print
557 D2AC CD D17F call ctlout ;may be up-arrow C
558 D2AF E1 pop hl
559 D2B0 C1 pop bc
560 D2B1 7E ld a,(hl) ;recall char
561 D2B2 FE 03 cp ctlc ;set flags for reboot test
562 D2B4 78 ld a,b ;move length to A
563 D2B5 C2 D2BD jp nz,notc ;skip if not a control c
564 D2B8 FE 01 cp 1 ;control C, must be length 1
565 D2BA CA 0000 jp z,reboot ;reboot if blen = 1
566 ;length not one, so skip reboot
567 D2BD notc: ;not reboot, are we at end of buffer?
568 D2BD B9 cp c
569 D2BE DA D1EF jp c,readnx ;go for another if not
570 D2C1 readen: ;end of read operation, store blen
571 D2C1 E1 pop hl
572 D2C2 70 ld (hl),b ;M(current len) = B
573 D2C3 0E 0D ld c,cr
574 D2C5 C3 D148 jp conout ;return carriage
575 ; ret
576 D2C8 func1: ;return console character with echo
577 D2C8 CD D106 call conech
578 D2CB C3 D301 jp sta$ret
579
580 D190 func2 equ tabout
581 ;write console character with tab expansion
582
583 D2CE func3: ;return reader character
584 D2CE CD DE15 call readerf
585 D2D1 C3 D301 jp sta$ret
586
587 ;func4: equated to punchf
588 ;write punch character
589
590 ;func5: equated to listf
591'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-10
592
593
594 ;write list character
595 ;write to list device
596
597 D2D4 func6: ;direct console i/o - read if 0ffh
598 D2D4 79 ld a,c
599 D2D5 3C inc a
600 D2D6 CA D2E0 jp z,dirinp ;0ffh => 00h, means input mode
601 D2D9 3C inc a
602 D2DA CA DE06 jp z,constf ;0feH in C for status
603 ;direct output function
604 D2DD C3 DE0C jp conoutf
605
606 D2E0 CD DE06 dirinp: call constf ;status check
607 D2E3 B7 or a
608 D2E4 CA DD91 jp z,retmon ;skip, return 00 if not ready
609 ;character is ready, get it
610 D2E7 CD DE09 call coninf ;to A
611 D2EA C3 D301 jp sta$ret
612
613 D2ED func7: ;return io byte
614 D2ED 3A 0003 ld a,(ioloc)
615 D2F0 C3 D301 jp sta$ret
616
617 D2F3 func8: ;set i/o byte
618 D2F3 21 0003 ld hl,ioloc
619 D2F6 71 ld (hl),c
620 D2F7 C9 ret ;jmp goback
621
622 D2F8 func9: ;write line until $ encountered
623 D2F8 EB ex de,hl ;was lhld info
624 D2F9 4D ld c,l
625 D2FA 44 ld b,h ;BC=string address
626 D2FB C3 D1D3 jp print ;out to console
627
628 D1E1 func10 equ read
629 ;read a buffered console line
630
631 D2FE func11: ;check console status
632 D2FE CD D123 call conbrk
633 ;(drop through to sta$ret)
634 D301 sta$ret: ;store the A register to aret
635 D301 32 D345 ld (aret),a
636 D304 func$ret:
637 D304 C9 ret ;jmp goback (pop stack for non cp/m functions)
638
639 D305 setlret1: ;set lret = 1
640 D305 3E 01 ld a,1
641 D307 C3 D301 jp sta$ret
642
643
644
645 ; data areas
646
647 D30A compcol:
648 D30A 00 db 0 ;true if computing column position
649 D30B strtcol:
650'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-11
651
652
653 D30B 00 db 0 ;starting column position after read
654 D30C 00 column: db 0 ;column position
655 D30D 00 listcp: db 0 ;listing toggle
656 D30E 00 kbchar: db 0 ;initial key char = 00
657 D30F entsp: ds 2 ;entry stack pointer
658 D311 ds ssize*2 ;stack size
659 D341 lstack:
660 ; end of Basic I/O System
661
662 ;*****************************************************************
663 ;*****************************************************************
664
665 ; common values shared between bdosi and bdos
666 D341 usrcode:
667 D341 00 db 0 ;current user number
668 D342 00 curdsk: db 0 ;current disk number
669 D343 info: ds 2 ;information address
670 D345 aret: ds 2 ;address value to return
671 D345 lret equ aret ;low(aret)
672
673 ;*****************************************************************
674 ;*****************************************************************
675 ;** **
676 ;** B a s i c D i s k O p e r a t i n g S y s t e m **
677 ;** **
678 ;*****************************************************************
679 ;*****************************************************************
680
681 0022 dvers equ 22h ;version 2.2
682 ; module addresses
683
684 ; literal constants
685 00FF true equ 0ffh ;constant true
686 0000 false equ 000h ;constant false
687 FFFF enddir equ 0ffffh ;end of directory
688 0001 byte equ 1 ;number of bytes for "byte" type
689 0002 word equ 2 ;number of bytes for "word" type
690
691 ; fixed addresses in low memory
692 005C tfcb equ 005ch ;default fcb location
693 0080 tbuff equ 0080h ;default buffer location
694
695 ; fixed addresses referenced in bios module are
696 ; pererr (0009), selerr (000c), roderr (000f)
697
698 ; error message handlers
699
700 ;per$error: ;report permanent error to user
701 ; ld hl,pererr
702 ; jp goerr
703
704 ;rod$error: ;report read/only disk error
705 ; ld hl,roderr
706 ; jp goerr
707
708 ;rof$error: ;report read/only file error
709'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-12
710
711
712 ; ld hl,roferr
713 ; jp goerr
714
715 D347 sel$error: ;report select error
716 D347 21 D00B ld hl,selerr
717
718
719 D34A goerr: ;HL = .errorhandler, call subroutine
720 D34A 5E ld e,(hl)
721 D34B 23 inc hl
722 D34C 56 ld d,(hl) ;address of routine in DE
723 D34D EB ex de,hl
724 D34E E9 jp (hl) ;to subroutine
725
726
727
728 ; local subroutines for bios interface
729
730 D34F move: ;move data length of length C from source DE to
731 ;destination given by HL
732 D34F 0C inc c ;in case it is zero
733 D350 0D move0: dec c
734 D351 C8 ret z ;more to move
735 D352 1A ld a,(de)
736 D353 77 ld (hl),a ;one byte moved
737 D354 13 inc de
738 D355 23 inc hl ;to next byte
739 D356 C3 D350 jp move0
740
741 D359 selectdisk: ;select the disk drive given by curdsk, and fill
742 ;the base addresses curtrka - alloca, then fill
743 ;the values of the disk parameter block
744 D359 3A D342 ld a,(curdsk)
745 D35C 4F ld c,a ;current disk# to c
746 ;lsb of e = 0 if not yet logged - in
747 D35D CD DE1B call seldskf ;HL filled by call
748 ;HL = 0000 if error, otherwise disk headers
749 D360 7C ld a,h
750 D361 B5 or l
751 D362 C8 ret z ;return with 0000 in HL and z flag
752 ;disk header block address in hl
753 D363 5E ld e,(hl)
754 D364 23 inc hl
755 D365 56 ld d,(hl)
756 D366 23 inc hl ;DE=.tran
757 D367 22 DDB3 ld (cdrmaxa),hl
758 D36A 23 inc hl
759 D36B 23 inc hl ;.cdrmax
760 D36C 22 DDB5 ld (curtrka),hl
761 D36F 23 inc hl
762 D370 23 inc hl ;HL=.currec
763 D371 22 DDB7 ld (curreca),hl
764 D374 23 inc hl
765 D375 23 inc hl ;HL=.buffa
766 ;DE still contains .tran
767 D376 EB ex de,hl
768'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-13
769
770
771 D377 22 DDD0 ld (tranv),hl ;.tran vector
772 D37A 21 DDB9 ld hl,buffa ;DE= source for move, HL=dest
773 D37D 0E 08 ld c,addlist
774 D37F CD D34F call move ;addlist filled
775 ;now fill the disk parameter block
776 D382 2A DDBB ld hl,(dpbaddr)
777 D385 EB ex de,hl ;DE is source
778 D386 21 DDC1 ld hl,sectpt ;HL is destination
779 D389 0E 0F ld c,dpblist
780 D38B CD D34F call move ;data filled
781 ;now set single/double map mode
782 D38E 2A DDC6 ld hl,(maxall) ;largest allocation number
783 D391 7C ld a,h ;00 indicates < 255
784 D392 21 DDDD ld hl,single
785 D395 36 FF ld (hl),true ;assume a=00
786 D397 B7 or a
787 D398 CA D39D jp z,retselect
788 ;high order of maxall not zero, use double dm
789 D39B 36 00 ld (hl),false
790 D39D retselect:
791 D39D 3E FF ld a,true
792 D39F B7 or a
793 D3A0 C9 ret ;select disk function ok
794
795 D3A1 home: ;move to home position, then offset to start of dir
796 D3A1 CD DE18 call homef ;move to track 00, sector 00 reference
797 ;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf
798 ;first directory position selected
799 D3A4 AF xor a ;constant zero to accumulator
800 D3A5 2A DDB5 ld hl,(curtrka)
801 D3A8 77 ld (hl),a
802 D3A9 23 inc hl
803 D3AA 77 ld (hl),a ;curtrk=0000
804 D3AB 2A DDB7 ld hl,(curreca)
805 D3AE 77 ld (hl),a
806 D3AF 23 inc hl
807 D3B0 77 ld (hl),a ;currec=0000
808 ;curtrk, currec both set to 0000
809 D3B1 C9 ret
810
811 D3B2 rdbuff: ;read buffer and check condition
812 D3B2 CD DE27 call readf ;current drive, track, sector, dma
813 D3B5 C3 D3BB jp diocomp ;check for i/o errors
814
815 D3B8 wrbuff: ;write buffer and check condition
816 ;write type (wrtype) is in register C
817 ;wrtype = 0 => normal write operation
818 ;wrtype = 1 => directory write operation
819 ;wrtype = 2 => start of new block
820 D3B8 CD DE2A call writef ;current drive, track, sector, dma
821 D3BB diocomp: ;check for disk errors
822 D3BB B7 or a
823 D3BC C8 ret z
824 D3BD 21 D009 ld hl,pererr
825 D3C0 C3 D34A jp goerr
826
827'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-14
828
829
830 D3C3 seek$dir: ;seek the record containing the current dir entry
831 D3C3 2A DDEA ld hl,(dcnt) ;directory counter to HL
832 D3C6 0E 02 ld c,dskshf
833 D3C8 CD D4EA call hlrotr ;value to HL
834 D3CB 22 DDE5 ld (arecord),hl
835 D3CE 22 DDEC ld (drec),hl ;ready for seek
836 ; jp seek
837 ; ret
838
839
840 D3D1 seek: ;seek the track given by arecord (actual record)
841 ;local equates for registers
842 ;load the registers from memory
843 D3D1 21 DDE5 ld hl,arecord
844 D3D4 4E ld c,(hl)
845 D3D5 23 inc hl
846 D3D6 46 ld b,(hl)
847 D3D7 2A DDB7 ld hl,(curreca)
848 D3DA 5E ld e,(hl)
849 D3DB 23 inc hl
850 D3DC 56 ld d,(hl)
851 D3DD 2A DDB5 ld hl,(curtrka)
852 D3E0 7E ld a,(hl)
853 D3E1 23 inc hl
854 D3E2 66 ld h,(hl)
855 D3E3 6F ld l,a
856 ;loop while arecord < currec
857 D3E4 79 seek0: ld a,c
858 D3E5 93 sub e
859 D3E6 78 ld a,b
860 D3E7 9A sbc a,d
861 D3E8 D2 D3FA jp nc,seek1 ;skip if arecord >= currec
862 ;currec = currec - sectpt
863 D3EB E5 push hl
864 D3EC 2A DDC1 ld hl,(sectpt)
865 D3EF 7B ld a,e
866 D3F0 95 sub l
867 D3F1 5F ld e,a
868 D3F2 7A ld a,d
869 D3F3 9C sbc a,h
870 D3F4 57 ld d,a
871 D3F5 E1 pop hl
872 ;curtrk = curtrk - 1
873 D3F6 2B dec hl
874 D3F7 C3 D3E4 jp seek0 ;for another try
875
876 D3FA seek1: ;look while arecord >= (t:=currec + sectpt)
877 D3FA E5 push hl
878 D3FB 2A DDC1 ld hl,(sectpt)
879 D3FE 19 add hl,de ;HL = currec+sectpt
880 D3FF DA D40F jp c,seek2 ;can be > FFFFH
881 D402 79 ld a,c
882 D403 95 sub l
883 D404 78 ld a,b
884 D405 9C sbc a,h
885 D406 DA D40F jp c,seek2 ;skip if t > arecord
886'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-15
887
888
889 ;currec = t
890 D409 EB ex de,hl
891 ;curtrk = curtrk + 1
892 D40A E1 pop hl
893 D40B 23 inc hl
894 D40C C3 D3FA jp seek1 ;for another try
895
896 D40F E1 seek2: pop hl
897 ;arrive here with updated values in each register
898 D410 C5 push bc
899 D411 D5 push de
900 D412 E5 push hl ;to stack for later
901 ;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk
902 D413 EB ex de,hl
903 D414 2A DDCE ld hl,(offset)
904 D417 19 add hl,de ;HL = curtrk+offset
905 D418 44 ld b,h
906 D419 4D ld c,l
907 D41A CD DE1E call settrkf ;track set up
908 ;note that BC - curtrk is difference to move in bios
909 D41D D1 pop de ;recall curtrk
910 D41E 2A DDB5 ld hl,(curtrka)
911 D421 73 ld (hl),e
912 D422 23 inc hl
913 D423 72 ld (hl),d ;curtrk updated
914 ;now compute sector as arecord-currec
915 D424 D1 pop de ;recall currec
916 D425 2A DDB7 ld hl,(curreca)
917 D428 73 ld (hl),e
918 D429 23 inc hl
919 D42A 72 ld (hl),d
920 D42B C1 pop bc ;BC=arecord, DE=currec
921 D42C 79 ld a,c
922 D42D 93 sub e
923 D42E 4F ld c,a
924 D42F 78 ld a,b
925 D430 9A sbc a,d
926 D431 47 ld b,a
927 D432 2A DDD0 ld hl,(tranv)
928 D435 EB ex de,hl ;BC=sector#, DE=.tran
929 D436 CD DE30 call sectran ;HL = tran(sector)
930 D439 4D ld c,l
931 D43A 44 ld b,h ;BC = tran(sector)
932 D43B C3 DE21 jp setsecf ;sector selected
933 ; ret
934
935 ; file control block (fcb) constants
936 00E5 empty equ 0e5h ;empty directory entry
937 007F lstrec equ 127 ;last record# in extent
938 0080 recsiz equ 128 ;record size
939 0020 fcblen equ 32 ;file control block size
940 0004 dirrec equ recsiz/fcblen ;directory elts / record
941 0002 dskshf equ 2 ;log2(dirrec)
942 0003 dskmsk equ dirrec-1
943 0005 fcbshf equ 5 ;log2(fcblen)
944
945'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-16
946
947
948 000C extnum equ 12 ;extent number field
949 001F maxext equ 31 ;largest extent number
950 000D ubytes equ 13 ;unfilled bytes field
951 000E modnum equ 14 ;data module number
952 000F maxmod equ 15 ;largest module number
953 0080 fwfmsk equ 80h ;file write flag is high order modnum
954 000F namlen equ 15 ;name length
955 000F reccnt equ 15 ;record count field
956 0010 dskmap equ 16 ;disk map field
957 001F lstfcb equ fcblen-1
958 0020 nxtrec equ fcblen
959 0021 ranrec equ nxtrec+1 ;random record field (2 bytes)
960
961 ; reserved file indicators
962 0009 rofile equ 9 ;high order of first type char
963 000A invis equ 10 ;invisible file in dir command
964 ; equ 11 ;reserved
965
966 ; utility functions for file access
967
968 D43E dm$position: ;compute disk map position for vrecord to HL
969 D43E 21 DDC3 ld hl,blkshf
970 D441 4E ld c,(hl) ;shift count to C
971 D442 3A DDE3 ld a,(vrecord) ;current virtual record to A
972 D445 B7 dmpos0: or a
973 D446 1F rra
974 D447 0D dec c
975 D448 C2 D445 jp nz,dmpos0
976 ;A = shr(vrecord,blkshf) = vrecord/2**(sect/block)
977 D44B 47 ld b,a ;save it for later addition
978 D44C 3E 08 ld a,8
979 D44E 96 sub (hl) ;8-blkshf to accumulator
980 D44F 4F ld c,a ;extent shift count in register c
981 D450 3A DDE2 ld a,(extval) ;extent value ani extmsk
982 D453 dmpos1:
983 ;blkshf = 3,4,5,6,7, C=5,4,3,2,1
984 ;shift is 4,3,2,1,0
985 D453 0D dec c
986 D454 CA D45C jp z,dmpos2
987 D457 B7 or a
988 D458 17 rla
989 D459 C3 D453 jp dmpos1
990
991 D45C dmpos2: ;arrive here with A = shl(ext and extmsk,7-blkshf)
992 D45C 80 add a,b ;add the previous shr(vrecord,blkshf) value
993 ;A is one of the following values, depending upon alloc
994 ;bks blkshf
995 ;1k 3 v/8 + extval * 16
996 ;2k 4 v/16+ extval * 8
997 ;4k 5 v/32+ extval * 4
998 ;8k 6 v/64+ extval * 2
999 ;16k 7 v/128+extval * 1
1000 D45D C9 ret ;with dm$position in A
1001
1002 D45E getdm: ;return disk map value from position given by BC
1003 D45E 2A D343 ld hl,(info) ;base address of file control block
1004'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-17
1005
1006
1007 D461 11 0010 ld de,dskmap
1008 D464 19 add hl,de ;HL =.diskmap
1009 D465 09 add hl,bc ;index by a single byte value
1010 D466 3A DDDD ld a,(single) ;single byte/map entry?
1011 D469 B7 or a
1012 D46A CA D471 jp z,getdmd ;get disk map single byte
1013 D46D 6E ld l,(hl)
1014 D46E 26 00 ld h,0
1015 D470 C9 ret ;with HL=00bb
1016 D471 getdmd:
1017 D471 09 add hl,bc ;HL=.fcb(dm+i*2)
1018 ;double precision value returned
1019 D472 5E ld e,(hl)
1020 D473 23 inc hl
1021 D474 56 ld d,(hl)
1022 D475 EB ex de,hl
1023 D476 C9 ret
1024
1025 D477 index: ;compute disk block number from current fcb
1026 D477 CD D43E call dm$position ;0...15 in register A
1027 D47A 4F ld c,a
1028 D47B 06 00 ld b,0
1029 D47D CD D45E call getdm ;value to HL
1030 D480 22 DDE5 ld (arecord),hl
1031 D483 C9 ret
1032
1033 D484 allocated: ;called following index to see if block allocated
1034 D484 2A DDE5 ld hl,(arecord)
1035 D487 7D ld a,l
1036 D488 B4 or h
1037 D489 C9 ret
1038
1039 D48A atran: ;compute actual record address, assuming index called
1040 D48A 3A DDC3 ld a,(blkshf) ;shift count to reg A
1041 D48D 2A DDE5 ld hl,(arecord)
1042 D490 29 atran0: add hl,hl
1043 D491 3D dec a
1044 D492 C2 D490 jp nz,atran0 ;shl(arecord,blkshf)
1045 D495 22 DDE7 ld (arecord1),hl ;save shifted block #
1046 D498 3A DDC4 ld a,(blkmsk)
1047 D49B 4F ld c,a ;mask value to C
1048 D49C 3A DDE3 ld a,(vrecord)
1049 D49F A1 and c ;masked value in A
1050 D4A0 B5 or l
1051 D4A1 6F ld l,a ;to HL
1052 D4A2 22 DDE5 ld (arecord),hl ;arecord=HL or (vrecord and blkmsk)
1053 D4A5 C9 ret
1054
1055 D4A6 getexta: ;get current extent field address to A
1056 D4A6 2A D343 ld hl,(info)
1057 D4A9 11 000C ld de,extnum
1058 D4AC 19 add hl,de ;HL=.fcb(extnum)
1059 D4AD C9 ret
1060
1061 D4AE getfcba: ;compute reccnt and nxtrec addresses for get/setfcb
1062 D4AE 2A D343 ld hl,(info)
1063'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-18
1064
1065
1066 D4B1 11 000F ld de,reccnt
1067 D4B4 19 add hl,de
1068 D4B5 EB ex de,hl ;DE=.fcb(reccnt)
1069 D4B6 21 0011 ld hl,nxtrec-reccnt
1070 D4B9 19 add hl,de ;HL=.fcb(nxtrec)
1071 D4BA C9 ret
1072
1073 D4BB getfcb: ;set variables from currently addressed fcb
1074 D4BB CD D4AE call getfcba ;addresses in DE, HL
1075 D4BE 7E ld a,(hl)
1076 D4BF 32 DDE3 ld (vrecord),a ;vrecord=fcb(nxtrec)
1077 D4C2 EB ex de,hl
1078 D4C3 7E ld a,(hl)
1079 D4C4 32 DDE1 ld (rcount),a ;rcount=fcb(reccnt)
1080 D4C7 CD D4A6 call getexta ;HL=.fcb(extnum)
1081 D4CA 3A DDC5 ld a,(extmsk) ;extent mask to a
1082 D4CD A6 and (hl) ;fcb(extnum) and extmsk
1083 D4CE 32 DDE2 ld (extval),a
1084 D4D1 C9 ret
1085
1086 D4D2 setfcb: ;place values back into current fcb
1087 D4D2 CD D4AE call getfcba ;addresses to DE, HL
1088 D4D5 3A DDD5 ld a,(seqio)
1089 D4D8 FE 02 cp 02
1090 D4DA C2 D4DE jp nz,setfcb1
1091 D4DD AF xor a ;check ranfill
1092 D4DE setfcb1:
1093 D4DE 4F ld c,a ;=1 if sequential i/o
1094 D4DF 3A DDE3 ld a,(vrecord)
1095 D4E2 81 add a,c
1096 D4E3 77 ld (hl),a ;fcb(nxtrec)=vrecord+seqio
1097 D4E4 EB ex de,hl
1098 D4E5 3A DDE1 ld a,(rcount)
1099 D4E8 77 ld (hl),a ;fcb(reccnt)=rcount
1100 D4E9 C9 ret
1101
1102 D4EA hlrotr: ;hl rotate right by amount C
1103 D4EA 0C inc c ;in case zero
1104 D4EB hlrotr0:
1105 D4EB 0D dec c
1106 D4EC C8 ret z ;return when zero
1107 D4ED 7C ld a,h
1108 D4EE B7 or a
1109 D4EF 1F rra
1110 D4F0 67 ld h,a ;high byte
1111 D4F1 7D ld a,l
1112 D4F2 1F rra
1113 D4F3 6F ld l,a ;low byte
1114 D4F4 C3 D4EB jp hlrotr0
1115
1116 D4F7 compute$cs: ;compute checksum for current directory buffer
1117 D4F7 0E 80 ld c,recsiz ;size of directory buffer
1118 D4F9 2A DDB9 ld hl,(buffa) ;current directory buffer
1119 D4FC AF xor a ;clear checksum value
1120 D4FD computecs0:
1121 D4FD 86 add a,(hl)
1122'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-19
1123
1124
1125 D4FE 23 inc hl
1126 D4FF 0D dec c ;cs=cs+buff(recsiz-C)
1127 D500 C2 D4FD jp nz,computecs0
1128 D503 C9 ret ;with checksum in A
1129
1130 D504 hlrotl: ;rotate the mask in HL by amount in C
1131 D504 0C inc c ;may be zero
1132 D505 hlrotl0:
1133 D505 0D dec c
1134 D506 C8 ret z ;return if zero
1135 D507 29 add hl,hl
1136 D508 C3 D505 jp hlrotl0
1137
1138 D50B set$cdisk: ;set a "1" value in curdsk position of BC
1139 D50B C5 push bc ;save input parameter
1140 D50C 3A D342 ld a,(curdsk)
1141 D50F 4F ld c,a ;ready parameter for shift
1142 D510 21 0001 ld hl,1 ;number to shift
1143 D513 CD D504 call hlrotl ;HL = mask to integrate
1144 D516 C1 pop bc ;original mask
1145 D517 79 ld a,c
1146 D518 B5 or l
1147 D519 6F ld l,a
1148 D51A 78 ld a,b
1149 D51B B4 or h
1150 D51C 67 ld h,a ;HL = mask or rol(1,curdsk)
1151 D51D C9 ret
1152
1153 D51E nowrite: ;return true if dir checksum difference occurred
1154 D51E 2A DDAD ld hl,(rodsk)
1155 D521 3A D342 ld a,(curdsk)
1156 D524 4F ld c,a
1157 D525 CD D4EA call hlrotr
1158 D528 7D ld a,l
1159 D529 E6 01 and 1b
1160 D52B C9 ret ;non zero if nowrite
1161
1162 D52C set$ro: ;set current disk to read only
1163 D52C 21 DDAD ld hl,rodsk
1164 D52F 4E ld c,(hl)
1165 D530 23 inc hl
1166 D531 46 ld b,(hl)
1167 D532 CD D50B call set$cdisk ;sets bit to 1
1168 D535 22 DDAD ld (rodsk),hl
1169 ;high water mark in directory goes to max
1170 D538 2A DDC8 ld hl,(dirmax)
1171 D53B 23 inc hl
1172 D53C EB ex de,hl ;DE = directory max
1173 D53D 2A DDB3 ld hl,(cdrmaxa) ;HL = .cdrmax
1174 D540 73 ld (hl),e
1175 D541 23 inc hl
1176 D542 72 ld (hl),d ;cdrmax = dirmax
1177 D543 C9 ret
1178
1179 D544 check$rodir: ;check current directory element for read/only status
1180 D544 CD D55E call getdptra ;address of element
1181'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-20
1182
1183
1184
1185 D547 check$rofile: ;check current buff(dptr) or fcb(0) for r/o status
1186 D547 11 0009 ld de,rofile
1187 D54A 19 add hl,de ;offset to ro bit
1188 D54B 7E ld a,(hl)
1189 D54C 17 rla
1190 D54D D0 ret nc ;return if not set
1191 D54E 21 D00F ld hl,roferr
1192 D551 C3 D34A jp goerr
1193 ; jp rof$error ;exit to read only disk message
1194
1195
1196 D554 check$write: ;check for write protected disk
1197 D554 CD D51E call nowrite
1198 D557 C8 ret z ;ok to write if not rodsk
1199 D558 21 D00D ld hl,roderr
1200 D55B C3 D34A jp goerr
1201 ; jp rod$error ;read only disk error
1202
1203 D55E getdptra: ;compute the address of a directory element at
1204 ;positon dptr in the buffer
1205 D55E 2A DDB9 ld hl,(buffa)
1206 D561 3A DDE9 ld a,(dptr)
1207 D564 addh: ;HL = HL + A
1208 D564 85 add a,l
1209 D565 6F ld l,a
1210 D566 D0 ret nc
1211 ;overflow to H
1212 D567 24 inc h
1213 D568 C9 ret
1214
1215
1216 D569 getmodnum: ;compute the address of the module number
1217 ;bring module number to accumulator
1218 ;(high order bit is fwf (file write flag)
1219 D569 2A D343 ld hl,(info)
1220 D56C 11 000E ld de,modnum
1221 D56F 19 add hl,de ;HL=.fcb(modnum)
1222 D570 7E ld a,(hl)
1223 D571 C9 ret ;A=fcb(modnum)
1224
1225 D572 clrmodnum: ;clear the module number field for user open/make
1226 D572 CD D569 call getmodnum
1227 D575 36 00 ld (hl),0 ;fcb(modnum)=0
1228 D577 C9 ret
1229
1230 D578 CD D569 setfwf: call getmodnum ;HL=.fcb(modnum), A=fcb(modnum)
1231 ;set fwf (file write flag) to "1"
1232 D57B F6 80 or fwfmsk
1233 D57D 77 ld (hl),a ;fcb(modnum)=fcb(modnum) or 80h
1234 ;also returns non zero in accumulator
1235 D57E C9 ret
1236
1237
1238 D57F compcdr: ;return cy if cdrmax > dcnt
1239 D57F 2A DDEA ld hl,(dcnt)
1240'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-21
1241
1242
1243 D582 EB ex de,hl ;DE = directory counter
1244 D583 2A DDB3 ld hl,(cdrmaxa) ;HL=.cdrmax
1245 D586 7B ld a,e
1246 D587 96 sub (hl) ;low(dcnt) - low(cdrmax)
1247 D588 23 inc hl ;HL = .cdrmax+1
1248 D589 7A ld a,d
1249 D58A 9E sbc a,(hl) ;hig(dcnt) - hig(cdrmax)
1250 ;condition dcnt - cdrmax produces cy if cdrmax>dcnt
1251 D58B C9 ret
1252
1253 D58C setcdr: ;if not (cdrmax > dcnt) then cdrmax = dcnt+1
1254 D58C CD D57F call compcdr
1255 D58F D8 ret c ;return if cdrmax > dcnt
1256 ;otherwise, HL = .cdrmax+1, DE = dcnt
1257 D590 13 inc de
1258 D591 72 ld (hl),d
1259 D592 2B dec hl
1260 D593 73 ld (hl),e
1261 D594 C9 ret
1262
1263 D595 subdh: ;compute HL = DE - HL
1264 D595 7B ld a,e
1265 D596 95 sub l
1266 D597 6F ld l,a
1267 D598 7A ld a,d
1268 D599 9C sbc a,h
1269 D59A 67 ld h,a
1270 D59B C9 ret
1271
1272 D59C newchecksum:
1273 D59C 0E FF ld c,true ;drop through to compute new checksum
1274 D59E checksum: ;compute current checksum record and update the
1275 ;directory element if C=true, or check for = if not
1276 ;drec < chksiz?
1277 D59E 2A DDEC ld hl,(drec)
1278 D5A1 EB ex de,hl
1279 D5A2 2A DDCC ld hl,(chksiz)
1280 D5A5 CD D595 call subdh ;DE-HL
1281 D5A8 D0 ret nc ;skip checksum if past checksum vector size
1282 ;drec < chksiz, so continue
1283 D5A9 C5 push bc ;save init flag
1284 D5AA CD D4F7 call compute$cs ;check sum value to A
1285 D5AD 2A DDBD ld hl,(checka) ;address of check sum vector
1286 D5B0 EB ex de,hl
1287 D5B1 2A DDEC ld hl,(drec) ;value of drec
1288 D5B4 19 add hl,de ;HL = .check(drec)
1289 D5B5 C1 pop bc ;recall true=0ffh or false=00 to C
1290 D5B6 0C inc c ;0ffh produces zero flag
1291 D5B7 CA D5C4 jp z,initial$cs
1292 ;not initializing, compare
1293 D5BA BE cp (hl) ;compute$cs=check(drec)?
1294 D5BB C8 ret z ;no message if ok
1295 ;checksum error, are we beyond
1296 ;the end of the disk?
1297 D5BC CD D57F call compcdr
1298 D5BF D0 ret nc ;no message if so
1299'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-22
1300
1301
1302 D5C0 CD D52C call set$ro ;read/only disk set
1303 D5C3 C9 ret
1304
1305 D5C4 initial$cs: ;initializing the checksum
1306 D5C4 77 ld (hl),a
1307 D5C5 C9 ret
1308
1309
1310 D5C6 wrdir: ;write the current directory entry, set checksum
1311 D5C6 CD D59C call newchecksum ;initialize entry
1312 D5C9 CD D5E0 call setdir ;directory dma
1313 D5CC 0E 01 ld c,1 ;indicates a write directory operation
1314 D5CE CD D3B8 call wrbuff ;write the buffer
1315 D5D1 C3 D5DA jp setdata ;to data dma address
1316 ; ret
1317 D5D4 rd$dir: ;read a directory entry into the directory buffer
1318 D5D4 CD D5E0 call setdir ;directory dma
1319 D5D7 CD D3B2 call rdbuff ;directory record loaded
1320 ;jmp setdata to data dma address
1321 ; ret
1322 D5DA setdata: ;set data dma address
1323 D5DA 21 DDB1 ld hl,dmaad
1324 D5DD C3 D5E3 jp setdma ;to complete the call
1325
1326 D5E0 setdir: ;set directory dma address
1327 D5E0 21 DDB9 ld hl,buffa ;jmp setdma to complete call
1328
1329 D5E3 setdma: ;HL=.dma address to set (i.e., buffa or dmaad)
1330 D5E3 4E ld c,(hl)
1331 D5E4 23 inc hl
1332 D5E5 46 ld b,(hl) ;parameter ready
1333 D5E6 C3 DE24 jp setdmaf
1334
1335 D5E9 dir$to$user: ;copy the directory entry to the user buffer
1336 ;after call to search or searchn by user code
1337 D5E9 2A DDB9 ld hl,(buffa)
1338 D5EC EB ex de,hl ;source is directory buffer
1339 D5ED 2A DDB1 ld hl,(dmaad) ;destination is user dma address
1340 D5F0 0E 80 ld c,recsiz ;copy entire record
1341 D5F2 C3 D34F jp move
1342 ; ret
1343
1344 D5F5 end$of$dir: ;return zero flag if at end of directory, non zero
1345 ;if not at end (end of dir if dcnt = 0ffffh)
1346 D5F5 21 DDEA ld hl,dcnt
1347 D5F8 7E ld a,(hl) ;may be 0ffh
1348 D5F9 23 inc hl
1349 D5FA BE cp (hl) ;low(dcnt) = high(dcnt)?
1350 D5FB C0 ret nz ;non zero returned if different
1351 ;high and low the same, = 0ffh?
1352 D5FC 3C inc a ;0ffh becomes 00 if so
1353 D5FD C9 ret
1354
1355 D5FE set$end$dir: ;set dcnt to the end of the directory
1356 D5FE 21 FFFF ld hl,enddir
1357 D601 22 DDEA ld (dcnt),hl
1358'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-23
1359
1360
1361 D604 C9 ret
1362
1363 D605 read$dir: ;read next directory entry, with C=true if initializing
1364 D605 2A DDC8 ld hl,(dirmax)
1365 D608 EB ex de,hl ;in preparation for subtract
1366 D609 2A DDEA ld hl,(dcnt)
1367 D60C 23 inc hl
1368 D60D 22 DDEA ld (dcnt),hl ;dcnt=dcnt+1
1369 ;continue while dirmax >= dcnt (dirmax-dcnt no cy)
1370 D610 CD D595 call subdh ;DE-HL
1371 D613 D2 D619 jp nc,read$dir0
1372 ;yes, set dcnt to end of directory
1373 D616 C3 D5FE jp set$end$dir
1374 ; ret
1375
1376 D619 read$dir0: ;not at end of directory, seek next element
1377 ;initialization flag is in C
1378 D619 3A DDEA ld a,(dcnt)
1379 D61C E6 03 and dskmsk ;low(dcnt) and dskmsk
1380 D61E 06 05 ld b,fcbshf ;to multiply by fcb size
1381 D620 read$dir1:
1382 D620 87 add a,a
1383 D621 05 dec b
1384 D622 C2 D620 jp nz,read$dir1
1385 ;A = (low(dcnt) and dskmsk) shl fcbshf
1386 D625 32 DDE9 ld (dptr),a ;ready for next dir operation
1387 D628 B7 or a
1388 D629 C0 ret nz ;return if not a new record
1389 D62A C5 push bc ;save initialization flag C
1390 D62B CD D3C3 call seek$dir ;seek proper record
1391 D62E CD D5D4 call rd$dir ;read the directory record
1392 D631 C1 pop bc ;recall initialization flag
1393 D632 C3 D59E jp checksum ;checksum the directory elt
1394 ; ret
1395
1396
1397 D635 getallocbit: ;given allocation vector position BC, return with byte
1398 ;containing BC shifted so that the least significant
1399 ;bit is in the low order accumulator position. HL is
1400 ;the address of the byte for possible replacement in
1401 ;memory upon return, and D contains the number of shifts
1402 ;required to place the returned value back into position
1403 D635 79 ld a,c
1404 D636 E6 07 and 111b
1405 D638 3C inc a
1406 D639 5F ld e,a
1407 D63A 57 ld d,a
1408 ;d and e both contain the number of bit positions to shift
1409 D63B 79 ld a,c
1410 D63C 0F rrca
1411 D63D 0F rrca
1412 D63E 0F rrca
1413 D63F E6 1F and 11111b
1414 D641 4F ld c,a ;C shr 3 to C
1415 D642 78 ld a,b
1416 D643 87 add a,a
1417'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-24
1418
1419
1420 D644 87 add a,a
1421 D645 87 add a,a
1422 D646 87 add a,a
1423 D647 87 add a,a ;B shl 5
1424 D648 B1 or c
1425 D649 4F ld c,a ;bbbccccc to C
1426 D64A 78 ld a,b
1427 D64B 0F rrca
1428 D64C 0F rrca
1429 D64D 0F rrca
1430 D64E E6 1F and 11111b
1431 D650 47 ld b,a ;BC shr 3 to BC
1432 D651 2A DDBF ld hl,(alloca) ;base address of allocation vector
1433 D654 09 add hl,bc
1434 D655 7E ld a,(hl) ;byte to A, hl = .alloc(BC shr 3)
1435 ;now move the bit to the low order position of A
1436 D656 07 rotl: rlca
1437 D657 1D dec e
1438 D658 C2 D656 jp nz,rotl
1439 D65B C9 ret
1440
1441
1442 D65C set$alloc$bit: ;BC is the bit position of ALLOC to set or reset. The
1443 ;value of the bit is in register E.
1444 D65C D5 push de
1445 D65D CD D635 call getallocbit ;shifted val A, count in D
1446 D660 E6 FE and 11111110b ;mask low bit to zero (may be set)
1447 D662 C1 pop bc
1448 D663 B1 or c ;low bit of C is masked into A
1449 ; jp rotr ;to rotate back into proper position
1450 ; ret
1451 D664 rotr:
1452 ;byte value from ALLOC is in register A, with shift count
1453 ;in register C (to place bit back into position), and
1454 ;target ALLOC position in registers HL, rotate and replace
1455 D664 0F rrca
1456 D665 15 dec d
1457 D666 C2 D664 jp nz,rotr ;back into position
1458 D669 77 ld (hl),a ;back to ALLOC
1459 D66A C9 ret
1460
1461 D66B scandm: ;scan the disk map addressed by dptr for non-zero
1462 ;entries, the allocation vector entry corresponding
1463 ;to a non-zero entry is set to the value of C (0,1)
1464 D66B CD D55E call getdptra ;HL = buffa + dptr
1465 ;HL addresses the beginning of the directory entry
1466 D66E 11 0010 ld de,dskmap
1467 D671 19 add hl,de ;hl now addresses the disk map
1468 D672 C5 push bc ;save the 0/1 bit to set
1469 D673 0E 11 ld c,fcblen-dskmap+1;size of single byte disk map + 1
1470 D675 scandm0: ;loop once for each disk map entry
1471 D675 D1 pop de ;recall bit parity
1472 D676 0D dec c
1473 D677 C8 ret z ;all done scanning?
1474 ;no, get next entry for scan
1475 D678 D5 push de ;replace bit parity
1476'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-25
1477
1478
1479 D679 3A DDDD ld a,(single)
1480 D67C B7 or a
1481 D67D CA D688 jp z,scandm1
1482 ;single byte scan operation
1483 D680 C5 push bc ;save counter
1484 D681 E5 push hl ;save map address
1485 D682 4E ld c,(hl)
1486 D683 06 00 ld b,0 ;BC=block#
1487 D685 C3 D68E jp scandm2
1488
1489 D688 scandm1: ;double byte scan operation
1490 D688 0D dec c ;count for double byte
1491 D689 C5 push bc ;save counter
1492 D68A 4E ld c,(hl)
1493 D68B 23 inc hl
1494 D68C 46 ld b,(hl) ;BC=block#
1495 D68D E5 push hl ;save map address
1496 D68E scandm2: ;arrive here with BC=block#, E=0/1
1497 D68E 79 ld a,c
1498 D68F B0 or b ;skip if = 0000
1499 D690 CA D69D jp z,scanm3
1500 D693 2A DDC6 ld hl,(maxall) ;check invalid index
1501 D696 7D ld a,l
1502 D697 91 sub c
1503 D698 7C ld a,h
1504 D699 98 sbc a,b ;maxall - block#
1505 D69A D4 D65C call nc,set$alloc$bit
1506 ;bit set to 0/1
1507 D69D E1 scanm3: pop hl
1508 D69E 23 inc hl ;to next bit position
1509 D69F C1 pop bc ;recall counter
1510 D6A0 C3 D675 jp scandm0 ;for another item
1511
1512 D6A3 initialize: ;initialize the current disk
1513 ;lret = false ;set to true if $ file exists
1514 ;compute the length of the allocation vector - 2
1515 D6A3 2A DDC6 ld hl,(maxall)
1516 D6A6 0E 03 ld c,3 ;perform maxall/8
1517 ;number of bytes in alloc vector is (maxall/8)+1
1518 D6A8 CD D4EA call hlrotr
1519 D6AB 23 inc hl ;HL = maxall/8+1
1520 D6AC 44 ld b,h
1521 D6AD 4D ld c,l ;count down BC til zero
1522 D6AE 2A DDBF ld hl,(alloca) ;base of allocation vector
1523 ;fill the allocation vector with zeros
1524 D6B1 initial0:
1525 D6B1 36 00 ld (hl),0
1526 D6B3 23 inc hl ;alloc(i)=0
1527 D6B4 0B dec bc ;count length down
1528 D6B5 78 ld a,b
1529 D6B6 B1 or c
1530 D6B7 C2 D6B1 jp nz,initial0
1531 ;set the reserved space for the directory
1532 D6BA 2A DDCA ld hl,(dirblk)
1533 D6BD EB ex de,hl
1534 D6BE 2A DDBF ld hl,(alloca) ;HL=.alloc()
1535'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-26
1536
1537
1538 D6C1 73 ld (hl),e
1539 D6C2 23 inc hl
1540 D6C3 72 ld (hl),d ;sets reserved directory blks
1541 ;allocation vector initialized, home disk
1542 D6C4 CD D3A1 call home
1543 ;cdrmax = 3 (scans at least one directory record)
1544 D6C7 2A DDB3 ld hl,(cdrmaxa)
1545 D6CA 36 03 ld (hl),3
1546 D6CC 23 inc hl
1547 D6CD 36 00 ld (hl),0
1548 ;cdrmax = 0000
1549 D6CF CD D5FE call set$end$dir ;dcnt = enddir
1550 ;read directory entries and check for allocated storage
1551 D6D2 initial2:
1552 D6D2 0E FF ld c,true
1553 D6D4 CD D605 call read$dir
1554 D6D7 CD D5F5 call end$of$dir
1555 D6DA C8 ret z ;return if end of directory
1556 ;not end of directory, valid entry?
1557 D6DB CD D55E call getdptra ;HL = buffa + dptr
1558 D6DE 3E E5 ld a,empty
1559 D6E0 BE cp (hl)
1560 D6E1 CA D6D2 jp z,initial2 ;go get another item
1561 ;not empty, user code the same?
1562 D6E4 3A D341 ld a,(usrcode)
1563 D6E7 BE cp (hl)
1564 D6E8 C2 D6F6 jp nz,pdollar
1565 ;same user code, check for '$' submit
1566 D6EB 23 inc hl
1567 D6EC 7E ld a,(hl) ;first character
1568 D6ED D6 24 sub '$' ;dollar file?
1569 D6EF C2 D6F6 jp nz,pdollar
1570 ;dollar file found, mark in lret
1571 D6F2 3D dec a
1572 D6F3 32 D345 ld (lret),a ;lret = 255
1573 D6F6 pdollar: ;now scan the disk map for allocated blocks
1574 D6F6 0E 01 ld c,1 ;set to allocated
1575 D6F8 CD D66B call scandm
1576 D6FB CD D58C call setcdr ;set cdrmax to dcnt
1577 D6FE C3 D6D2 jp initial2 ;for another entry
1578
1579 D701 copy$dirloc: ;copy directory location to lret following
1580 ;delete, rename, ... ops
1581 D701 3A DDD4 ld a,(dirloc)
1582 D704 C3 D301 jp sta$ret
1583 ; ret
1584
1585 D707 compext: ;compare extent# in A with that in C, return nonzero
1586 ;if they do not match
1587 D707 C5 push bc ;save C's original value
1588 D708 F5 push af
1589 D709 3A DDC5 ld a,(extmsk)
1590 D70C 2F cpl
1591 D70D 47 ld b,a
1592 ;B has negated form of extent mask
1593 D70E 79 ld a,c
1594'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-27
1595
1596
1597 D70F A0 and b
1598 D710 4F ld c,a ;low bits removed from C
1599 D711 F1 pop af
1600 D712 A0 and b ;low bits removed from A
1601 D713 91 sub c
1602 D714 E6 1F and maxext ;set flags
1603 D716 C1 pop bc ;restore original values
1604 D717 C9 ret
1605
1606 D718 search: ;search for directory element of length C at info
1607 D718 3E FF ld a,0ffh
1608 D71A 32 DDD4 ld (dirloc),a ;changed if actually found
1609 D71D 21 DDD8 ld hl,searchl
1610 D720 71 ld (hl),c ;searchl = C
1611 D721 2A D343 ld hl,(info)
1612 D724 22 DDD9 ld (searcha),hl ;searcha = info
1613 D727 CD D5FE call set$end$dir ;dcnt = enddir
1614 D72A CD D3A1 call home ;to start at the beginning
1615 ;(drop through to searchn)
1616
1617 D72D searchn: ;search for the next directory element, assuming
1618 ;a previous call on search which sets searcha and
1619 ;searchl
1620 D72D 0E 00 ld c,false
1621 D72F CD D605 call read$dir ;read next dir element
1622 D732 CD D5F5 call end$of$dir
1623 D735 CA D794 jp z,search$fin ;skip to end if so
1624 ;not end of directory, scan for match
1625 D738 2A DDD9 ld hl,(searcha)
1626 D73B EB ex de,hl ;DE=beginning of user fcb
1627 D73C 1A ld a,(de) ;first character
1628 D73D FE E5 cp empty ;keep scanning if empty
1629 D73F CA D74A jp z,searchnext
1630 ;not empty, may be end of logical directory
1631 D742 D5 push de ;save search address
1632 D743 CD D57F call compcdr ;past logical end?
1633 D746 D1 pop de ;recall address
1634 D747 D2 D794 jp nc,search$fin ;artificial stop
1635 D74A searchnext:
1636 D74A CD D55E call getdptra ;HL = buffa+dptr
1637 D74D 3A DDD8 ld a,(searchl)
1638 D750 4F ld c,a ;length of search to c
1639 D751 06 00 ld b,0 ;b counts up, c counts down
1640 D753 searchloop:
1641 D753 79 ld a,c
1642 D754 B7 or a
1643 D755 CA D783 jp z,endsearch
1644 D758 1A ld a,(de)
1645 D759 FE 3F cp '?'
1646 D75B CA D77C jp z,searchok ;? matches all
1647 ;scan next character if not ubytes
1648 D75E 78 ld a,b
1649 D75F FE 0D cp ubytes
1650 D761 CA D77C jp z,searchok
1651 ;not the ubytes field, extent field?
1652 D764 FE 0C cp extnum ;may be extent field
1653'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-28
1654
1655
1656 D766 1A ld a,(de) ;fcb character
1657 D767 CA D773 jp z,searchext ;skip to search extent
1658 D76A 96 sub (hl)
1659 D76B E6 7F and 7fh ;mask-out flags/extent modulus
1660 D76D C2 D72D jp nz,searchn ;skip if not matched
1661 D770 C3 D77C jp searchok ;matched character
1662
1663 D773 searchext: ;A has fcb character
1664 ;attempt an extent # match
1665 D773 C5 push bc ;save counters
1666 D774 4E ld c,(hl) ;directory character to c
1667 D775 CD D707 call compext ;compare user/dir char
1668 D778 C1 pop bc ;recall counters
1669 D779 C2 D72D jp nz,searchn ;skip if no match
1670 D77C searchok: ;current character matches
1671 D77C 13 inc de
1672 D77D 23 inc hl
1673 D77E 04 inc b
1674 D77F 0D dec c
1675 D780 C3 D753 jp searchloop
1676
1677 D783 endsearch: ;entire name matches, return dir position
1678 D783 3A DDEA ld a,(dcnt)
1679 D786 E6 03 and dskmsk
1680 D788 32 D345 ld (lret),a
1681 ;lret = low(dcnt) and 11b
1682 D78B 21 DDD4 ld hl,dirloc
1683 D78E 7E ld a,(hl)
1684 D78F 17 rla
1685 D790 D0 ret nc ;dirloc=0ffh?
1686 ;yes, change it to 0 to mark as found
1687 D791 AF xor a
1688 D792 77 ld (hl),a ;dirloc=0
1689 D793 C9 ret
1690
1691 D794 search$fin: ;end of directory, or empty name
1692 D794 CD D5FE call set$end$dir ;may be artifical end
1693 D797 3E FF ld a,255
1694 D799 C3 D301 jp sta$ret
1695
1696 D79C delete: ;delete the currently addressed file
1697 D79C CD D554 call check$write ;write protected?
1698 D79F 0E 0C ld c,extnum
1699 D7A1 CD D718 call search ;search through file type
1700 D7A4 delete0:
1701 ;loop while directory matches
1702 D7A4 CD D5F5 call end$of$dir
1703 D7A7 C8 ret z ;stop if end
1704 ;set each non zero disk map entry to 0
1705 ;in the allocation vector
1706 ;may be r/o file
1707 D7A8 CD D544 call check$rodir ;ro disk error if found
1708 D7AB CD D55E call getdptra ;HL=.buff(dptr)
1709 D7AE 36 E5 ld (hl),empty
1710 D7B0 0E 00 ld c,0
1711 D7B2 CD D66B call scandm ;alloc elts set to 0
1712'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-29
1713
1714
1715 D7B5 CD D5C6 call wrdir ;write the directory
1716 D7B8 CD D72D call searchn ;to next element
1717 D7BB C3 D7A4 jp delete0 ;for another record
1718
1719 D7BE get$block: ;given allocation vector position BC, find the zero bit
1720 ;closest to this position by searching left and right.
1721 ;if found, set the bit to one and return the bit position
1722 ;in hl. if not found (i.e., we pass 0 on the left, or
1723 ;maxall on the right), return 0000 in hl
1724 D7BE 50 ld d,b
1725 D7BF 59 ld e,c ;copy of starting position to de
1726 D7C0 lefttst:
1727 D7C0 79 ld a,c
1728 D7C1 B0 or b
1729 D7C2 CA D7D1 jp z,righttst ;skip if left=0000
1730 ;left not at position zero, bit zero?
1731 D7C5 0B dec bc
1732 D7C6 D5 push de
1733 D7C7 C5 push bc ;left,right pushed
1734 D7C8 CD D635 call getallocbit
1735 D7CB 1F rra
1736 D7CC D2 D7EC jp nc,retblock ;return block number if zero
1737 ;bit is one, so try the right
1738 D7CF C1 pop bc
1739 D7D0 D1 pop de ;left, right restored
1740 D7D1 righttst:
1741 D7D1 2A DDC6 ld hl,(maxall) ;value of maximum allocation#
1742 D7D4 7B ld a,e
1743 D7D5 95 sub l
1744 D7D6 7A ld a,d
1745 D7D7 9C sbc a,h ;right=maxall?
1746 D7D8 D2 D7F4 jp nc,retblock0 ;return block 0000 if so
1747 D7DB 13 inc de
1748 D7DC C5 push bc
1749 D7DD D5 push de ;left, right pushed
1750 D7DE 42 ld b,d
1751 D7DF 4B ld c,e ;ready right for call
1752 D7E0 CD D635 call getallocbit
1753 D7E3 1F rra
1754 D7E4 D2 D7EC jp nc,retblock ;return block number if zero
1755 D7E7 D1 pop de
1756 D7E8 C1 pop bc ;restore left and right pointers
1757 D7E9 C3 D7C0 jp lefttst ;for another attempt
1758 D7EC retblock:
1759 D7EC 17 rla
1760 D7ED 3C inc a ;bit back into position and set to 1
1761 ;d contains the number of shifts required to reposition
1762 D7EE CD D664 call rotr ;move bit back to position and store
1763 D7F1 E1 pop hl
1764 D7F2 D1 pop de ;HL returned value, DE discarded
1765 D7F3 C9 ret
1766
1767 D7F4 retblock0: ;cannot find an available bit, return 0000
1768 D7F4 79 ld a,c
1769 D7F5 B0 or b
1770 D7F6 C2 D7C0 jp nz,lefttst ;also at beginning
1771'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-30
1772
1773
1774 D7F9 21 0000 ld hl,0000h
1775 D7FC C9 ret
1776
1777 D7FD copy$fcb: ;copy the entire file control block
1778 D7FD 0E 00 ld c,0
1779 D7FF 1E 20 ld e,fcblen ;start at 0, to fcblen-1
1780 ; jp copy$dir
1781
1782 D801 copy$dir: ;copy fcb information starting at C for E bytes
1783 ;into the currently addressed directory entry
1784 D801 D5 push de ;save length for later
1785 D802 06 00 ld b,0 ;double index to BC
1786 D804 2A D343 ld hl,(info) ;HL = source for data
1787 D807 09 add hl,bc
1788 D808 EB ex de,hl ;DE=.fcb(C), source for copy
1789 D809 CD D55E call getdptra ;HL=.buff(dptr), destination
1790 D80C C1 pop bc ;DE=source, HL=dest, C=length
1791 D80D CD D34F call move ;data moved
1792 D810 seek$copy: ;enter from close to seek and copy current element
1793 D810 CD D3C3 call seek$dir ;to the directory element
1794 D813 C3 D5C6 jp wrdir ;write the directory element
1795 ; ret
1796 D816 rename: ;rename the file described by the first half of
1797 ;the currently addressed file control block. the
1798 ;new name is contained in the last half of the
1799 ;currently addressed file conrol block. the file
1800 ;name and type are changed, but the reel number
1801 ;is ignored. the user number is identical
1802 D816 CD D554 call check$write ;may be write protected
1803 ;search up to the extent field
1804 D819 0E 0C ld c,extnum
1805 D81B CD D718 call search
1806 ;copy position 0
1807 D81E 2A D343 ld hl,(info)
1808 D821 7E ld a,(hl) ;HL=.fcb(0), A=fcb(0)
1809 D822 11 0010 ld de,dskmap
1810 D825 19 add hl,de ;HL=.fcb(dskmap)
1811 D826 77 ld (hl),a ;fcb(dskmap)=fcb(0)
1812 ;assume the same disk drive for new named file
1813 D827 rename0:
1814 D827 CD D5F5 call end$of$dir
1815 D82A C8 ret z ;stop at end of dir
1816 ;not end of directory, rename next element
1817 D82B CD D544 call check$rodir ;may be read-only file
1818 D82E 0E 10 ld c,dskmap
1819 D830 1E 0C ld e,extnum
1820 D832 CD D801 call copy$dir
1821 ;element renamed, move to next
1822 D835 CD D72D call searchn
1823 D838 C3 D827 jp rename0
1824
1825 D83B indicators: ;set file indicators for current fcb
1826 D83B 0E 0C ld c,extnum
1827 D83D CD D718 call search ;through file type
1828 D840 CD D5F5 indic0: call end$of$dir
1829 D843 C8 ret z ;stop at end of dir
1830'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-31
1831
1832
1833 ;not end of directory, continue to change
1834 D844 0E 00 ld c,0
1835 D846 1E 0C ld e,extnum ;copy name
1836 D848 CD D801 call copy$dir
1837 D84B CD D72D call searchn
1838 D84E C3 D840 jp indic0
1839
1840 D851 open: ;search for the directory entry, copy to fcb
1841 D851 0E 0F ld c,namlen
1842 D853 CD D718 call search
1843 D856 CD D5F5 call end$of$dir
1844 D859 C8 ret z ;return with lret=255 if end
1845 ;not end of directory, copy fcb information
1846 D85A open$copy: ;(referenced below to copy fcb info)
1847 D85A CD D4A6 call getexta
1848 D85D 7E ld a,(hl)
1849 D85E F5 push af
1850 D85F E5 push hl ;save extent#
1851 D860 CD D55E call getdptra
1852 D863 EB ex de,hl ;DE = .buff(dptr)
1853 D864 2A D343 ld hl,(info) ;HL=.fcb(0)
1854 D867 0E 20 ld c,nxtrec ;length of move operation
1855 D869 D5 push de ;save .buff(dptr)
1856 D86A CD D34F call move ;from .buff(dptr) to .fcb(0)
1857 ;note that entire fcb is copied, including indicators
1858 D86D CD D578 call setfwf ;sets file write flag
1859 D870 D1 pop de
1860 D871 21 000C ld hl,extnum
1861 D874 19 add hl,de ;HL=.buff(dptr+extnum)
1862 D875 4E ld c,(hl) ;C = directory extent number
1863 D876 21 000F ld hl,reccnt
1864 D879 19 add hl,de ;HL=.buff(dptr+reccnt)
1865 D87A 46 ld b,(hl) ;B holds directory record count
1866 D87B E1 pop hl
1867 D87C F1 pop af
1868 D87D 77 ld (hl),a ;restore extent number
1869 ;HL = .user extent#, B = dir rec cnt, C = dir extent#
1870 ;if user ext < dir ext then user := 128 records
1871 ;if user ext = dir ext then user := dir records
1872 ;if user ext > dir ext then user := 0 records
1873 D87E 79 ld a,c
1874 D87F BE cp (hl)
1875 D880 78 ld a,b ;ready dir reccnt
1876 D881 CA D88B jp z,open$rcnt ;if same, user gets dir reccnt
1877 D884 3E 00 ld a,0
1878 D886 DA D88B jp c,open$rcnt ;user is larger
1879 D889 3E 80 ld a,128 ;directory is larger
1880 D88B open$rcnt: ;A has record count to fill
1881 D88B 2A D343 ld hl,(info)
1882 D88E 11 000F ld de,reccnt
1883 D891 19 add hl,de
1884 D892 77 ld (hl),a
1885 D893 C9 ret
1886
1887 D894 mergezero: ;HL = .fcb1(i), DE = .fcb2(i),
1888 ;if fcb1(i) = 0 then fcb1(i) := fcb2(i)
1889'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-32
1890
1891
1892 D894 7E ld a,(hl)
1893 D895 23 inc hl
1894 D896 B6 or (hl)
1895 D897 2B dec hl
1896 D898 C0 ret nz ;return if = 0000
1897 D899 1A ld a,(de)
1898 D89A 77 ld (hl),a
1899 D89B 13 inc de
1900 D89C 23 inc hl ;low byte copied
1901 D89D 1A ld a,(de)
1902 D89E 77 ld (hl),a
1903 D89F 1B dec de
1904 D8A0 2B dec hl ;back to input form
1905 D8A1 C9 ret
1906
1907 D8A2 close: ;locate the directory element and re-write it
1908 D8A2 AF xor a
1909 D8A3 32 D345 ld (lret),a
1910 D8A6 32 DDEA ld (dcnt),a
1911 D8A9 32 DDEB ld (dcnt+1),a
1912 D8AC CD D51E call nowrite
1913 D8AF C0 ret nz ;skip close if r/o disk
1914 ;check file write flag - 0 indicates written
1915 D8B0 CD D569 call getmodnum ;fcb(modnum) in A
1916 D8B3 E6 80 and fwfmsk
1917 D8B5 C0 ret nz ;return if bit remains set
1918 D8B6 0E 0F ld c,namlen
1919 D8B8 CD D718 call search ;locate file
1920 D8BB CD D5F5 call end$of$dir
1921 D8BE C8 ret z ;return if not found
1922 ;merge the disk map at info with that at buff(dptr)
1923 D8BF 01 0010 ld bc,dskmap
1924 D8C2 CD D55E call getdptra
1925 D8C5 09 add hl,bc
1926 D8C6 EB ex de,hl ;DE is .buff(dptr+16)
1927 D8C7 2A D343 ld hl,(info)
1928 D8CA 09 add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16)
1929 D8CB 0E 10 ld c,fcblen-dskmap;length of single byte dm
1930 D8CD 3A DDDD merge0: ld a,(single)
1931 D8D0 B7 or a
1932 D8D1 CA D8E8 jp z,merged ;skip to double
1933 ;this is a single byte map
1934 ;if fcb(i) = 0 then fcb(i) = buff(i)
1935 ;if buff(i) = 0 then buff(i) = fcb(i)
1936 ;if fcb(i) <> buff(i) then error
1937 D8D4 7E ld a,(hl)
1938 D8D5 B7 or a
1939 D8D6 1A ld a,(de)
1940 D8D7 C2 D8DB jp nz,fcbnzero
1941 ;fcb(i) = 0
1942 D8DA 77 ld (hl),a ;fcb(i) = buff(i)
1943 D8DB fcbnzero:
1944 D8DB B7 or a
1945 D8DC C2 D8E1 jp nz,buffnzero
1946 ;buff(i) = 0
1947 D8DF 7E ld a,(hl)
1948'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-33
1949
1950
1951 D8E0 12 ld (de),a ;buff(i)=fcb(i)
1952 D8E1 buffnzero:
1953 D8E1 BE cp (hl)
1954 D8E2 C2 D91F jp nz,mergerr ;fcb(i) = buff(i)?
1955 D8E5 C3 D8FD jp dmset ;if merge ok
1956
1957 D8E8 merged: ;this is a double byte merge operation
1958 D8E8 CD D894 call mergezero ;buff = fcb if buff 0000
1959 D8EB EB ex de,hl
1960 D8EC CD D894 call mergezero
1961 D8EF EB ex de,hl ;fcb = buff if fcb 0000
1962 ;they should be identical at this point
1963 D8F0 1A ld a,(de)
1964 D8F1 BE cp (hl)
1965 D8F2 C2 D91F jp nz,mergerr ;low same?
1966 D8F5 13 inc de
1967 D8F6 23 inc hl ;to high byte
1968 D8F7 1A ld a,(de)
1969 D8F8 BE cp (hl)
1970 D8F9 C2 D91F jp nz,mergerr ;high same?
1971 ;merge operation ok for this pair
1972 D8FC 0D dec c ;extra count for double byte
1973 D8FD 13 dmset: inc de
1974 D8FE 23 inc hl ;to next byte position
1975 D8FF 0D dec c
1976 D900 C2 D8CD jp nz,merge0 ;for more
1977 ;end of disk map merge, check record count
1978 ;DE = .buff(dptr)+32, HL = .fcb(32)
1979 D903 01 FFEC ld bc,-(fcblen-extnum)
1980 D906 09 add hl,bc
1981 D907 EB ex de,hl
1982 D908 09 add hl,bc
1983 ;DE = .fcb(extnum), HL = .buff(dptr+extnum)
1984 D909 1A ld a,(de) ;current user extent number
1985 ;if fcb(ext) >= buff(fcb) then
1986 ;buff(ext) := fcb(ext), buff(rec) := fcb(rec)
1987 D90A BE cp (hl)
1988 D90B DA D917 jp c,endmerge
1989 ;fcb extent number >= dir extent number
1990 D90E 77 ld (hl),a ;buff(ext) = fcb(ext)
1991 ;update directory record count field
1992 D90F 01 0003 ld bc,reccnt-extnum
1993 D912 09 add hl,bc
1994 D913 EB ex de,hl
1995 D914 09 add hl,bc
1996 ;DE=.buff(reccnt), HL=.fcb(reccnt)
1997 D915 7E ld a,(hl)
1998 D916 12 ld (de),a ;buff(reccnt)=fcb(reccnt)
1999 D917 endmerge:
2000 D917 3E FF ld a,true
2001 D919 32 DDD2 ld (fcb$copied),a ;mark as copied
2002 D91C C3 D810 jp seek$copy ;ok to "wrdir" here - 1.4 compat
2003 ; ret
2004
2005 D91F mergerr: ;elements did not merge correctly
2006 D91F 21 D345 ld hl,lret
2007'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-34
2008
2009
2010 D922 35 dec (hl) ;=255 non zero flag set
2011 D923 C9 ret
2012
2013 D924 make: ;create a new file by creating a directory entry
2014 ;then opening the file
2015 D924 CD D554 call check$write ;may be write protected
2016 D927 2A D343 ld hl,(info)
2017 D92A E5 push hl ;save fcb address, look for e5
2018 D92B 21 DDAC ld hl,efcb
2019 D92E 22 D343 ld (info),hl ;info = .empty
2020 D931 0E 01 ld c,1
2021 D933 CD D718 call search ;length 1 match on empty entry
2022 D936 CD D5F5 call end$of$dir ;zero flag set if no space
2023 D939 E1 pop hl ;recall info address
2024 D93A 22 D343 ld (info),hl ;in case we return here
2025 D93D C8 ret z ;return with error condition 255 if not found
2026 D93E EB ex de,hl ;DE = info address
2027 ;clear the remainder of the fcb
2028 D93F 21 000F ld hl,namlen
2029 D942 19 add hl,de ;HL=.fcb(namlen)
2030 D943 0E 11 ld c,fcblen-namlen ;number of bytes to fill
2031 D945 AF xor a ;clear accumulator to 00 for fill
2032 D946 77 make0: ld (hl),a
2033 D947 23 inc hl
2034 D948 0D dec c
2035 D949 C2 D946 jp nz,make0
2036 D94C 21 000D ld hl,ubytes
2037 D94F 19 add hl,de ;HL = .fcb(ubytes)
2038 D950 77 ld (hl),a ;fcb(ubytes) = 0
2039 D951 CD D58C call setcdr ;may have extended the directory
2040 ;now copy entry to the directory
2041 D954 CD D7FD call copy$fcb
2042 ;and set the file write flag to "1"
2043 D957 C3 D578 jp setfwf
2044 ; ret
2045
2046 D95A open$reel: ;close the current extent, and open the next one
2047 ;if possible. RMF is true if in read mode
2048 D95A AF xor a
2049 D95B 32 DDD2 ld (fcb$copied),a ;set true if actually copied
2050 D95E CD D8A2 call close ;close current extent
2051 ;lret remains at enddir if we cannot open the next ext
2052 D961 CD D5F5 call end$of$dir
2053 D964 C8 ret z ;return if end
2054 ;increment extent number
2055 D965 2A D343 ld hl,(info)
2056 D968 01 000C ld bc,extnum
2057 D96B 09 add hl,bc ;HL=.fcb(extnum)
2058 D96C 7E ld a,(hl)
2059 D96D 3C inc a
2060 D96E E6 1F and maxext
2061 D970 77 ld (hl),a ;fcb(extnum)=++1
2062 D971 CA D983 jp z,open$mod ;move to next module if zero
2063 ;may be in the same extent group
2064 D974 47 ld b,a
2065 D975 3A DDC5 ld a,(extmsk)
2066'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-35
2067
2068
2069 D978 A0 and b
2070 ;if result is zero, then not in the same group
2071 D979 21 DDD2 ld hl,fcb$copied ;true if the fcb was copied to directory
2072 D97C A6 and (hl) ;produces a 00 in accumulator if not written
2073 D97D CA D98E jp z,open$reel0 ;go to next physical extent
2074 ;result is non zero, so we must be in same logical ext
2075 D980 C3 D9AC jp open$reel1 ;to copy fcb information
2076 D983 open$mod: ;extent number overflow, go to next module
2077 D983 01 0002 ld bc,modnum-extnum
2078 D986 09 add hl,bc ;HL=.fcb(modnum)
2079 D987 34 inc (hl) ;fcb(modnum)=++1
2080 ;module number incremented, check for overflow
2081 D988 7E ld a,(hl)
2082 D989 E6 0F and maxmod ;mask high order bits
2083 D98B CA D9B6 jp z,open$r$err ;cannot overflow to zero
2084 ;otherwise, ok to continue with new module
2085 D98E open$reel0:
2086 D98E 0E 0F ld c,namlen
2087 D990 CD D718 call search ;next extent found?
2088 D993 CD D5F5 call end$of$dir
2089 D996 C2 D9AC jp nz,open$reel1
2090 ;end of file encountered
2091 D999 3A DDD3 ld a,(rmf)
2092 D99C 3C inc a ;0ffh becomes 00 if read
2093 D99D CA D9B6 jp z,open$r$err ;sets lret = 1
2094 ;try to extend the current file
2095 D9A0 CD D924 call make
2096 ;cannot be end of directory
2097 D9A3 CD D5F5 call end$of$dir
2098 D9A6 CA D9B6 jp z,open$r$err ;with lret = 1
2099 D9A9 C3 D9AF jp open$reel2
2100
2101 D9AC open$reel1: ;not end of file, open
2102 D9AC CD D85A call open$copy
2103 D9AF open$reel2:
2104 D9AF CD D4BB call getfcb ;set parameters
2105 D9B2 AF xor a
2106 D9B3 C3 D301 jp sta$ret ;lret = 0
2107 ; ret ;with lret = 0
2108
2109 D9B6 open$r$err: ;cannot move to next extent of this file
2110 D9B6 CD D305 call setlret1 ;lret = 1
2111 D9B9 C3 D578 jp setfwf ;ensure that it will not be closed
2112 ; ret
2113
2114 D9BC seqdiskread: ;sequential disk read operation
2115 D9BC 3E 01 ld a,1
2116 D9BE 32 DDD5 ld (seqio),a
2117 ;drop through to diskread
2118
2119 D9C1 diskread: ;(may enter from seqdiskread)
2120 D9C1 3E FF ld a,true
2121 D9C3 32 DDD3 ld (rmf),a ;read mode flag = true (open$reel)
2122 ;read the next record from the current fcb
2123 D9C6 CD D4BB call getfcb ;sets parameters for the read
2124 D9C9 3A DDE3 ld a,(vrecord)
2125'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-36
2126
2127
2128 D9CC 21 DDE1 ld hl,rcount
2129 D9CF BE cp (hl) ;vrecord-rcount
2130 ;skip if rcount > vrecord
2131 D9D0 DA D9E6 jp c,recordok
2132 ;not enough records in the extent
2133 ;record count must be 128 to continue
2134 D9D3 FE 80 cp 128 ;vrecord = 128?
2135 D9D5 C2 D9FB jp nz,diskeof ;skip if vrecord<>128
2136 D9D8 CD D95A call open$reel ;go to next extent if so
2137 D9DB AF xor a
2138 D9DC 32 DDE3 ld (vrecord),a ;vrecord=00
2139 ;now check for open ok
2140 D9DF 3A D345 ld a,(lret)
2141 D9E2 B7 or a
2142 D9E3 C2 D9FB jp nz,diskeof ;stop at eof
2143 D9E6 recordok: ;arrive with fcb addressing a record to read
2144 D9E6 CD D477 call index
2145 ;error 2 if reading unwritten data
2146 ;(returns 1 to be compatible with 1.4)
2147 D9E9 CD D484 call allocated ;arecord=0000?
2148 D9EC CA D9FB jp z,diskeof
2149 ;record has been allocated, read it
2150 D9EF CD D48A call atran ;arecord now a disk address
2151 D9F2 CD D3D1 call seek ;to proper track,sector
2152 D9F5 CD D3B2 call rdbuff ;to dma address
2153 D9F8 C3 D4D2 jp setfcb ;replace parameter
2154 ; ret
2155
2156 D9FB diskeof:
2157 D9FB C3 D305 jp setlret1 ;lret = 1
2158 ; ret
2159
2160 D9FE seqdiskwrite: ;sequential disk write
2161 D9FE 3E 01 ld a,1
2162 DA00 32 DDD5 ld (seqio),a
2163 ;drop through to diskwrite
2164
2165 DA03 diskwrite: ;(may enter here from seqdiskwrite above)
2166 DA03 3E 00 ld a,false
2167 DA05 32 DDD3 ld (rmf),a ;read mode flag
2168 ;write record to currently selected file
2169 DA08 CD D554 call check$write ;in case write protected
2170 DA0B 2A D343 ld hl,(info) ;HL = .fcb(0)
2171 DA0E CD D547 call check$rofile ;may be a read-only file
2172 DA11 CD D4BB call getfcb ;to set local parameters
2173 DA14 3A DDE3 ld a,(vrecord)
2174 DA17 FE 80 cp lstrec+1 ;vrecord-128
2175 ;skip if vrecord > lstrec
2176 ;vrecord = 128, cannot open next extent
2177 DA19 D2 D305 jp nc,setlret1 ;lret=1
2178 DA1C diskwr0: ;can write the next record, so continue
2179 DA1C CD D477 call index
2180 DA1F CD D484 call allocated
2181 DA22 0E 00 ld c,0 ;marked as normal write operation for wrbuff
2182 DA24 C2 DA6E jp nz,diskwr1
2183 ;not allocated
2184'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-37
2185
2186
2187 ;the argument to getblock is the starting
2188 ;position for the disk search, and should be
2189 ;the last allocated block for this file, or
2190 ;the value 0 if no space has been allocated
2191 DA27 CD D43E call dm$position
2192 DA2A 32 DDD7 ld (dminx),a ;save for later
2193 DA2D 01 0000 ld bc,0000h ;may use block zero
2194 DA30 B7 or a
2195 DA31 CA DA3B jp z,nopblock ;skip if no previous block
2196 ;previous block exists at A
2197 DA34 4F ld c,a
2198 DA35 0B dec bc ;previous block # in BC
2199 DA36 CD D45E call getdm ;previous block # to HL
2200 DA39 44 ld b,h
2201 DA3A 4D ld c,l ;BC=prev block#
2202 DA3B nopblock: ;BC = 0000, or previous block #
2203 DA3B CD D7BE call get$block ;block # to HL
2204 ;arrive here with block# or zero
2205 DA3E 7D ld a,l
2206 DA3F B4 or h
2207 DA40 C2 DA48 jp nz,blockok
2208 ;cannot find a block to allocate
2209 DA43 3E 02 ld a,2
2210 DA45 C3 D301 jp sta$ret ;lret=2
2211
2212 DA48 blockok: ;allocated block number is in HL
2213 DA48 22 DDE5 ld (arecord),hl
2214 DA4B EB ex de,hl ;block number to DE
2215 DA4C 2A D343 ld hl,(info)
2216 DA4F 01 0010 ld bc,dskmap
2217 DA52 09 add hl,bc ;HL=.fcb(dskmap)
2218 DA53 3A DDDD ld a,(single)
2219 DA56 B7 or a ;set flags for single byte dm
2220 DA57 3A DDD7 ld a,(dminx) ;recall dm index
2221 DA5A CA DA64 jp z,allocwd ;skip if allocating word
2222 ;allocating a byte value
2223 DA5D CD D564 call addh
2224 DA60 73 ld (hl),e ;single byte alloc
2225 DA61 C3 DA6C jp diskwru ;to continue
2226
2227 DA64 allocwd: ;allocate a word value
2228 DA64 4F ld c,a
2229 DA65 06 00 ld b,0 ;double(dminx)
2230 DA67 09 add hl,bc
2231 DA68 09 add hl,bc ;HL=.fcb(dminx*2)
2232 DA69 73 ld (hl),e
2233 DA6A 23 inc hl
2234 DA6B 72 ld (hl),d ;double wd
2235 DA6C diskwru: ;disk write to previously unallocated block
2236 DA6C 0E 02 ld c,2 ;marked as unallocated write
2237 DA6E diskwr1: ;continue the write operation of no allocation error
2238 ;C = 0 if normal write, 2 if to prev unalloc block
2239 DA6E 3A D345 ld a,(lret)
2240 DA71 B7 or a
2241 DA72 C0 ret nz ;stop if non zero returned value
2242 DA73 C5 push bc ;save write flag
2243'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-38
2244
2245
2246 DA74 CD D48A call atran ;arecord set
2247 DA77 3A DDD5 ld a,(seqio)
2248 DA7A 3D dec a
2249 DA7B 3D dec a
2250 DA7C C2 DABB jp nz,diskwr11
2251 DA7F C1 pop bc
2252 DA80 C5 push bc
2253 DA81 79 ld a,c
2254 DA82 3D dec a
2255 DA83 3D dec a
2256 DA84 C2 DABB jp nz,diskwr11 ;old allocation
2257 DA87 E5 push hl ;arecord in hl ret from atran
2258 DA88 2A DDB9 ld hl,(buffa)
2259 DA8B 57 ld d,a ;zero buffa & fill
2260 DA8C 77 fill0: ld (hl),a
2261 DA8D 23 inc hl
2262 DA8E 14 inc d
2263 DA8F F2 DA8C jp p,fill0
2264 DA92 CD D5E0 call setdir
2265 DA95 2A DDE7 ld hl,(arecord1)
2266 DA98 0E 02 ld c,2
2267 DA9A 22 DDE5 fill1: ld (arecord),hl
2268 DA9D C5 push bc
2269 DA9E CD D3D1 call seek
2270 DAA1 C1 pop bc
2271 DAA2 CD D3B8 call wrbuff ;write fill record
2272 DAA5 2A DDE5 ld hl,(arecord) ;restore last record
2273 DAA8 0E 00 ld c,0 ;change allocate flag
2274 DAAA 3A DDC4 ld a,(blkmsk)
2275 DAAD 47 ld b,a
2276 DAAE A5 and l
2277 DAAF B8 cp b
2278 DAB0 23 inc hl
2279 DAB1 C2 DA9A jp nz,fill1 ;cont until cluster is zeroed
2280 DAB4 E1 pop hl
2281 DAB5 22 DDE5 ld (arecord),hl
2282 DAB8 CD D5DA call setdata
2283 DABB diskwr11:
2284 DABB CD D3D1 call seek ;to proper file position
2285 DABE C1 pop bc
2286 DABF C5 push bc ;restore/save write flag (C=2 if new block)
2287 DAC0 CD D3B8 call wrbuff ;written to disk
2288 DAC3 C1 pop bc ;C = 2 if a new block was allocated, 0 if not
2289 ;increment record count if rcount<=vrecord
2290 DAC4 3A DDE3 ld a,(vrecord)
2291 DAC7 21 DDE1 ld hl,rcount
2292 DACA BE cp (hl) ;vrecord-rcount
2293 DACB DA DAD2 jp c,diskwr2
2294 ;rcount <= vrecord
2295 DACE 77 ld (hl),a
2296 DACF 34 inc (hl) ;rcount = vrecord+1
2297 DAD0 0E 02 ld c,2 ;mark as record count incremented
2298 DAD2 diskwr2: ;A has vrecord, C=2 if new block or new record#
2299 DAD2 0D dec c
2300 DAD3 0D dec c
2301 DAD4 C2 DADF jp nz,noupdate
2302'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-39
2303
2304
2305 DAD7 F5 push af ;save vrecord value
2306 DAD8 CD D569 call getmodnum ;HL=.fcb(modnum), A=fcb(modnum)
2307 ;reset the file write flag to mark as written fcb
2308 DADB E6 7F and (not fwfmsk) and 0ffh;bit reset
2309 DADD 77 ld (hl),a ;fcb(modnum) = fcb(modnum) and 7fh
2310 DADE F1 pop af ;restore vrecord
2311 DADF noupdate: ;check for end of extent, if found attempt to open
2312 ;next extent in preparation for next write
2313 DADF FE 7F cp lstrec ;vrecord=lstrec?
2314 DAE1 C2 DB00 jp nz,diskwr3 ;skip if not
2315 ;may be random access write, if so we are done
2316 ;change next
2317 DAE4 3A DDD5 ld a,(seqio)
2318 DAE7 FE 01 cp 1
2319 DAE9 C2 DB00 jp nz,diskwr3 ;skip next extent open op
2320 ;update current fcb before going to next extent
2321 DAEC CD D4D2 call setfcb
2322 DAEF CD D95A call open$reel ;rmf=false
2323 ;vrecord remains at lstrec causing eof if
2324 ;no more directory space is available
2325 DAF2 21 D345 ld hl,lret
2326 DAF5 7E ld a,(hl)
2327 DAF6 B7 or a
2328 DAF7 C2 DAFE jp nz,nospace
2329 ;space available, set vrecord=255
2330 DAFA 3D dec a
2331 DAFB 32 DDE3 ld (vrecord),a ;goes to 00 next time
2332 DAFE nospace:
2333 DAFE 36 00 ld (hl),0 ;lret = 00 for returned value
2334 DB00 diskwr3:
2335 DB00 C3 D4D2 jp setfcb ;replace parameters
2336 ; ret
2337
2338 DB03 rseek: ;random access seek operation, C=0ffh if read mode
2339 ;fcb is assumed to address an active file control block
2340 ;(modnum has been set to 1100$0000b if previous bad seek)
2341 DB03 AF xor a
2342 DB04 32 DDD5 ld (seqio),a ;marked as random access operation
2343 DB07 C5 rseek1: push bc ;save r/w flag
2344 DB08 2A D343 ld hl,(info)
2345 DB0B EB ex de,hl ;DE will hold base of fcb
2346 DB0C 21 0021 ld hl,ranrec
2347 DB0F 19 add hl,de ;HL=.fcb(ranrec)
2348 DB10 7E ld a,(hl)
2349 DB11 E6 7F and 7fh
2350 DB13 F5 push af ;record number
2351 DB14 7E ld a,(hl)
2352 DB15 17 rla ;cy=lsb of extent#
2353 DB16 23 inc hl
2354 DB17 7E ld a,(hl)
2355 DB18 17 rla
2356 DB19 E6 1F and 11111b ;A=ext#
2357 DB1B 4F ld c,a ;C holds extent number, record stacked
2358 DB1C 7E ld a,(hl)
2359 DB1D 1F rra
2360 DB1E 1F rra
2361'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-40
2362
2363
2364 DB1F 1F rra
2365 DB20 1F rra
2366 DB21 E6 0F and 1111b ;mod#
2367 DB23 47 ld b,a ;B holds module#, C holds ext#
2368 DB24 F1 pop af ;recall sought record #
2369 ;check to insure that high byte of ran rec = 00
2370 DB25 23 inc hl
2371 DB26 6E ld l,(hl) ;l=high byte (must be 00)
2372 DB27 2C inc l
2373 DB28 2D dec l
2374 DB29 2E 06 ld l,6 ;zero flag, l=6
2375 ;produce error 6, seek past physical eod
2376 DB2B C2 DB8B jp nz,seekerr
2377 ;otherwise, high byte = 0, A = sought record
2378 DB2E 21 0020 ld hl,nxtrec
2379 DB31 19 add hl,de ;HL = .fcb(nxtrec)
2380 DB32 77 ld (hl),a ;sought rec# stored away
2381 ;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored
2382 ;the r/w flag is still stacked. compare fcb values
2383 DB33 21 000C ld hl,extnum
2384 DB36 19 add hl,de
2385 DB37 79 ld a,c ;A=seek ext#
2386 DB38 96 sub (hl)
2387 DB39 C2 DB47 jp nz,ranclose ;tests for = extents
2388 ;extents match, check mod#
2389 DB3C 21 000E ld hl,modnum
2390 DB3F 19 add hl,de
2391 DB40 78 ld a,b ;B=seek mod#
2392 ;could be overflow at eof, producing module#
2393 ;of 90H or 10H, so compare all but fwf
2394 DB41 96 sub (hl)
2395 DB42 E6 7F and 7fh
2396 DB44 CA DB7F jp z,seekok ;same?
2397 DB47 ranclose:
2398 DB47 C5 push bc
2399 DB48 D5 push de ;save seek mod#,ext#, .fcb
2400 DB49 CD D8A2 call close ;current extent closed
2401 DB4C D1 pop de
2402 DB4D C1 pop bc ;recall parameters and fill
2403 DB4E 2E 03 ld l,3 ;cannot close error #3
2404 DB50 3A D345 ld a,(lret)
2405 DB53 3C inc a
2406 DB54 CA DB84 jp z,badseek
2407 DB57 21 000C ld hl,extnum
2408 DB5A 19 add hl,de
2409 DB5B 71 ld (hl),c ;fcb(extnum)=ext#
2410 DB5C 21 000E ld hl,modnum
2411 DB5F 19 add hl,de
2412 DB60 70 ld (hl),b ;fcb(modnum)=mod#
2413 DB61 CD D851 call open ;is the file present?
2414 DB64 3A D345 ld a,(lret)
2415 DB67 3C inc a
2416 DB68 C2 DB7F jp nz,seekok ;open successful?
2417 ;cannot open the file, read mode?
2418 DB6B C1 pop bc ;r/w flag to c (=0ffh if read)
2419 DB6C C5 push bc ;everyone expects this item stacked
2420'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-41
2421
2422
2423 DB6D 2E 04 ld l,4 ;seek to unwritten extent #4
2424 DB6F 0C inc c ;becomes 00 if read operation
2425 DB70 CA DB84 jp z,badseek ;skip to error if read operation
2426 ;write operation, make new extent
2427 DB73 CD D924 call make
2428 DB76 2E 05 ld l,5 ;cannot create new extent #5
2429 DB78 3A D345 ld a,(lret)
2430 DB7B 3C inc a
2431 DB7C CA DB84 jp z,badseek ;no dir space
2432 ;file make operation successful
2433 DB7F seekok:
2434 DB7F C1 pop bc ;discard r/w flag
2435 DB80 AF xor a
2436 DB81 C3 D301 jp sta$ret ;with zero set
2437 DB84 badseek: ;fcb no longer contains a valid fcb, mark
2438 ;with 1100$000b in modnum field so that it
2439 ;appears as overflow with file write flag set
2440 DB84 E5 push hl ;save error flag
2441 DB85 CD D569 call getmodnum ;HL = .modnum
2442 DB88 36 C0 ld (hl),11000000b
2443 DB8A E1 pop hl ;and drop through
2444 DB8B seekerr:
2445 DB8B C1 pop bc ;discard r/w flag
2446 DB8C 7D ld a,l
2447 DB8D 32 D345 ld (lret),a ;lret=#, nonzero
2448 ;setfwf returns non-zero accumulator for err
2449 DB90 C3 D578 jp setfwf ;flag set, so subsequent close ok
2450 ; ret
2451
2452 DB93 randiskread: ;random disk read operation
2453 DB93 0E FF ld c,true ;marked as read operation
2454 DB95 CD DB03 call rseek
2455 DB98 CC D9C1 call z,diskread ;if seek successful
2456 DB9B C9 ret
2457
2458 DB9C randiskwrite: ;random disk write operation
2459 DB9C 0E 00 ld c,false ;marked as write operation
2460 DB9E CD DB03 call rseek
2461 DBA1 CC DA03 call z,diskwrite ;if seek successful
2462 DBA4 C9 ret
2463
2464 DBA5 compute$rr: ;compute random record position for getfilesize/setrandom
2465 DBA5 EB ex de,hl
2466 DBA6 19 add hl,de
2467 ;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt)
2468 DBA7 4E ld c,(hl)
2469 DBA8 06 00 ld b,0 ;BC = 0000 0000 ?rrr rrrr
2470 DBAA 21 000C ld hl,extnum
2471 DBAD 19 add hl,de
2472 DBAE 7E ld a,(hl)
2473 DBAF 0F rrca
2474 DBB0 E6 80 and 80h ;A=e000 0000
2475 DBB2 81 add a,c
2476 DBB3 4F ld c,a
2477 DBB4 3E 00 ld a,0
2478 DBB6 88 adc a,b
2479'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-42
2480
2481
2482 DBB7 47 ld b,a
2483 ;BC = 0000 000? errrr rrrr
2484 DBB8 7E ld a,(hl)
2485 DBB9 0F rrca
2486 DBBA E6 0F and 0fh
2487 DBBC 80 add a,b
2488 DBBD 47 ld b,a
2489 ;BC = 000? eeee errrr rrrr
2490 DBBE 21 000E ld hl,modnum
2491 DBC1 19 add hl,de
2492 DBC2 7E ld a,(hl) ;A=XXX? mmmm
2493 DBC3 87 add a,a
2494 DBC4 87 add a,a
2495 DBC5 87 add a,a
2496 DBC6 87 add a,a ;cy=? A=mmmm 0000
2497 DBC7 F5 push af
2498 DBC8 80 add a,b
2499 DBC9 47 ld b,a
2500 ;cy=?, BC = mmmm eeee errr rrrr
2501 DBCA F5 push af ;possible second carry
2502 DBCB E1 pop hl ;cy = lsb of L
2503 DBCC 7D ld a,l ;cy = lsb of A
2504 DBCD E1 pop hl ;cy = lsb of L
2505 DBCE B5 or l ;cy/cy = lsb of A
2506 DBCF E6 01 and 1 ;A = 0000 000? possible carry-out
2507 DBD1 C9 ret
2508
2509 DBD2 getfilesize: ;compute logical file size for current fcb
2510 DBD2 0E 0C ld c,extnum
2511 DBD4 CD D718 call search
2512 ;zero the receiving ranrec field
2513 DBD7 2A D343 ld hl,(info)
2514 DBDA 11 0021 ld de,ranrec
2515 DBDD 19 add hl,de
2516 DBDE E5 push hl ;save position
2517 DBDF 72 ld (hl),d
2518 DBE0 23 inc hl
2519 DBE1 72 ld (hl),d
2520 DBE2 23 inc hl
2521 DBE3 72 ld (hl),d ;=00 00 00
2522 DBE4 getsize:
2523 DBE4 CD D5F5 call end$of$dir
2524 DBE7 CA DC0C jp z,setsize
2525 ;current fcb addressed by dptr
2526 DBEA CD D55E call getdptra
2527 DBED 11 000F ld de,reccnt ;ready for compute size
2528 DBF0 CD DBA5 call compute$rr
2529 ;A=0000 000? BC = mmmm eeee errr rrrr
2530 ;compare with memory, larger?
2531 DBF3 E1 pop hl
2532 DBF4 E5 push hl ;recall, replace .fcb(ranrec)
2533 DBF5 5F ld e,a ;save cy
2534 DBF6 79 ld a,c
2535 DBF7 96 sub (hl)
2536 DBF8 23 inc hl ;ls byte
2537 DBF9 78 ld a,b
2538'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-43
2539
2540
2541 DBFA 9E sbc a,(hl)
2542 DBFB 23 inc hl ;middle byte
2543 DBFC 7B ld a,e
2544 DBFD 9E sbc a,(hl) ;carry if .fcb(ranrec) > directory
2545 DBFE DA DC06 jp c,getnextsize ;for another try
2546 ;fcb is less or equal, fill from directory
2547 DC01 73 ld (hl),e
2548 DC02 2B dec hl
2549 DC03 70 ld (hl),b
2550 DC04 2B dec hl
2551 DC05 71 ld (hl),c
2552 DC06 getnextsize:
2553 DC06 CD D72D call searchn
2554 DC09 C3 DBE4 jp getsize
2555
2556 DC0C setsize:
2557 DC0C E1 pop hl ;discard .fcb(ranrec)
2558 DC0D C9 ret
2559
2560 DC0E setrandom: ;set random record from the current file control block
2561 DC0E 2A D343 ld hl,(info)
2562 DC11 11 0020 ld de,nxtrec ;ready params for computesize
2563 DC14 CD DBA5 call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr
2564 DC17 21 0021 ld hl,ranrec
2565 DC1A 19 add hl,de ;HL = .fcb(ranrec)
2566 DC1B 71 ld (hl),c
2567 DC1C 23 inc hl
2568 DC1D 70 ld (hl),b
2569 DC1E 23 inc hl
2570 DC1F 77 ld (hl),a ;to ranrec
2571 DC20 C9 ret
2572
2573 DC21 select: ;select disk info for subsequent input or output ops
2574 DC21 2A DDAF ld hl,(dlog)
2575 DC24 3A D342 ld a,(curdsk)
2576 DC27 4F ld c,a
2577 DC28 CD D4EA call hlrotr
2578 DC2B E5 push hl
2579 DC2C EB ex de,hl ;save it for test below, send to seldsk
2580 DC2D CD D359 call selectdisk
2581 DC30 E1 pop hl ;recall dlog vector
2582 DC31 CC D347 call z,sel$error ;returns true if select ok
2583 ;is the disk logged in?
2584 DC34 7D ld a,l
2585 DC35 1F rra
2586 DC36 D8 ret c ;return if bit is set
2587 ;disk not logged in, set bit and initialize
2588 DC37 2A DDAF ld hl,(dlog)
2589 DC3A 4D ld c,l
2590 DC3B 44 ld b,h ;call ready
2591 DC3C CD D50B call set$cdisk
2592 DC3F 22 DDAF ld (dlog),hl ;dlog=set$cdisk(dlog)
2593 DC42 C3 D6A3 jp initialize
2594 ; ret
2595
2596 DC45 curselect:
2597'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-44
2598
2599
2600 DC45 3A DDD6 ld a,(linfo)
2601 DC48 21 D342 ld hl,curdsk
2602 DC4B BE cp (hl)
2603 DC4C C8 ret z ;skip if linfo=curdsk
2604 DC4D 77 ld (hl),a ;curdsk=info
2605 DC4E C3 DC21 jp select
2606 ; ret
2607
2608 DC51 reselect: ;check current fcb to see if reselection necessary
2609 DC51 3E FF ld a,true
2610 DC53 32 DDDE ld (resel),a ;mark possible reselect
2611 DC56 2A D343 ld hl,(info)
2612 DC59 7E ld a,(hl) ;drive select code
2613 DC5A E6 1F and 11111b ;non zero is auto drive select
2614 DC5C 3D dec a ;drive code normalized to 0..30, or 255
2615 DC5D 32 DDD6 ld (linfo),a ;save drive code
2616 DC60 FE 1E cp 30
2617 DC62 D2 DC75 jp nc,noselect
2618 ;auto select function, save curdsk
2619 DC65 3A D342 ld a,(curdsk)
2620 DC68 32 DDDF ld (olddsk),a ;olddsk=curdsk
2621 DC6B 7E ld a,(hl)
2622 DC6C 32 DDE0 ld (fcbdsk),a ;save drive code
2623 DC6F E6 E0 and 11100000b
2624 DC71 77 ld (hl),a ;preserve hi bits
2625 DC72 CD DC45 call curselect
2626 DC75 noselect: ;set user code
2627 DC75 3A D341 ld a,(usrcode) ;0...31
2628 DC78 2A D343 ld hl,(info)
2629 DC7B B6 or (hl)
2630 DC7C 77 ld (hl),a
2631 DC7D C9 ret
2632
2633 ; individual function handlers
2634 DC7E func12: ;return version number
2635 DC7E 3E 22 ld a,dvers
2636 DC80 C3 D301 jp sta$ret ;lret = dvers (high = 00)
2637 ; ret
2638 ; jp goback
2639
2640 DC83 func13: ;reset disk system - initialize to disk 0
2641 DC83 21 0000 ld hl,0
2642 DC86 22 DDAD ld (rodsk),hl
2643 DC89 22 DDAF ld (dlog),hl
2644 DC8C AF xor a
2645 DC8D 32 D342 ld (curdsk),a ;note that usrcode remains unchanged
2646 DC90 21 0080 ld hl,tbuff
2647 DC93 22 DDB1 ld (dmaad),hl ;dmaad = tbuff
2648 DC96 CD D5DA call setdata ;to data dma address
2649 DC99 C3 DC21 jp select
2650 ; ret
2651 ; jp goback
2652
2653 DC45 func14 equ curselect ;select disk info
2654 ; ret
2655 ; jp goback
2656'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-45
2657
2658
2659
2660 DC9C func15: ;open file
2661 DC9C CD D572 call clrmodnum ;clear the module number
2662 DC9F CD DC51 call reselect
2663 DCA2 C3 D851 jp open
2664 ; ret
2665 ; jp goback
2666
2667 DCA5 func16: ;close file
2668 DCA5 CD DC51 call reselect
2669 DCA8 C3 D8A2 jp close
2670 ; ret
2671 ; jp goback
2672
2673 DCAB func17: ;search for first occurrence of a file
2674 DCAB 0E 00 ld c,0 ;length assuming '?' true
2675 DCAD EB ex de,hl ;was lhld info
2676 DCAE 7E ld a,(hl)
2677 DCAF FE 3F cp '?' ;no reselect if ?
2678 DCB1 CA DCC2 jp z,qselect ;skip reselect if so
2679 ;normal search
2680 DCB4 CD D4A6 call getexta
2681 DCB7 7E ld a,(hl)
2682 DCB8 FE 3F cp '?' ;
2683 DCBA C4 D572 call nz,clrmodnum ;module number zeroed
2684 DCBD CD DC51 call reselect
2685 DCC0 0E 0F ld c,namlen
2686 DCC2 qselect:
2687 DCC2 CD D718 call search
2688 DCC5 C3 D5E9 jp dir$to$user ;copy directory entry to user
2689 ; ret
2690 ; jp goback
2691
2692 DCC8 func18: ;search for next occurrence of a file name
2693 DCC8 2A DDD9 ld hl,(searcha)
2694 DCCB 22 D343 ld (info),hl
2695 DCCE CD DC51 call reselect
2696 DCD1 CD D72D call searchn
2697 DCD4 C3 D5E9 jp dir$to$user ;copy directory entry to user
2698 ; ret
2699 ; jp goback
2700
2701 DCD7 func19: ;delete a file
2702 DCD7 CD DC51 call reselect
2703 DCDA CD D79C call delete
2704 DCDD C3 D701 jp copy$dirloc
2705 ; ret
2706 ; jp goback
2707
2708 DCE0 func20: ;read a file
2709 DCE0 CD DC51 call reselect
2710 DCE3 C3 D9BC jp seqdiskread
2711 ; jp goback
2712
2713 DCE6 func21: ;write a file
2714 DCE6 CD DC51 call reselect
2715'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-46
2716
2717
2718 DCE9 C3 D9FE jp seqdiskwrite
2719 ; jp goback
2720
2721 DCEC func22: ;make a file
2722 DCEC CD D572 call clrmodnum
2723 DCEF CD DC51 call reselect
2724 DCF2 C3 D924 jp make
2725 ; ret
2726 ; jp goback
2727
2728 DCF5 func23: ;rename a file
2729 DCF5 CD DC51 call reselect
2730 DCF8 CD D816 call rename
2731 DCFB C3 D701 jp copy$dirloc
2732 ; ret
2733 ; jp goback
2734
2735 DCFE func24: ;return the login vector
2736 DCFE 2A DDAF ld hl,(dlog)
2737 DD01 C3 DD29 jp sthl$ret
2738 ; ret
2739 ; jp goback
2740
2741 DD04 func25: ;return selected disk number
2742 DD04 3A D342 ld a,(curdsk)
2743 DD07 C3 D301 jp sta$ret
2744 ; ret
2745 ; jp goback
2746
2747 DD0A func26: ;set the subsequent dma address to info
2748 DD0A EB ex de,hl ;was lhld info
2749 DD0B 22 DDB1 ld (dmaad),hl ;dmaad = info
2750 DD0E C3 D5DA jp setdata ;to data dma address
2751 ; ret
2752 ; jp goback
2753
2754 DD11 func27: ;return the login vector address
2755 DD11 2A DDBF ld hl,(alloca)
2756 DD14 C3 DD29 jp sthl$ret
2757 ; ret
2758 ; jp goback
2759
2760 D52C func28 equ set$ro
2761 ;write protect current disk
2762 ; ret
2763 ; jp goback
2764
2765 DD17 func29: ;return r/o bit vector
2766 DD17 2A DDAD ld hl,(rodsk)
2767 DD1A C3 DD29 jp sthl$ret
2768 ; ret
2769 ; jp goback
2770
2771 DD1D func30: ;set file indicators
2772 DD1D CD DC51 call reselect
2773 DD20 CD D83B call indicators
2774'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-47
2775
2776
2777 DD23 C3 D701 jp copy$dirloc ;lret=dirloc
2778 ; ret
2779 ; jp goback
2780
2781 DD26 func31: ;return address of disk parameter block
2782 DD26 2A DDBB ld hl,(dpbaddr)
2783 DD29 sthl$ret:
2784 DD29 22 D345 ld (aret),hl
2785 DD2C C9 ret
2786 ; jp goback
2787
2788 DD2D func32: ;set user code
2789 DD2D 3A DDD6 ld a,(linfo)
2790 DD30 FE FF cp 0ffh
2791 DD32 C2 DD3B jp nz,setusrcode
2792 ;interrogate user code instead
2793 DD35 3A D341 ld a,(usrcode)
2794 DD38 C3 D301 jp sta$ret ;lret=usrcode
2795 ; ret
2796 ; jp goback
2797
2798 DD3B setusrcode:
2799 DD3B E6 1F and 1fh
2800 DD3D 32 D341 ld (usrcode),a
2801 DD40 C9 ret
2802 ; jp goback
2803
2804 DD41 func33: ;random disk read operation
2805 DD41 CD DC51 call reselect
2806 DD44 C3 DB93 jp randiskread ;to perform the disk read
2807 ; ret
2808 ; jp goback
2809
2810 DD47 func34: ;random disk write operation
2811 DD47 CD DC51 call reselect
2812 DD4A C3 DB9C jp randiskwrite ;to perform the disk write
2813 ; ret
2814 ; jp goback
2815
2816 DD4D func35: ;return file size (0-65536)
2817 DD4D CD DC51 call reselect
2818 DD50 C3 DBD2 jp getfilesize
2819 ; ret
2820 ; jp goback
2821
2822 DC0E func36 equ setrandom ;set random record
2823 ; ret
2824 ; jp goback
2825
2826 DD53 2A D343 func37: ld hl,(info)
2827 DD56 7D ld a,l
2828 DD57 2F cpl
2829 DD58 5F ld e,a
2830 DD59 7C ld a,h
2831 DD5A 2F cpl
2832 DD5B 2A DDAF ld hl,(dlog)
2833'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-48
2834
2835
2836 DD5E A4 and h
2837 DD5F 57 ld d,a
2838 DD60 7D ld a,l
2839 DD61 A3 and e
2840 DD62 5F ld e,a
2841 DD63 2A DDAD ld hl,(rodsk)
2842 DD66 EB ex de,hl
2843 DD67 22 DDAF ld (dlog),hl
2844 DD6A 7D ld a,l
2845 DD6B A3 and e
2846 DD6C 6F ld l,a
2847 DD6D 7C ld a,h
2848 DD6E A2 and d
2849 DD6F 67 ld h,a
2850 DD70 22 DDAD ld (rodsk),hl
2851 DD73 C9 ret
2852
2853 DD74 goback: ;arrive here at end of processing to return to user
2854 DD74 3A DDDE ld a,(resel)
2855 DD77 B7 or a
2856 DD78 CA DD91 jp z,retmon
2857 ;reselection may have taken place
2858 DD7B 2A D343 ld hl,(info)
2859 DD7E 36 00 ld (hl),0 ;fcb(0)=0
2860 DD80 3A DDE0 ld a,(fcbdsk)
2861 DD83 B7 or a
2862 DD84 CA DD91 jp z,retmon
2863 ;restore disk number
2864 DD87 77 ld (hl),a ;fcb(0)=fcbdsk
2865 DD88 3A DDDF ld a,(olddsk)
2866 DD8B 32 DDD6 ld (linfo),a
2867 DD8E CD DC45 call curselect
2868
2869 ; return from the disk monitor
2870 DD91 2A D30F retmon: ld hl,(entsp)
2871 DD94 F9 ld sp,hl ;user stack restored
2872 DD95 2A D345 ld hl,(aret)
2873 DD98 7D ld a,l
2874 DD99 44 ld b,h ;BA = HL = aret
2875 DD9A C9 ret
2876
2877 D304 func38 equ func$ret
2878 D304 func39 equ func$ret
2879 DD9B func40: ;random disk write with zero fill of unallocated block
2880 DD9B CD DC51 call reselect
2881 DD9E 3E 02 ld a,2
2882 DDA0 32 DDD5 ld (seqio),a
2883 DDA3 0E 00 ld c,false
2884 DDA5 CD DB07 call rseek1
2885 DDA8 CC DA03 call z,diskwrite ;if seek successful
2886 DDAB C9 ret
2887
2888 ; data areas
2889
2890 ; initialized data
2891 DDAC E5 efcb: db empty ;0e5=available dir entry
2892'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-49
2893
2894
2895 DDAD 0000 rodsk: dw 0 ;read only disk vector
2896 DDAF 0000 dlog: dw 0 ;logged-in disks
2897 DDB1 0080 dmaad: dw tbuff ;initial dma address
2898
2899 ; curtrka - alloca are set upon disk select
2900 ; (data must be adjacent, do not insert variables)
2901 ; (address of translate vector, not used)
2902 DDB3 cdrmaxa:
2903 DDB3 ds word ;pointer to cur dir max value
2904 DDB5 curtrka:
2905 DDB5 ds word ;current track address
2906 DDB7 curreca:
2907 DDB7 ds word ;current record address
2908 DDB9 buffa: ds word ;pointer to directory dma address
2909 DDBB dpbaddr:
2910 DDBB ds word ;current disk parameter block address
2911 DDBD checka: ds word ;current checksum vector address
2912 DDBF alloca: ds word ;current allocation vector address
2913 0008 addlist equ $-buffa ;address list size
2914
2915 ; sectpt - offset obtained from disk parm block at dpbaddr
2916 ; (data must be adjacent, do not insert variables)
2917 DDC1 sectpt: ds word ;sectors per track
2918 DDC3 blkshf: ds byte ;block shift factor
2919 DDC4 blkmsk: ds byte ;block mask
2920 DDC5 extmsk: ds byte ;extent mask
2921 DDC6 maxall: ds word ;maximum allocation number
2922 DDC8 dirmax: ds word ;largest directory number
2923 DDCA dirblk: ds word ;reserved allocation bits for directory
2924 DDCC chksiz: ds word ;size of checksum vector
2925 DDCE offset: ds word ;offset tracks at beginning
2926 000F dpblist equ $-sectpt ;size of area
2927
2928 ; local variables
2929 DDD0 tranv: ds word ;address of translate vector
2930 DDD2 fcb$copied:
2931 DDD2 ds byte ;set true if copy$fcb called
2932 DDD3 rmf: ds byte ;read mode flag for open$reel
2933 DDD4 dirloc: ds byte ;directory flag in rename, etc.
2934 DDD5 seqio: ds byte ;1 if sequential i/o
2935 DDD6 linfo: ds byte ;low(info)
2936 DDD7 dminx: ds byte ;local for diskwrite
2937 DDD8 searchl:
2938 DDD8 ds byte ;search length
2939 DDD9 searcha:
2940 DDD9 ds word ;search address
2941 DDDB tinfo: ds word ;temp for info in "make"
2942 DDDD single: ds byte ;set true if single byte allocation map
2943 DDDE resel: ds byte ;reselection flag
2944 DDDF olddsk: ds byte ;disk on entry to bdos
2945 DDE0 fcbdsk: ds byte ;disk named in fcb
2946 DDE1 rcount: ds byte ;record count in current fcb
2947 DDE2 extval: ds byte ;extent number and extmsk
2948 DDE3 vrecord:
2949 DDE3 ds word ;current virtual record
2950 DDE5 arecord:
2951'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE 1-50
2952
2953
2954 DDE5 ds word ;current actual record
2955 DDE7 arecord1:
2956 DDE7 ds word ;current actual block# * blkmsk
2957
2958 ; local variables for directory access
2959 DDE9 dptr: ds byte ;directory pointer 0,1,2,3
2960 DDEA dcnt: ds word ;directory counter 0,1,...,dirmax
2961 DDEC drec: ds word ;directory record 0,1,...,dirmax/4
2962
2963 ;bios equ ($ and 0ff00h)+100h;next module
2964
2965 end
2966'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE S
2967
2968
2969Macros:
2970
2971Symbols:
2972D564 ADDH 0008 ADDLIST DDBF ALLOCA
2973D484 ALLOCATED DA64 ALLOCWD DDE5 ARECORD
2974DDE7 ARECORD1 D345 ARET D48A ATRAN
2975D490 ATRAN0 D299 BACKSP D1A4 BACKUP
2976D24E BACKX DB84 BADSEEK 0006 BDOSA
2977D011 BDOSE 0E00 BDOSLEN D000 BDOSPH
2978DE00 BIOS 2000 BIOSLEN DE00 BIOSPH
2979DDC4 BLKMSK DDC3 BLKSHF DA48 BLOCKOK
2980DE00 BOOTF DDB9 BUFFA D8E1 BUFFNZERO
29810001 BYTE 0800 CCPLEN C800 CCPPH
2982DDB3 CDRMAXA D544 CHECK$RODIR D547 CHECK$ROFILE
2983D554 CHECK$WRITE DDBD CHECKA D59E CHECKSUM
2984DDCC CHKSIZ D8A2 CLOSE D572 CLRMODNUM
2985D30C COLUMN D57F COMPCDR D30A COMPCOL
2986D707 COMPEXT D162 COMPOUT D4F7 COMPUTE$CS
2987DBA5 COMPUTE$RR D4FD COMPUTECS0 D142 CONB0
2988D145 CONB1 D123 CONBRK D106 CONECH
2989D0FB CONIN DE09 CONINF D148 CONOUT
2990DE0C CONOUTF DE06 CONSTF D801 COPY$DIR
2991D701 COPY$DIRLOC D7FD COPY$FCB 000E CPMLEN
2992000D CR D1C9 CRLF D1B1 CRLFP
2993D1B9 CRLFP0 005E CTL 0003 CTLC
29940005 CTLE 0008 CTLH D17F CTLOUT
29950010 CTLP 0012 CTLR 0013 CTLS
29960015 CTLU 0018 CTLX 001A CTLZ
2997D342 CURDSK DDB7 CURRECA DC45 CURSELECT
2998DDB5 CURTRKA DDEA DCNT D79C DELETE
2999D7A4 DELETE0 D3BB DIOCOMP D5E9 DIR$TO$USER
3000DDCA DIRBLK D2E0 DIRINP DDD4 DIRLOC
3001DDC8 DIRMAX 0004 DIRREC D9FB DISKEOF
3002000C DISKF D9C1 DISKREAD DA1C DISKWR0
3003DA6E DISKWR1 DABB DISKWR11 DAD2 DISKWR2
3004DB00 DISKWR3 DA03 DISKWRITE DA6C DISKWRU
3005DDAF DLOG D43E DM$POSITION DDB1 DMAAD
3006DDD7 DMINX D445 DMPOS0 D453 DMPOS1
3007D45C DMPOS2 D8FD DMSET DDBB DPBADDR
3008000F DPBLIST DDE9 DPTR DDEC DREC
3009D0C6 DSKERR 0010 DSKMAP D0BA DSKMSG
30100003 DSKMSK 0002 DSKSHF 0022 DVERS
3011D114 ECHOC DDAC EFCB 00E5 EMPTY
3012D5F5 END$OF$DIR FFFF ENDDIR D917 ENDMERGE
3013D783 ENDSEARCH D30F ENTSP D0E5 ERRFLG
3014DDC5 EXTMSK 000C EXTNUM DDE2 EXTVAL
30150000 FALSE DDD2 FCB$COPIED DDE0 FCBDSK
30160020 FCBLEN D8DB FCBNZERO 0005 FCBSHF
3017DA8C FILL0 DA9A FILL1 D304 FUNC$RET
3018D2C8 FUNC1 D1E1 FUNC10 D2FE FUNC11
3019DC7E FUNC12 DC83 FUNC13 DC45 FUNC14
3020DC9C FUNC15 DCA5 FUNC16 DCAB FUNC17
3021DCC8 FUNC18 DCD7 FUNC19 D190 FUNC2
3022DCE0 FUNC20 DCE6 FUNC21 DCEC FUNC22
3023DCF5 FUNC23 DCFE FUNC24 DD04 FUNC25
3024'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE S-1
3025
3026
3027DD0A FUNC26 DD11 FUNC27 D52C FUNC28
3028DD17 FUNC29 D2CE FUNC3 DD1D FUNC30
3029DD26 FUNC31 DD2D FUNC32 DD41 FUNC33
3030DD47 FUNC34 DD4D FUNC35 DC0E FUNC36
3031DD53 FUNC37 D304 FUNC38 D304 FUNC39
3032DD9B FUNC40 D2D4 FUNC6 D2ED FUNC7
3033D2F3 FUNC8 D2F8 FUNC9 D047 FUNCTAB
30340080 FWFMSK D7BE GET$BLOCK D635 GETALLOCBIT
3035D45E GETDM D471 GETDMD D55E GETDPTRA
3036D4A6 GETEXTA D4BB GETFCB D4AE GETFCBA
3037DBD2 GETFILESIZE D569 GETMODNUM DC06 GETNEXTSIZE
3038DBE4 GETSIZE DD74 GOBACK D34A GOERR
3039D504 HLROTL D505 HLROTL0 D4EA HLROTR
3040D4EB HLROTR0 D3A1 HOME DE18 HOMEF
3041D477 INDEX D840 INDIC0 D83B INDICATORS
3042D343 INFO D5C4 INITIAL$CS D6B1 INITIAL0
3043D6D2 INITIAL2 D6A3 INITIALIZE 000A INVIS
30440003 IOLOC D30E KBCHAR D7C0 LEFTTST
3045000A LF D270 LINELEN DDD6 LINFO
3046D30D LISTCP DE0F LISTF DE2D LISTSTF
3047D345 LRET D341 LSTACK 001F LSTFCB
3048007F LSTREC D924 MAKE D946 MAKE0
3049DDC6 MAXALL 001F MAXEXT 000F MAXMOD
3050D8CD MERGE0 D8E8 MERGED D91F MERGERR
3051D894 MERGEZERO 000E MODNUM D34F MOVE
3052D350 MOVE0 0040 MSIZE 000F NAMLEN
30530000 NEEDZ80 D59C NEWCHECKSUM 0029 NFUNCS
30540002 NHDISKS DA3B NOPBLOCK DC75 NOSELECT
3055DAFE NOSPACE D179 NOTBACKSP D2BD NOTC
3056D237 NOTE D216 NOTH D248 NOTP
3057D2A6 NOTR D226 NOTRUB D26B NOTU
3058D25F NOTX DADF NOUPDATE D51E NOWRITE
30590020 NXTREC DDCE OFFSET DDDF OLDDSK
3060D851 OPEN D85A OPEN$COPY D983 OPEN$MOD
3061D9B6 OPEN$R$ERR D88B OPEN$RCNT D95A OPEN$REEL
3062D98E OPEN$REEL0 D9AC OPEN$REEL1 D9AF OPEN$REEL2
30630001 PATCHOS D1AC PCTLH D6F6 PDOLLAR
3064D009 PERERR D0CA PERMSG D099 PERSUB
3065D1D3 PRINT DE12 PUNCHF DCC2 QSELECT
3066DB47 RANCLOSE DB93 RANDISKREAD DB9C RANDISKWRITE
30670021 RANREC DDE1 RCOUNT D5D4 RD$DIR
3068D3B2 RDBUFF D2A9 RDECH1 D2A6 RDECHO
3069D1E1 READ D605 READ$DIR D619 READ$DIR0
3070D620 READ$DIR1 D2C1 READEN DE15 READERF
3071DE27 READF D1F1 READN0 D1EF READNX
30720000 REBOOT 000F RECCNT D9E6 RECORDOK
30730080 RECSIZ D816 RENAME D827 RENAME0
3074D278 REP0 D28A REP1 DDDE RESEL
3075DC51 RESELECT D7EC RETBLOCK D7F4 RETBLOCK0
3076DD91 RETMON D39D RETSELECT D7D1 RIGHTTST
3077DDD3 RMF D00D RODERR D0E1 RODMSG
3078DDAD RODSK D0AB RODSUB D00F ROFERR
30790009 ROFILE D0DC ROFMSG D0B1 ROFSUB
3080D656 ROTL D664 ROTR DB03 RSEEK
3081DB07 RSEEK1 007F RUBOUT D66B SCANDM
3082D675 SCANDM0 D688 SCANDM1 D68E SCANDM2
3083'Bdos Interface, Bdos, Version 2.2 Feb, 1980' MACRO-80 3.44 09-Dec-81 PAGE S-2
3084
3085
3086D69D SCANM3 D718 SEARCH D794 SEARCH$FIN
3087DDD9 SEARCHA D773 SEARCHEXT DDD8 SEARCHL
3088D753 SEARCHLOOP D72D SEARCHN D74A SEARCHNEXT
3089D77C SEARCHOK DDC1 SECTPT DE30 SECTRAN
3090D3D1 SEEK D810 SEEK$COPY D3C3 SEEK$DIR
3091D3E4 SEEK0 D3FA SEEK1 D40F SEEK2
3092DB8B SEEKERR DB7F SEEKOK D347 SEL$ERROR
3093DE1B SELDSKF DC21 SELECT D359 SELECTDISK
3094D00B SELERR D0D5 SELMSG D0A5 SELSUB
3095D9BC SEQDISKREAD D9FE SEQDISKWRITE DDD5 SEQIO
3096D65C SET$ALLOC$BIT D50B SET$CDISK D5FE SET$END$DIR
3097D52C SET$RO D58C SETCDR D5DA SETDATA
3098D5E0 SETDIR D5E3 SETDMA DE24 SETDMAF
3099D4D2 SETFCB D4DE SETFCB1 D578 SETFWF
3100D305 SETLRET1 DC0E SETRANDOM DE21 SETSECF
3101DC0C SETSIZE DE1E SETTRKF DD3B SETUSRCODE
3102DDDD SINGLE 0018 SSIZE D301 STA$RET
3103DD29 STHL$RET D30B STRTCOL D595 SUBDH
31040009 TAB D196 TAB0 D190 TABOUT
31050080 TBUFF 005C TFCB DDDB TINFO
3106DDD0 TRANV 00FF TRUE 000D UBYTES
3107D341 USRCODE DDE3 VRECORD D0B4 WAIT$ERR
3108DE03 WBOOTF 0002 WORD D3B8 WRBUFF
3109D5C6 WRDIR DE2A WRITEF
3110
3111
3112
3113No Fatal error(s)