-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathio.asm
2209 lines (2089 loc) · 43 KB
/
io.asm
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
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
keep obj/io
mcopy io.macros
copy sh.dp
****************************************************************
*
* Redirect
*
* This module implements I/O redirection.
*
****************************************************************
*
* IOCom - Common data area for I/O redirection
*
****************************************************************
*
IOCom data
using Common
;
; Constants
;
formFeed equ $C form feed character code
lineFeed equ $A lineFeed character code
dFile equ 2 direction number for a file
dConsole equ 0 direction number for the console
frBuffSize equ 4096 size of the I/O buffer
;
; Standard devices
;
devStout dc i'2' standard out device
dc a4'TextConsole'
devErrout dc i'2' error out device
dc a4'TextConsoleErr'
devInput dc i'2' input device
dc a4'TextConsole'
;
; Standard I/O reference numbers
;
~stinRefnum entry standard in
ds 2
~stoutRefnum entry standard out
ds 2
~erroutRefnum entry error out
ds 2
;
; Global variables
;
consoleRefnum ds 2 output reference number for .CONSOLE
erroutAppend ds 2 append to error out file?
next_fName ds 4 pointer to first file name record
next_IORec ds 4 pointer to next record in chain
stOut_Append ds 2 append to standard out file?
WstIn_fName ds 4*3 temp save area for file names
allTerms dc i'$007F,128' for specifying all chars as terminators
ioLine ds 255 input line
ds 1 (used by IOInit)
ch ds 2 character I/O buffer
;
; I/O redirection stack frame and work frame
;
fr_disp ds 2 disp into I/O buffer
fr_last ds 4 pointer to last file record
fr_next ds 4 pointer to next file record
fr_ref ds 2 reference number for the opened file
fr_name ds 4 file name
fr_output ds 2 is the file opened for output?
fr_use anop use count (output only)
fr_maxdisp ds 2 max disp allowed (input only)
fr_buff anop location in the record of the I/O buffer
fd_disp equ 0 displacements into the file record
fd_last equ fr_last-fr_disp
fd_next equ fr_next-fr_disp
fd_ref equ fr_ref-fr_disp
fd_name equ fr_name-fr_disp
fd_output equ fr_output-fr_disp
fd_use equ fr_use-fr_disp
fd_maxdisp equ fr_maxdisp-fr_disp
fd_buff equ fr_buff-fr_disp
io_next ds 4 pointer to next record
errOut_direction ds 2 direction of error out
stOut_direction ds 2 direction of standard out
stIn_direction ds 2 direction of standard in
errOut_file ds 4 pointer to errout file record
stOut_file ds 4 pointer to stout file record
stIn_file ds 4 pointer to stin file record
stIn_fName dc a4'console' stin file name
stOut_fName dc a4'console' stout file name
errOut_fName dc a4'console' errout file name
io_end anop
io_len equ io_end-io_next length of the I/O record
Wio_next ds io_len temp save area for io list
;...............................................................
;
; The remainder of this data area contains DCBs and records
; used by the .CONSOLE driver. All DCBs for the .CONSOLE
; driver should appear in this section. The device number is
; initialized by the console driver, and does not have to be
; reinitialized or checked by any subroutine using the area.
; All other named fields should be set before any call is made.
;...............................................................
;
; DCB for setting the terminator list back to the standards
;
tlDCB anop DCB for D_Control to set our terminator list
dc i'5' parameter count
tlNum ds 2 device number
dc i'$8001' control code
dc a4'terminators' control list ptr
dc i4'l:termList+4' request count
dc i4'0' transfer count
terminators dc i'$807F,l:termList/2'
termList dc i'$001B,$802E,$000D' ESC, open-apple ., RETURN
;
; Used to find the .CONSOLE device
;
scDCB anop DCB for D_Control to read the screen char
dc i'5' parameter count
scNum ds 2 device number
dc i'$8004' control code
dc a4'ch' control list ptr
dc i4'1' request count
dc i4'0' transfer count
ntDCB anop DCB for D_Control to set our terminator list
dc i'5' parameter count
ntNum ds 2 device number
dc i'$8001' control code
dc a4'allTerms' control list ptr
dc i4'260' request count
dc i4'0' transfer count
;
; Variables used by the .CONSOLE driver for input
;
rdDCB anop DCB for D_Read call
dc i'6' parameter count
rdNum ds 2 device number
rdLine ds 4 control list ptr
rdLen ds 4 request count
dc i4'0' start block
dc i'0' block size
rdTrans ds 4 transfer count
;
; .CONSOLE Input port values
;
dvDCB anop DCB for D_Control call to set/read state
dc i'5' parameter count
dvNum ds 2 device number
code ds 2 control code
dc a4'list' control list ptr
dc i4'12' request count
dc i4'0' transfer count
list dc c' ' fill character
def_cursor dc i1'$81' default cursor mode
cursor_mode dc i1'$81' current cursor mode
dc i1'0' beep flag
entry_type ds 1 initial entry flag
exit_type ds 1 exit type
dc c' ' last char read
dc i1'0' last modifier key read
last_Term dc i'0' last terminator read w/modifier
cursor_pos dc i1'0' cursor position
dc i1'0' length of the returned string
dc i1'0' input field
dc i1'0' horizontal cursor position
dc i'0' UIR origin.x
dc i1'0' vertical cursor position
;
; Tells the .CONSOLE driver to do a formatted read
;
frDCB anop DCB for D_Control to request UIM read
dc i'5' parameter count
frNum ds 2 device number
dc i'$8003' control code
dc a4'zero' control list ptr
dc i4'2' request count
dc i4'0'
zero dc i'0'
end
****************************************************************
*
* CloseErrout - Close error out
*
* Inputs:
* errOut_direction - direction of output
* errOut_file - pointer to file record
*
****************************************************************
*
CloseErrout start
using COMMON
using IOCOM
lda errOut_direction if output is to a file then
cmp #dFile
bne lb2
move4 errOut_file,r0 decrement use level
ldy #fd_use
lda [r0],Y
dec A
sta [r0],Y
bne lb1 if use level = 0 then
move4 r0,iop1 purge the buffer
jsr Purge
ldy #fd_ref close the file
lda [r0],Y
sta clRefnum
OSClose clRec
bcc lb0
sta o_error
lb0 brl DispRec deallocate the file record
lb1 anop endif
lb2 anop endif
rts
clRec dc i'1' OSClose record
clRefnum ds 2
end
****************************************************************
*
* CloseStin - Close stin
*
* Inputs:
* stIn_direction - direction of input
* stIn_file - pointer to file record
*
****************************************************************
*
CloseStin start
using COMMON
using IOCOM
lda stIn_direction if output is to a file then
cmp #dFile
bne lb1
move4 stIn_file,r0 recover file record pointer
ldy #fd_ref close the file
lda [r0],Y
sta clRefnum
OSClose clRec
bcc lb0
sta o_error
lb0 brl DispRec deallocate the file record
lb1 anop endif
rts
clRec dc i'1' OSClose record
clRefnum ds 2
end
****************************************************************
*
* CloseStout - Close stout
*
* Inputs:
* stOut_direction - direction of output
* stOut_file - pointer to file record
*
****************************************************************
*
CloseStout start
using COMMON
using IOCOM
lda stOut_direction if output is to a file then
cmp #dFile
bne lb2
move4 stOut_file,r0 decrement use level
ldy #fd_use
lda [r0],Y
dec A
sta [r0],Y
bne lb1 if use level = 0 then
move4 r0,iop1 purge the buffer
jsr Purge
ldy #fd_ref close the file
lda [r0],Y
sta clRefnum
OSClose clRec
bcc lb0
sta o_error
lb0 brl DispRec deallocate the file record
lb1 anop endif
lb2 anop endif
rts
clRec dc i'1' OSClose record
clRefnum ds 2
end
****************************************************************
*
* DoRedirection - Handle input and output redirection
*
* Inputs:
* LINE - command line with I/O redirection info
*
* Outputs:
* LINE - command line with I/O redirection stripped
* C - set if error
*
****************************************************************
*
DoRedirection start
using COMMON
using IOCOM
move io_next,Wio_next,#io_len save info, in case of error
move stIn_fName,WstIn_fName,#l:WstIn_fName
lda errOut_direction save current direction
sta old_errOut_direction
lda stOut_direction
sta old_stOut_direction
lda stIn_direction
sta old_stIn_direction
malloc #io_len allocate a new I/O redirection record
sta r0
stx r2
ora r2
bne in1
lda #outOfMem
jsl SysError
sec
rts
in1 ldy #io_len-2 save the old record
lb0 lda io_next,Y
sta [r0],Y
dey
dbpl Y,lb0
move4 r0,io_next
ph4 errOut_fName duplicate the path names
jsl DuplicateOSString
sta errOut_fName
stx errOut_fName+2
ph4 stOut_fName
jsl DuplicateOSString
sta stOut_fName
stx stOut_fName+2
ph4 stIn_fName
jsl DuplicateOSString
sta stIn_fName
stx stIn_fName+2
jsr ParseIO parse the redirection
jcs err
lda #dFile set error output direction
sta errOut_direction
sta stOut_direction
sta stIn_direction
ph4 errOut_fName
ph4 #console
jsl CompareOSStrings
tax
bne lb1
stz errOut_direction
lb1 ph4 stOut_fName set standard output direction
ph4 #console
jsl CompareOSStrings
tax
bne lb3
stz stOut_direction
lb3 ph4 stIn_fName set standard input direction
ph4 #console
jsl CompareOSStrings
tax
bne lb5
stz stIn_direction
lb5 lda #dFile if errout is to a file then
cmp errOut_direction
bne lb10
cmp stOut_direction if stout is to a file then
bne lb9
ph4 errOut_fName if they are to the same file then
ph4 stOut_fName
jsl CompareOSStrings
tax
bne lb8
lda erroutAppend if their append status differs
cmp stOut_Append then
beq lb7
puts #'Cannot append and redirect to the same file',CR=T,ERROUT=T
brl err else
lb7 lda #1 if not APPEND then
sta erroutAppend mark errout for append
; endif
; endif
lb8 anop endif
lb9 anop endif
lb10 anop endif
lda stOut_direction if either direction is a file then
ora old_stOut_direction
beq lb11
jsr RedirectStout redirect stout
move4 stOut_fName,setOut+4
OSSet_Prefix setOut
bcc lb11
sta o_error
lb11 anop
lda errOut_direction if either direction is a file then
ora old_errOut_direction
beq lb12
jsr RedirectErrout redirect errout
move4 errOut_fName,setErr+4
OSSet_Prefix setErr
bcc lb12
sta o_error
lb12 anop
lda stIn_direction if either direction is a file then
ora old_stIn_direction
beq lb13
jsr RedirectStin redirect stin
move4 stIn_fName,setIn+4
OSSet_Prefix setIn
bcc lb13
sta o_error
lb13 anop
lda #1 mark output files as append
sta stOut_Append (allows them to be "reopened")
sta erroutAppend
clc
rts rts
;
; Handle an I/O redirection error
;
err free io_next
move Wio_next,io_next,#io_len
move WstIn_fName,stIn_fName,#l:WstIn_fName
sec
rts
;
; Local data
;
setIn dc i'2,10',a4'0'
setOut dc i'2,11',a4'0'
setErr dc i'2,12',a4'0'
old_errOut_direction ds 2 old directions, for time skips
old_stOut_direction ds 2
old_stIn_direction ds 2
end
****************************************************************
*
* DispRec - Dispose of a file record
*
* Inputs:
* r0 - pointer to the record
*
****************************************************************
*
DispRec private
using COMMON
using IOCOM
ldy #fd_next fetch next pointer
lda [r0],Y
sta r8
ldy #fd_next+2
lda [r0],Y
sta r10
ldy #fd_last if last pointer is nil then
lda [r0],Y
sta r4
ldy #fd_last+2
lda [r0],Y
sta r6
ora r4
bne lb1
move4 r8,next_fName next_fName = next pointer
bra lb2
lb1 anop else
ldy #fd_next last^.next = next
lda r8
sta [r4],Y
ldy #fd_next+2
lda r10
sta [r4],Y
lb2 anop endif
lda r8 if next <> nil then
ora r10
beq lb3
ldy #fd_last next^last = last
lda r4
sta [r8],Y
ldy #fd_last+2
lda r6
sta [r8],Y
lb3 anop endif
free r0 dispose of record
rts
end
****************************************************************
*
* FileBuff - Check for an existing file buffer
*
* Inputs:
* A - 0 for input, 1 for output
* X - append flag
* r4 - address of the file name
*
* Outputs:
* C - set if name found
* V - set if there is a clash (output on a file opened for
* input, input on an open file, or redirect to an
* open file)
* r0 - pointer to buffer, if one exists
*
****************************************************************
*
FileBuff private
using COMMON
using IOCOM
sta output
stx append
move4 next_fName,r8 for each existing file record do
lb1 lda r8
ora r10
jeq lb6
add4 r8,#fd_name,r0 if names match then
ph4 [r0]
ph4 r4
jsl CompareOSStrings
tax
jne lb5
clv
move4 r8,r0 set addr of file record
lda output if file is being opened for input
bne lb2 then
ldy #fd_output if the file is open for output
lda [r8],Y then
beq lb1A
puts #'Cannot redirect input from an open file',CR=T,ERROUT=T
stz stIn_direction fake direction to console
lb1A sep #$40 flag error
bra lb4
lb2 ldy #fd_output else if old file open for input
lda [r8],Y or this is not an append then
beq lb3
lda append
bne lb4
lb3 puts #'Cannot append to an open file',CR=T,ERROUT=T
sep #$40 flag error
lb4 anop endif
sec return
rts
lb5 anop endif
ldy #fd_next next
lda [r8],Y
tax
ldy #fd_next+2
lda [r8],Y
sta r10
stx r8
brl lb1
lb6 clc
clv
rts
output ds 2 output flag
append ds 2 append flag
end
****************************************************************
*
* FileInit - Common initialization for file records
*
* Outputs:
* next_fName - pointer to record's area
* fr_last - nil
* fr_next - pointer to next file record
* fr_use - set to 1
* C - set if an error occurred
*
****************************************************************
*
FileInit private
using COMMON
using IOCOM
malloc #fd_buff+frBuffSize
sta r4
stx r6
ora r6
bne lb1
la o_error,outOfMem
sec
rts
lb1 stz fr_last last pointer is nil
stz fr_last+2
lda next_fName next pointer := next_fName
sta fr_next if next pointer is not nil then
sta r0
lda next_fName+2
sta fr_next+2
sta r2
ora r0
beq lb2
ldy #fd_last set old record's last pointer
lda r4
sta [r0],Y
ldy #fd_last+2
lda r6
sta [r0],Y
lb2 anop endif
move4 r4,next_fName set list pointer to new record
lda #1 set use count to 1
sta fr_use
clc
rts
end
****************************************************************
*
* InitConsole - Set I/O redirection to standard in/out
*
****************************************************************
*
InitConsole start
debug InitConsole
using Common
using Reccom
using IOCOM
;
; Make sure the shell knows what the standard devices are
;
SetIODevices devStout
;
; Open the console files
;
OSSet_Level lvRec make sure the level is 0
bcc lb1
sta o_error
lb1 OSClose clRec close all open files
bcc lb2
sta o_error
lb2 OSOpen opRec open .console
bcc lb3
sta o_error
brl rts
lb3 lda opRefnum set the console reference number
sta consoleRefnum
sta ~stinRefnum initialize the I/O reference numbers
sta ~stoutRefnum
sta ~erroutRefnum
sta srRefnum set the standard refnums
lda #10
sta srPrefixNum
SetStdRefnumGS srRec
inc srPrefixNum
SetStdRefnumGS srRec
inc srPrefixNum
SetStdRefnumGS srRec
;
; Initialize the text toolkit drivers
;
ph2 devInput set input device
ph4 devInput+2
_setinputdevice
bcs rts
ph2 devStout set output device
ph4 devStout+2
_setoutputdevice
bcs rts
ph2 devErrout set the error device
ph4 devErrout+2
_seterrordevice
bcs rts
ph2 #$7F set input globals
ph2 #$00
_setinglobals
bcs rts
ph2 #$7F set output globals
ph2 #$00
_setoutglobals
bcs rts
ph2 #$7F set output globals for error device
ph2 #$00
_seterrglobals
bcs rts
ph2 #0 init input device
_inittextdev
bcs rts
ph2 #1 init output device
_inittextdev
bcs rts
ph2 #2 init error device
_inittextdev
bcs rts
clc
rts rts
;
; Local data
;
clRec dc i'1' close record for closing all files
dc i'0'
lvRec dc i'1,0' set the level to 0
opRec dc i'2' for Open call
opRefNum ds 2
dc a4'console'
srRec dc i'2' for SetStdRefnum call
srPrefixnum ds 2
srRefnum ds 2
end
****************************************************************
*
* IOInit - Initialize the I/O redirection module
*
****************************************************************
*
IOInit start
using Common
using IOCom
debug IOInit
;
; Get ready for device reads of the .CONSOLE driver
;
lda #1 find out which device is the console
sta diNum driver
in1 ~OSD_Info diDCB
bcs err
ldx dName+2
cpx console
bne in3
short I,M
in2 lda console+1,X
cmp dName+3,X
bne in3
dex
bne in2
long I,M
bra in4
in3 long I,M
inc diNum
bra in1
in4 lda diNum save the device number
sta tlNum
sta frNum
sta ntNum
sta rdNum
sta dvNum
sta scNum
~OSD_Control tlDCB use our terminator list
rts
;
; Terminal error handler
;
err pha could not start the driver: this is bad!
ph4 str
_SysFailMgr
str dw 'Could not start the console device: '
;
; Local data
;
diDCB dc i'2' for D_Info calls to find the .console device
diNum ds 2
dc a4'dName'
dName dc i'35,0',31c' ' buffer for device name
end
****************************************************************
*
* OutputInit - Complete initialization of an output file buffer
*
* Inputs:
* fr_name - name of the file
* A - append flag
*
* Outputs:
* fr_output - set to 1
* fr_ref - reference number for open file
* fr_disp - set to zero bytes into the buffer
* r0 - pointer to file record
* C - set if error
*
* Notes:
* If an error ocurrs, the file record (which is assumed
* to be the first one in the list) is disposed of, and
* all pointers properly patched.
*
****************************************************************
*
OutputInit private
using COMMON
using IOCOM
;
; Initialization common to character and block devices
;
sta append save append flag
move4 next_fName,r0 set file pointer
lda #1 set output flag to true
sta fr_output
la fr_disp,fd_buff set disp to 0 bytes into buffer
;
; Handle character devices
;
lda fr_name set the path name in the file I/O
ldx fr_name+2 records
sta giPathname
sta opPathName
sta crPathname
stx giPathname+2
stx opPathName+2
stx crPathname+2
OSGet_File_Info giRec branch if the name is an existing file
bcc la1
cmp #$58 branch if this is a block device
bne la0
OSOpen opRec open the file
jcs err
lda opRefnum set the reference number
sta fr_ref
bra cc1
;
; Handle block devices
;
la0 OSCreate crRec create a new file (one does not exist)
bcs err
la1 OSOpen opRec open the file
bcs err
lda opRefnum set the reference #
sta mkRefnum
sta efRefnum
sta fr_ref
lda append if append then
beq la2
OSGet_EOF efRec set mark to EOF
bcc la1a
sta o_error
la1a move4 efEOF,mkMark
OSSet_Mark mkRec
bcc la3
sta o_error
bra la3 else
la2 stz mkMark set EOF to 0
stz mkMark+2
OSSet_EOF mkRec
bcc la3
sta o_error
la3 anop endif
;
; Common code for character and block devices
;
cc1 ldy #fd_buff-2 move the record to its spot
cc2 lda fr_disp,Y
sta [r0],Y
dey
dbpl Y,cc2
clc
rts
;
; Error handling
;
err sta o_error handle an error
ldy #fd_buff-2 move the record to its spot
la5 lda fr_disp,Y so it will dispose properly
sta [r0],Y
dey
dbpl Y,la5
jsr DispRec dispose of record
sec
rts
;
; Local data
;
append ds 2
giRec dc i'2' Get_File_Info record
giPathname ds 4
ds 2
crRec dc i'6' create record
crPathname ds 4
dc I'$C3'
dc I'4'
dc I4'0'
dc I'1'
dc 2I'0'
opRec dc i'2' Open record
opRefnum ds 2
opPathname ds 4
efRec dc i'2' Get_EOF record
efRefnum ds 2
efEOF ds 4
mkRec dc i'3' Set_Mark, Set_EOF record
mkRefnum ds 2
dc i'0'
mkMark ds 4
end
****************************************************************
*
* ParseIO - Parse I/O redirection
*
* Inputs:
* LINE - command line
*
* Outputs:
* LINE - command line with I/O redirection stripped
* C - set if error occurred
* errOut_fName - file name for error out
* erroutAppend - append to output file? (replace if false)
* stOut_ - same variables for standard out
* STIN - same variables for standard in
*
****************************************************************
*
ParseIO private
using COMMON
using IOCOM
;
; Initialization
;
stz out initialize redirection flags
stz in
stz errout
stz o_error initialize redirection error
short M reads work best with short A
ldx #0 start at beginning of line
;
; Detect and handle >>& (append to error out)
;
lb1 jsr NextChar get next char
cmp #'>' if char = '>' then
jne lb5
jsr RemoveChar remove it
jsr NextChar get next char
cmp #'>' if char = '>' then
jne lb3
jsr RemoveChar remove it
jsr NextChar get next char
cmp #'&' if char = '&' then
bne lb2
lda errout if errout then
jne err1 flag error
inc errout errout = true
jsr RemoveChar remove it
jsr GetName get file name
jcs err3
long M
free errOut_fName free the old name
move4 exPathname,errOut_fName set up redirection record
short M
lda #1
sta erroutAppend
bra lb1
;
; handle >> (append to standard out)
;
lb2 lda out if out then
jne err1 flag error
inc out out = true
dex
jsr GetName get file name
jcs err3
long M
free stOut_fName free the old name
move4 exPathname,stout_fName set up redirection record
short M
lda #1
sta stout_Append
brl lb1
;
; Detect and handle >& (write to error out)
;
lb3 cmp #'&' if char = '&' then
bne lb4
jsr RemoveChar remove it
jsr GetName get file name
jcs err3
ldx errout if error then