-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathdos.src
652 lines (647 loc) · 12.5 KB
/
dos.src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
.subttl disk commands
;
;********************************************
;
; Disk Command/Status Operations
;
; @[device-number][,command-string]
;
;********************************************
;
disk jsr load_to_temp assume default disk device
lda #0 clear name len
sta temp_name_len
jsr parse_no_default parse the string
bcs 90$
jsr puke_if_printer cannot use printers
bcs 90$
;
lda temp_name_len ignore the '0:' inserted by parse
cmp #3
bcs 10$
;
jmp dscheck no command is just dscheck
;
10$ ldx temp_name_len set up the file name
dex
dex
txa
ldx #<temp_name+2
ldy #>temp_name
jsr setnam
; open the disk channel,and read errst
jsr dscheck_no_setnam
90$ rts
;
;
;**************************************************************************
; disk status
;**************************************************************************
;dscheck read disk status
; plots status on status line
; returns c=0 if ok
; else returns c=1
; .a = 0
ds_lfn = 0 logical file number for ds check
;
ram ds_temp,2
;
dscheck lda #0 set up for error channel read
jsr setnam
dscheck_no_setnam ; entry point for submit command
ldx number
lda #ds_lfn
ldy #$6f
sty ds_flag ; force main routine to not update command line...
jsr setlfs
jsr open
bcs 90$
lda status
bmi 90$
ldx #ds_lfn
jsr chkin
bcs 90$
lda status
bpl 10$
90$ jsr 80$ close the command channel
lda #error_device_not_present
sec
rts
;
; set up for status line print
;
10$ lda status_line
jsr set_line
ldx #3 make sure can print
stx dflto
;
lda #0
sta ds_temp
sta ds_temp+1
;
20$ jsr basin do read a char
cmp #cr if cr
beq 80$ quit
cmp #'0' if not '0'
beq 30$
ldx ds_temp if ds_temp < 2
cpx #2
bcs 30$
inc ds_temp+1 inc ds_temp+1
30$ inc ds_temp inc ds_temp
jsr print print the char ( on command line )
jmp 20$ enddo
;
80$ lda #ds_lfn
jsr close
jsr clear_to_eol blank rest of line
jsr clrchn clear channels
lda ds_temp+1 return c=0 if ds_temp == 0
cmp #1
lda #0 .A = 0 ( null error ).
rts
;
;
;******************************************************************************
; read & display the disk directory
;******************************************************************************
ram t1
ram t0,2
ram dir_flag
;
directory
jsr load_to_temp assume default disk device
lda #0 clear name len
sta dir_flag dir_flag <= 0
sta temp_name_len
jsr parse_no_default parse the string
bcs 99$
jsr puke_if_printer can't dir printers
bcs 99$
;
lda #'$ convert 0: to $:
sta temp_name
;
lda #2 if name is 2 char long
cmp temp_name_len
bne 5$
dec temp_name_len name <= 1 char long ( "$" only )
;
5$ lda replace_flag puke iff replace flag set.....
beq 10$
lda #error_syntax_error
sec
99$ rts
;
10$ lda temp_name_len setnam
ldx #<temp_name ;fnadr low
ldy #>temp_name ;fnadr high
jsr setnam
lda #ds_lfn ;la
ldx number ;fa
ldy #$60 ;sa
jsr setlfs
jsr open ;open directory channel
bcs 90$ ;...branch on error
lda status
bmi 90$
ldx #ds_lfn
jsr chkin ;make it an input channel
bcs 90$ ;...branch on error
lda status
bmi 90$
;
lda #147
jsr print ; clear screen
inc dir_flag ; mark that we are reading directory
;
ldy #3 ;first pass only- trash first two bytes read
;
20$ sty t1 ;loop counter
25$ jsr basin
sta t0 ;get # blocks low
lda status
bne 90$ ;...branch if error
jsr basin
sta t0+1 ;get # blocks high
lda status
bne 90$ ;...branch if error
dec t1
bne 25$ ;...loop until done
;
ldax t0 print number
jsr print_decimal
;
lda #' '
jsr print print a space
;
30$ jsr basin ;read & print filename & filetype
beq 40$ ;...branch if eol
ldx status
bne 90$ ;...branch if error
jsr print
bcc 30$ ;...loop always
;
40$ lda #cr
jsr print ;start a new line
ldy #2
bne 20$ ;...loop always
;
90$ jsr clrchn ; clear channels
lda #ds_lfn ; close dir channel
sec
jsr close
lda dir_flag ; if we were really reading that crap
beq 95$
jsr primm scroll dir up above error and stat lines
.byte cr,cr,0
jsr press_any_key_to_continue
95$ jmp dscheck show user the problem
;******************************************************************************
; disk parser which has no right to exist
;******************************************************************************
;
; parse:
; parses users command for unit number, replace symbol,
; and file name.
; entry:
; users command in commanad,command_len.
; exit:
; c=1 .a=error code for why command is questionable.
; c=0 number,number = legal specified or
; default unit number.
; replace flag == 0 iff no '@'
; temp_name,temp_name_len <= default or
; specified filename with '0:'.
;
;
parse
jsr load_to_temp assume load file name ( save op ? )
parse_no_default
lda #0
sta charno char number is 0
sta replace_flag clear replace flag
;
10$ jsr gnc do read chars until at space
bcs parse_end quit if no more
bne 10$
;
15$ jsr gnc read first nonn white char after command
bcs parse_end quit if no more
beq 15$
jsr ungnc forget that we read it
jsr isdigit if was a digit
bcs 50$
lda #0 number <= 0
sta number
sta number+1
20$ jsr gnc do read char
bcs 30$ if no more or char is white
beq 30$ break
jsr char_mul_10 build up value
bcc 20$ if error
rts return
; enddo
;
30$ ldax number convert disk number to binary
jsr bcd_to_hex
stax number
;
40$ jsr gnc skip_white
bcs parse_end quit if done
beq 40$
jsr ungnc unread first non white char
;
50$ jsr gnc read next char
bcs parse_end quit if done
cmp #'@ if '@'
bne 60$
sta replace_flag set replace_flag
jsr gnc read next char
bcs parse_end end if done
;
60$ jsr ungnc unget current char ( must be file name time... )
lda #0 temp_name_len <= 0
sta temp_name_len
;
70$ jsr gnc do copy name from comand to temp_name
bcs parse_end quit if eof
ldx temp_name_len puke if too many chars
cpx #name_max-2-4 ( max string - space for "0:,s,r" )
bcs syntax
sta temp_name,x
inc temp_name_len
jmp 70$
;
syntax lda #error_syntax_error
sec
rts
;
parse_end ;if first char(s) are not "0:"
lda temp_name_len
cmp #2
bcc 10$
lda temp_name
cmp #'0
bne 10$
lda #':
cmp temp_name+1
beq 20$
10$ jsr insert_zero_colon
;
20$ lda number+1 if number < 4 or > 11
bne 90$
lda number
cmp #4
bcc 90$
cmp #12
bcc 100$
90$ sec puke
lda #error_numeric_value_illegal
100$ rts return
;
;
;
;**********************************************************************
; parser utils
;**********************************************************************
;
;
load_to_temp ; copy load file params to temp params
lda #0
sta number+1 number <= $00,load_disk
lda load_disk assume the default disk
sta number
;
ldy load_name_len copy load_name to temp_name
sty temp_name_len
10$ lda load_name,y
sta temp_name,y
dey
bpl 10$
rts
;
temp_to_load ; copy temp params to file params
lda number
sta load_disk
ldx temp_name_len
stx load_name_len
10$ lda temp_name,x
sta load_name,x
dex
bpl 10$
rts
;
insert_zero_colon
lda #':'
jsr insert_char_into_temp
lda #'0'
insert_char_into_temp
pha save char
lda temp_name_len
cmp #name_max
bcc 5$
lda #error_syntax_error
rts
5$ inc temp_name_len
ldx temp_name_len
10$ lda temp_name-1,x
sta temp_name,x
dex
bne 10$
pla
sta temp_name
rts
;
puke_if_printer
lda #error_numeric_value_illegal .a <= error code
ldx #7 return c=1 iff unit < 8
cpx number
rts
;
;
;**************************************************************************
; exit and save
;**************************************************************************
;
exit jsr parse parse the filename and unit number
bcs 90$
;
jsr puke_if_printer
bcs 90$ error, cannot exit to printer....
;
lda #'@ exit always replaces
sta replace_flag
jsr insert_char_into_temp
bcs 90$
jsr exit_entry try to save
bcs 90$
jsr dscheck check the save status
bcc 10$ if error
90$ rts return
;
10$ inc quit_flag signal main loop to quit
rts return happy
;
;
;
;
save jsr parse parse the filename and unit number
bcc 10$
rts
10$ jsr puke_if_printer if not a printer
bcs 90$
jsr exit_entry
bcs 90$
jmp dscheck
90$ rts
;
;
ram last_byte
;
type jsr clrchn clear channels
lda #0
sta temp_name_len
lda #1 number <= > 256
sta number+1
; parse the users crap
jsr parse_no_default
bcs 90$
jsr puke_if_printer if not printer
bcc 91$ puke
lda number save unit number on stack
pha
;
ldx temp_name_len if name = 0:"" ( inserted by parse )
dex
dex
bne 10$
lda #$FF x,a <= $00FF
jmp 50$ else
;
10$ stx command_len mark command len
20$ lda temp_name+2,x copy name to command
sta command,x
dex
bpl 20$
jsr parse_command_to_number convert to a number
bcc 50$ if error
tay save .a
pla restore stack
tya restore .a
bcs 90$ go complain
93$ lda #error_device_not_present
.byte $2c
92$ lda #error_syntax_error
.byte $2c
91$ lda #error_numeric_value_illegal
90$ pha
lda #2
jsr close
pla
sec
rts
;
50$ tay y <= low order bit of sa
pla .a <= unit number
cpx #0 if x <> 0
bne 91$ illegal quatity
tax .x <= unit
lda #2 la <= 2
jsr setlfs
lda #0 no name
jsr setnam
jsr open open
bcs 93$ device not present error
ldx #2 ckout
jsr ckout
bcs 93$ device_not_present_error
;
jsr buf_top move buffer to start of file
;
60$ jsr buf_advance while can read from buffer
bcs 70$
sta last_byte
jsr bsout do write to disk
bit status if nothing there
bpl 65$
jsr 80$ do up the close
lda #error_device_not_present return pissed
sec
rts
65$ jsr stop if stop pressed
bne 60$
jsr 70$
lda #error_stopped
sec
rts
;
70$ lda #cr if last byte was not cr
cmp last_byte
beq 80$
jsr bsout send one for the dummy (printer)
;
80$ jsr clrchn clear channels
lda #2 close the file
jsr close
jsr buf_to_cursor restore the file position
jsr clrchn clear channels
clc
rts
;
;
exit_entry
lda replace_flag
beq 10$
lda #'@
jsr insert_char_into_temp
bcc 10$
rts
10$ ldx temp_name_len
lda #',
sta temp_name,x
inx
lda #'W
sta temp_name,x
inx
stx temp_name_len
;
jsr dopen open the file
bcs 90$ puke if error
jsr clrchn
ldx #2 set up to write to file
jsr ckout
jsr print_entry send the data and close the file
90$ php save stat and errorno
pha
jsr buf_to_cursor goto cursor position
pla restore stat and errorno
plp
rts return
;
ram last_byte
;
print_entry
jsr buf_top move buffer to start of file
;
20$ jsr buf_advance while can read from buffer
bcs 70$
sta last_byte
jsr bsout do write to disk
bit status if nothing there
bpl 20$
jsr 80$ do up the close
lda #error_device_not_present return pissed
sec
rts
;
70$ lda #cr if last byte was not cr
cmp last_byte
beq 80$
jsr bsout send one for the dummy (printer)
80$ jsr clrchn clear channels
lda #2 close the file
jsr close
jsr buf_to_cursor restore the file position
jsr clrchn clear channels
clc
rts
;
;
;*************************************************************************
; load and include
;*************************************************************************
;
;
include jsr load_1 parse,open,chkin,etc
bcc go_load if ok, go load
rts return unhappy
;
load jsr load_1 set up for the load
bcc 10$ return if error
rts
;
10$ jsr buf_init init the buffer
jsr temp_to_load make note of this file
lda #0
sta status
;
go_load
10$ jsr basin do read a char
jsr buf_insert insert the char
bcs 90$ puke if buffer full.....
lda status until status <> 0
beq 10$
jsr dscheck show disk status to the user
php save error status
pha save error number
jsr 90$ close file
pla recall error number and status
plp
rts return to the monkey
;
90$ lda #2 ; close the file
jsr close
lda #error_insufficient_memory
sec
rts
;
; load_1
; parse for load unit, and filename
; perform the open
; perform the chkin
; return c=0 if looks ok to load
; x,a = first two bytes in file
; return c=1 if some sort of error
;
;
;
load_1 jsr parse parse the filename and unit number
bcs 90$
jsr puke_if_printer
bcs 90$
;
lda replace_flag puke if replace flag
beq 10$
jmp syntax
10$ jsr dopen open the file
bcs 90$ puke if error
jsr clrchn clear channels
ldx #2 set up to read from it...
jsr chkin
90$ rts return
;
;
;**************************************************************************
; disk open
;**************************************************************************
;
dopen lda #2 ; setlfs for suggested unit
ldx number
tay
jsr setlfs
lda temp_name_len
ldx #<temp_name ; setname for "temp_name"
ldy #>temp_name
jsr setnam
lda #$0E ; set the bank
ldx #$0E
jsr setbnk
jsr open ; attempt to open the file
bcs 91$
jsr dscheck
bcs 90$
rts ; return happy
;
91$ lda #error_device_not_present
sec
;
90$ php
pha
lda #2 ; close the file
jsr close
pla
plp
rts
;
;