-
Notifications
You must be signed in to change notification settings - Fork 1
/
ch08.txt
2342 lines (2099 loc) · 92.7 KB
/
ch08.txt
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
# CHAPTER 8 - DOS PROGRAM LOGIC
This chapter will take a detailed look at the operation of the DOS program
itself to aid the APPLE user in understanding it and to help him to make
intelligent use of its facilities. Each subroutine and group of variables or
constants will be covered separately by storage address. The enterprising
programmer may wish to create a disassembly of DOS on his printer and transfer
the annotations given here directly to such a listing. Addresses used will be
for DOS 3.3 and for a 48K master diskette version of DOS. Slot 6 is assumed.
Unless specifically indicated by a $ character, lengths are given in decimal,
addresses in hexadecimal (base 16).
DISK II CONTROLLER CARD ROM - BOOT 0
ADDRESS
C600-C65B This routine is the first code executed when a disk
is to be booted. It receives control via PR#6 or
C600G or 6 control-P.
Dynamically build a translate table for converting
disk codes to six bit hex at location $356-$3FF.
Call an RTS instruction in the monitor ROM and
extract the return address from the stack to find out
the address of this controller card ROM.
Use this address to determine the slot number of this
drive by shifting $Csxx.
Save the slot number times 16 ($s0)
Clear disk I/O latches, set read mode, select drive
1, turn disk drive on.
Pull disk arm back over 80 tracks to recalibrate the
arm to track zero.
Set up parms to read sector zero on track zero to
location $800.
Execution falls through into a general sector read
subroutine at C65C.
C65C-C6FA This subroutine reads the sector number stored at
$3D on the track indicated by $41 to the address
stored at $26,$27.
Look for D5/AA/96 sector address header on the disk.
If D5/AA/AD is found and sector data was wanted, go
to C6A6.
C683 Handle a sector address block.
Read three double bytes from the disk and combine
them to obtain the volume, track, and sector number
of the sector being read from the disk at this time.
Store the track at $40.
Compare the sector found to the sector wanted and the
track found to the track wanted.
If no match, go back to C65C.
Otherwise, if sector is correct, go to C65D to find
the sector data itself.
C6A6 Handle sector data block.
Read the 85 bytes of secondary data to $300-$355.
Read 256 bytes of primary data to the address stored
at $26,$27.
Verify that the data checksum is valid.
If not, start over at C65C.
"Nibbilize" the primary and secondary data together
into the primary data buffer ($26,$27).
Increment $27 (address page of read data) and $3D
(sector number to be read) and check against $800
to see if additional sectors need to be read.
If so, reload slot*16 and go back to C65C to read
next sector. (This feature is not used when loading
DOS but is used when loading from a BASICS diskette.)
Otherwise, go to $801 to begin executing the second
stage of the bootstrap.
FIRST RAM BOOTSTRAP LOADER - BOOT 1
ADDRESS
0801-084C This routine loads the second RAM loader, Boot 2,
including RWTS, into memory and jumps to it.
If this is not the first entry to Boot 1, go to $81F.
Get slot*16 and shift down to slot number.
Create the address of the ROM sector read subroutine
(C65C in our case) and store it at $3E,$3F.
Pick up the first memory page in which to read Boot 2
from location $8FE, add the length of Boot 2 in
sectors from $8FF, and set that value as the first
address to which to read (read last page first).
081F Get sector to read, if zero, go to $839.
Translate theoretical sector number into physical
sector number by indexing into skewing table at $84D.
Decrement theoretical sector number (8FF) for next
iteration through.
Set up parameters for ROM subroutine (C65C) and
jump to it. It will return to $801 when the sector
has been read.
0839 Adjust page number at 8FE to locate entry point of
Boot 2.
Perform a PR#0 and IN#0 by calling the monitor.
Initialize the monitor (TEXT mode, standard window,
etc.)
Get slot*16 again and go to Boot 2 ($3700 for a
master disk, $B700 in its final relocated location).
DOS 3.3 MAIN ROUTINES
ADDRESS
9D00-9D0F Relocatable address constants
9D00 Address of first DOS buffer at its file name field.
9D02 Address of the DOS keyboard intercept routine.
9D04 Address of the DOS video intercept routine.
9D06 Address of the primary file name buffer.
9D08 Address of the secondary (RENAME) file name buffer.
9D0A Address of the range length parameter used for LOAD.
9D0C Address of the DOS load address ($9D00).
9D0E Address of the file manager parameter list.
9D10-9D1C DOS video (CSWL) intercept's state handler address
table. States are used to drive the handling of DOS
commands as they appear as output of PRINT statements
and this table contains the address of the routine
which handles each state from state 0 to state 6.
9D1E-9D55 Command handler entry point table. This table
contains the address of a command handler subroutine
for each DOS command in the following standard order:
INIT A54F
LOAD A413
SAVE A397
RUN A4D1
CHAIN A4F0
DELETE A263
LOCK A271
UNLOCK A275
CLOSE A2EA
READ A51B
EXEC A5C6
WRITE A510
POSITION A5DD
OPEN A2A3
APPEND A298
RENAME A281
CATALOG A56E
MON A233
NOMON A23D
PR# A229
IN# A22E
MAXFILES A251
FP A57A
INT A59E
BSAVE A331
BLOAD A35D
BRUN A38E
VERIFY A27D
9D56-9D61 Active BASIC entry point vector table. The addresses
stored here are maintained by DOS such that they
apply to the current version of BASIC running.
9D56 Address of CHAIN entry point to BASIC.
9D58 Address of RUN.
9D5A Address of error handler.
9D5C Address of BASIC coldstart.
9D5E Address of BASIC warmstart.
9D60 Address of BASIC relocate (APPLESOFT only).
9D62-9D6B Image of the entry point vector for INTEGER BASIC.
This image is copied to 9D56 if INTEGER BASIC is made
active.
9D6C-9D77 Image of the entry point vector for the ROM version
of APPLESOFT.
9D78-9D83 Image of the entry point vector for the RAM version
of APPLESOFT.
9D84-9DBE DOS coldstart entry routine.
Get the slot and drive numbers and store as default
values for command keywords.
Copy APPLESOFT ROM or INTEGER BASIC entry point
vector into current BASIC entry point vector.
Remember which BASIC is active.
Go to 9DD1.
9DBF-9DE9 DOS warmstart entry routine.
Get the remembered BASIC type and set the ROM card
as necessary (calls A5B2).
9DD1 Remember whether entry is coldstart or warmstart
Call A851 to replace DOS keyboard and video
intercepts.
Set NOMON C,I,O.
Set video intercept handler state to 0.
Coldstart or warmstart the current BASIC (exit DOS).
(DOS will next gain control when BASIC prints its
input prompt character)
9DEA-9E50 First entry processing for DOS. This routine is
called by the keyboard intercept handler when the
first keyboard input request is made by BASIC after
a DOS coldstart.
If RAM APPLESOFT is active, copy its entry point
vector to the active BASIC entry point vector and
blank out the primary file name buffer so that no
HELLO file will be run.
Set MAXFILES to 3 by default.
Call A7D4 to build the DOS file buffers.
If an EXEC was active, close the EXEC file
Set the video intercept state to 0 and indicate
warmstart status by calling A75B.
If the last command executed was not INIT (this DOS
was not just booted), go to 9E45.
Otherwise, copy an image of the DOS jump vector to
$3D0-$3FF.
Point $3F2,$3F3 to DOS warmstart routine.
Set the AUTOSTART ROM power-up byte since the RESET
handler address was changed.
Set the command index for RUN (to run the HELLO file)
and go to A180 to execute it.
9E45 See if there is a pending command.
If so, go to A180 to execute it. Otherwise, return
to caller.
9E51-9E7F An image of the DOS 3-page jump vector which the
above routine copies to $3D0-$3FF. See Chapter 5 for
a description of its contents.
9E81-9EB9 DOS keyboard intercept routine.
Call 9ED1 to save the registers at entry to DOS.
If not coldstarting or reading a disk file,
go to 9E9E.
Get value in A register at entry and echo it on the
screen (erases flashing cursor).
If in read state (reading a file) go to A626 to get
next byte from disk file.
Otherwise, call 9DEA to do first entry processing.
Put cursor on screen in next position.
If EXECing, call A682 to get the next byte from the
EXEC file.
Set the video intercept state to 3 (input echo).
Call 9FBA to restore the registers at entry to DOS.
Call the true keyboard input routine.
Save the input character so that it will be restored
with the registers in the A register.
Do the same with the new X register value.
Exit DOS via 9FB3.
9EBA-9EBC A jump to the true KSWL handler routine.
9EBD-9ED0 DOS video intercept routine.
Call 9ED1 to save the registers at entry to DOS.
Get the video intercept state and, using it as an
index into the state handler table (9D11), go to
the proper handler routine, passing it the character
being printed.
9ED1-9EEA Common intercept save registers routine.
Save the A, X, Y, and S registers at AA59-AA5C.
While in DOS, restore the true I/O handlers (KSWL and
CSWL) to $36-$39.
Return to caller.
9EEB-9F11 State 0 output handler. --start of line--
If a RUN command was interrupted (by loading RAM
APPLESOFT) go to 9F78 to complete it.
If read flag is on (file being read) and output is a
"?" character (BASIC INPUT), go to state 6 to skip
it.
If read flag is on and output is prompt character
($33) go to state 2 to ignore the line.
Set state to 2 (ignore non-DOS command) just in case.
If output character is not a control-D, go to
state 2.
Otherwise, set state to 1 (collect possible DOS
command), set line index to zero, and fall through
to state 1.
9F12-9F22 State 1 output handler. --collect DOS command--
Using line index, store character in input buffer at
$200.
Increment line index.
If character is not a carriage return, exit DOS
via 9F95 (echo character on screen if MON I).
Otherwise, go to command scanner at 9FCD.
9F23-9F2E State 2 output handler. --non-DOS command ignore--
If the character is not a carriage return, exit DOS
via 9FA4 (echo character on screen).
Otherwise, set state back to 0 and exit DOS via
9FA4.
9F2F-9F51 State 3 output handler. --INPUT statement handler--
Set state to 0 in case INPUT ends.
If character is not a carriage return, echo it on
screen as long as EXEC is not in effect with NOMON I
but exit DOS in any case. (KSWL will set state=3)
Otherwise, call A65E to see if BASIC is executing a
program or is in immediate mode. If EXEC is running
or if BASIC is in immediate mode, go to state 1 to
collect the possible DOS command.
Otherwise, exit DOS, echoing the character as
appropriate.
9F52-9F60 State 4 output handler. --WRITE data to a file--
If the character is a carriage return, set state to
5 (start of write data line).
Call A60E to write the byte to the disk file.
Exit DOS with echo on screen if MON O.
9F61-9F70 State 5 output handler. --Start of WRITE data line--
If the character is a control-D, go to state 0 to
immediately exit write mode.
If the character is a line feed, write it and exit,
staying in state 5.
Otherwise, set the state to 4 and go to state 4.
9F71-9F77 State 6 output handler. --Skip prompt character--
Set state to 0.
Exit DOS via 9F9D (echo if MON I).
9F78-9F82 Finish RUN command, interrupted by APPLESOFT RAM LOAD
Reset the "RUN interrupted" flag.
Call A851 to replace the DOS CSWL/KSWL intercepts.
Go to A4DC to complete the RUN command.
9F83-9F94 DOS command scanner exit to BASIC routine.
If first character of command line is control-D,
go to echo exit (9F95).
Otherwise, set things up so BASIC won't see the DOS
command by passing a zero length line (only a
carriage return). Fall through to echo exit.
9F95-9FB0 Echo character on screen (conditionally) and exit DOS
9F95 Echo only if MON C set, otherwise, go to 9FB3.
9F99 Echo only if MON O set, otherwise, go to 9FB3.
9F9D Echo only if MON I set, otherwise, go to 9FB3.
9FA4 Always echo character.
Call 9FBA to restore registers at entry to DOS.
Call 9FC5 to echo character on screen.
Save contents of the registers after echoing.
Fall through to DOS exit routine.
9FB3-9FC4 DOS exit routine and register restore.
Call A851 to put back DOS KSWL/CSWL intercepts.
Restore S (stack) register from entry to DOS.
9FBA DOS register restore subroutine.
Restore registers from first entry to DOS and return
to caller.
9FC5-9FC7 A jump to the true CSWL routine.
9FC8-9FCC Skip a line on the screen.
Load a carriage return into the A register and
call 9FC5 to print it.
9FCD-A179 DOS command parse routine.
Set the command index to -1 (none).
Reset the pending command flag (none pending).
9FD6 Add one to command index.
If first charcater is a control-D, skip it.
Flush to a non-blank (call A1A4).
Compare command to command name in command name table
at A884 for the current command index.
If it doesn't match and if there are more entries
left to check, go back to 9FD6.
If it does match, go to A01B.
Otherwise, if command was not found in the table,
check to see if the first character was a control-D.
If so, go to A6C4 to print "SYNTAX ERROR".
Otherwise, call A75B to reset the state and warmstart
flag and go to 9F95 to echo the command and exit.
(the command must be for BASIC, not DOS)
A01B Compute an index into the operand table for the
command which was entered.
Call A65E to see if a BASIC program is executing.
If not, and the command is not a direct type command,
(according to the operand table) go to A6D2 to print
"NOT DIRECT COMMAND".
Otherwise, if the command is RUN, make the prompt
character ($33) non-printing.
Check the operand table to see if a first filename
is a legal operand for this command.
If not, go to A0A0.
Otherwise, clear the filename buffer (call A095).
Flush to the next non-blank (call A1A4) and copy
the filename operand to the first filename buffer.
Skip forward to a comma if one was not found yet.
If a second filename is legal for this command, use
the code above to copy it into the second filename
buffer.
Check both filenames to see if they are blank.
If one was required by the command but not given,
give a syntax error or pass it through to BASIC.
(As in the case of LOAD with no operands)
If all is well, go to A0D1 to continue.
A095 A subroutine to blank both filename buffers.
A0A0 Indicate no filename parsed.
Check operand table to see if a positional operand
is expected.
If not, go to A0D1 to continue.
Otherwise, call A1B9 to convert the numeric operand.
If omitted, give syntax error.
If number converted exceeds 16, give "RANGE ERROR"
If number is supposed to be a slot number, give
"RANGE ERROR" if it exceeds 7.
If number is not a slot number, give "RANGE ERROR" if
it is zero. (MAXFILES 0 is a no-no)
A0D1 Set defaults for the keyword operands (V=0,L=0,B=0)
A0E8 Get the line offset index and flush to the next
non-blank, skipping any commas found.
If we are not yet to the end of the line, go to A10C.
Check to see if any keywords were given which were
not allowed for this command.
If not, go to A17A to process the command.
A10C Lookup the keyword found on the command line in the
table of valid keywords (A940)
If not in table, give "SYNTAX ERROR" message.
Get its bit position in the keywords-given flag.
If the keyword does not have an operand value, go to
A164.
Otherwise, indicate keyword found in flag.
Convert the numeric value associated with keyword.
Give "SYNTAX ERROR" message if invalid.
Check to see if the number is within the acceptable
range as given in the keyword valid range table at
A955.
Save the value of the keyword in the keyword values
table starting at AA66.
Go parse the next keyword. go to A0E8.
A164 Indicate C, I, or O keywords were parsed.
Update the MON value in the keyword value table
appropriately.
Go parse the next keyword. go to A0E8.
A17A-A17F Call A180 to process the command, then exit via echo
at 9F83.
A180-A192 Do command.
Reset the video intercept state to zero.
Clear the file manager parameter list.
Using the command index, get the address of the
command handling routine from the command handler
routine table at 9D1E and go to it.
Command handler will exit to caller of this routine.
A193-A1A3 Get next character on command line and check to see
if it is a carriage return or a comma.
A1A4-A1AD Flush command line characters until a non-blank is
found.
A1AE-A1B8 Clear the file manager parameter list at B5BA to
zeros.
A1B9-A1D5 Convert numeric operand from command line. Call
either A1D6 (decimal convert) or A203 (hex convert)
depending upon the presence or lack thereof of a
dollar sign ($).
A1D6-A202 Decimal convert subroutine.
A203-A228 Hexadecimal convert subroutine.
A229-A22D PR#n command handler.
Load the parsed numeric value and exit via FE95 in
the monitor ROM.
A22E-A232 IN#n command handler.
Load the parsed numeric value and exit via FE8B in
the monitor ROM.
A233-A23C MON command handler.
Add new MON flags to old in AA5E and exit.
A23D-A250 NOMON command handler.
If C was given, put out a carriage return since this
line was echoed but its CR was not.
Turn off the proper bits in AA5E and exit.
A251-A262 MAXFILES command handler.
Turn off any EXEC file which is active.
Close all open files (call A316).
Set the new MAXFILES number at AA57.
Go to A7D4 to rebuild the DOS file buffers and exit.
A263-A270 DELETE command handler.
Load the delete file manager opcode (05).
Call the file manager open driver (A2AA) to perform
the delete.
Find the file buffer used to do the delete and free
it (call A764).
Exit to caller.
A271-A274 LOCK command handler.
Load the lock file manager opcode (07) and go to
A277.
A275-A27C UNLOCK command handler.
Load the unlock file manager opcode (08).
A277 Call the file manager open driver (A2AA) to perform
the desired function.
Exit to the caller via close (A2EA).
A27D-A280 VERIFY command handler.
Load the verify file manager opcode (0C) and go to
A277 to perform function.
A281-A297 RENAME command handler.
Store address of second file name in file manager
parameter list.
Load the rename file manager opcode (09).
Call the file manager driver at A2C8.
Exit via close (A2EA).
A298-A2A2 APPEND command handler.
Call A2A3 to OPEN the file.
Read the file byte by byte until a zero is found.
If append flag is on, add one to record number
and turn flag off.
Exit via a call to POSITION.
A2A3-A2A7 OPEN command handler.
Set file type as TEXT.
Go to A3D5 to open file.
A2A8-A2E9 Command handler common file management code.
Set opcode to OPEN.
A2AA If no L value was given on the command, use 0001 and
store record length value in file manager parmlist.
A2C8 Close file if already open.
Is there an available file buffer?
If not, issue "NO FILE BUFFERS AVAILABLE" message.
Point $40,$41 at the free file buffer.
Copy filename to file buffer (allocates the buffer)
(A743).
Copy buffer pointers to file manager parmlist (A74E).
Finish filling in the file manager parmlist (A71A).
Set operation code in parmlist.
Exit through the file manager driver.
A2EA-A2FB CLOSE command handler.
If no filename was given as part of command,
go to A316 to close all files.
Otherwise, find the open file buffer for filename
(A764).
If no such file open, exit to caller.
Otherwise, close file and free buffer (A2FC).
Go back through CLOSE command handler to make sure
there are not more open buffers for the same file.
A2FC-A315 Close a file and free its file buffer.
Find out if this buffer is EXEC's (A7AF).
If so, turn EXEC flag off.
Release the buffer by storing a $00 on its filename
field.
Copy file buffer pointers to the file manager
parmlist.
Set file manager opcode to CLOSE.
Exit through the file manager driver routine.
A316-A330 Close all open files.
Point to first file buffer (A792).
Go to A320.
A31B Point to next file buffer on chain (A79A).
If at end of chain, exit to caller.
A320 Is this file buffer EXEC's?
If so, skip it and go to A31B.
Is it not in use (open)?
If so, skip it and go to A31B.
Otherwise, close it and free it (A2FC).
Go to A316 to start all over.
A331-A35C BSAVE command handler.
Insure that the A and L keywords were present on the
command.
If not, issue "SYNTAX ERROR" message.
Open and verify a B type file (A3D5).
Write the A keyword value as the first two bytes of
the file.
Write the L keyword value as the next two bytes of
the file.
Use the A value to exit by writing a range of bytes
from memory to the file.
A35D-A38D BLOAD command handler.
Open the file, ignoring its type.
Insure the type is B.
If not, issue "FILE TYPE MISMATCH" message.
Otherwise, open B type file and test file type (A3D5)
Read the A value from the first two bytes of file.
If A keyword was not given, use the value just read.
Read L value as next two bytes in file.
Go to A471 to read range of bytes to memory from file
A38E-A396 BRUN command handler.
Call BLOAD command handler to load file into memory.
Replace DOS intercepts.
Exit DOS by jumping to the A address value to begin
execution of the binary program.
A397-A3D4 SAVE command handler.
Get the active BASIC type (AAB6).
If INTEGER, go to A3BC.
If APPLESOFT, test $D6 flag to see if program is
protected.
If so, issue "PROGRAM TOO LARGE" message.
Otherwise, open and test for A type file (A3D5).
Compute program length (PGMEND-LOMEM).
Write this two byte length to file.
Exit by writing program image from LOMEM as a range
of bytes (A3FF).
A3BC Open and test for I type file (A3D5).
Compute program length (HIMEM-PGMSTART).
Write this two byte length to file.
Exit by writing program image from PGMSTART as a
range of bytes (A3FF).
A3D5-A3DF Open and test file type.
Set file type wanted in file manager parmlist.
Call A2A8 to open file.
Go to A7C4 to check file type.
A3E0-A3FE Write a 2 byte value to the open file.
Store value to be written in file manager parmlist.
Set write one byte opcodes.
Call file manager driver.
Call it again to write second byte and exit to caller
A3FF-A40F Read/write a range of bytes.
Set the address of the range in file manager parmlist
Set subcode to read or write a range of bytes.
Call the file manager driver.
Close the file.
Exit through the VERIFY command handler to insure
data was written ok.
A410-A412 Issue "FILE TYPE MISMATCH" message.
A413-A479 LOAD command handler.
Close all files (A316).
Open the file in question.
Is it an A or I type file?
If not, issue "FILE TYPE MISMATCH" message.
Which BASIC is active?
If INTEGER, go to A450.
Select APPLESOFT BASIC (A4B1). This call could result
in DOS losing control if the RAM version must be
run.
Read first two bytes of file as length of program.
Add length to LOMEM (program start) to compute
program end.
Is program end beyond HIMEM?
If so, close file and issue "PROGRAM TOO LARGE".
Set program end and start of variables pointers.
Read program as range of bytes to program start.
Replace DOS intercepts (A851).
Go to BASIC's relocation routine to convert a RAM
APPLESOFT program to ROM and vice versa as needed.
A450 Select INTEGER BASIC (A4B1).
Read length of program (first two bytes in file).
Compute program start (HIMEM-LENGTH).
If zero or less than LOMEM, issue "PROGRAM TOO LARGE"
message and close file.
Set program start pointers.
Read program into memory as a range of bytes.
Exit to caller.
A47A-A4AA Read two bytes from file (Address or Length).
Set up parmlist to read two bytes to range length
field (AA60).
Call file manager driver.
Store value read as range length in file manager
parmlist just in case it was a length.
A4AB-A4B0 Close file and issue "PROGRAM TOO LARGE" message.
A4B1-A4D0 Select desired BASIC.
If desired BASIC is already active, exit to caller.
Save current command index in case we must RUN
APPLESOFT.
If INTEGER, go to A59E to select it.
Otherwise, copy primary file name to secondary
buffer to save it in case RAM APPLESOFT is needed.
Go to A57A to set APPLESOFT.
A4D1-A4E4 RUN command handler.
If APPLESOFT is active, set RUN intercepted flag so
that RUN can complete after APPLESOFT is loaded.
Call LOAD command handler to load the program.
Skip a line on the screen.
Put DOS intercepts back.
Go to the RUN entry point in the current BASIC.
A4E5-A4EF INTEGER BASIC RUN entry point intercept.
Delete all variables (CLR equivalent).
Go to the CHAIN entry point in INTEGER BASIC.
A4F0-A4FB CHAIN command handler.
Call the LOAD command handler to load the program.
Skip a line.
Replace DOS intercepts.
Go to current BASIC's CHAIN entry point.
A4FC-A505 APPLESOFT ROM RUN entry point intercept.
Call APPLESOFT to clear variables.
Reset ONERR.
Go to RUN entry point.
A506-A50D APPLESOFT RAM RUN entry point intercept.
Call APPLESOFT to clear variables.
Reset ONERR.
Go to RUN entry point.
A510-A51A WRITE command handler.
Call READ/WRITE common code (A526).
Set CSWL state to 5 (WRITE mode line start).
Exit DOS (9F83).
A51B-A525 READ command handler.
Call READ/WRITE common code (A526).
Set READ mode flag in status flags (AA51).
Exit DOS (9F83).
A526-A54E READ/WRITE common code.
Locate the open file buffer for this file (A764).
If not open, open it.
Copy file buffer addresses to file manager parmlist.
If R or B were given on command, copy to parmlist
and issue a POSITION call to file manager.
Exit to caller.
A54F-A56D INIT command handler.
If V was given, use it. Otherwise, use 254.
Store first page number of DOS in file manager
parmlist.
Call file manager driver to INIT diskette.
Exit through SAVE to store greeting program on disk.
A56E-A579 CATALOG command handler.
Call file manager with CATALOG opcode.
Set new V value as default for future commands.
Exit to caller.
A57A-A59D FP command handler.
Set ROM card, if any, for APPLESOFT (A5B2).
If successful, coldstart DOS (9D84).
Otherwise, set status flag to indicate INTEGER BASIC
is active.
Set primary filename buffer to "APPLESOFT".
Set flags to indicate RAM APPLESOFT and coldstart.
Go to RUN command handler.
A59E-A5B1 INT command handler.
Set ROM card, if any, for INTEGER BASIC (A5B2).
If not successful, issue "LANGUAGE NOT AVAILABLE".
Otherwise, clear RUN intercepted flag.
Coldstart DOS (9D84).
A5B2-A5C5 Set ROM to desired BASIC.
(This routine is passed a $4C for APPLESOFT or a $20
for INTEGER, since these bytes appear at $E000 in
these BASICs. It will work regardless of which
BASIC is onboard)
If desired BASIC is already available, exit.
Try selecting ROM card.
If desired BASIC is now available, exit.
Try selecting onboard ROM.
If desired BASIC is now available, exit.
Otherwise, exit with error return code.
A5C6-A5DC EXEC command handler.
Open the file (A2A3).
Copy file buffer address to EXEC's buffer pointer at
AAB4,AAB5.
Set EXEC active flag (AAB3).
Jump into POSITION command handler to skip R lines.
A5DD-A60D POSITION command handler.
Locate the open file buffer (A764).
If not found, open one as a TEXT file.
Copy buffer pointers to file manager parmlist.
If R was not given on command, exit.
A5F2 Otherwise, test R value for zero and exit if so.
Decrement R value by one.
Read file byte by byte until a carriage return (end
of line - $8D) is reached.
If at end of file, issue "END OF FILE" message.
Otherwise, go to A5F2 to skip next record.
A60E-A625 Write one data byte to file.
Insure that BASIC is running a program (A65E).
If not, close file and warmstart DOS.
Set up file manager parmlist to write the data byte
to the open file.
Call file manager and exit.
A626-A65B Read one data byte from file.
Insure that BASIC is running a program (A65E).
If not, close file and warmstart DOS.
Set CSWL intercept state to 6 (skip prompt character)
A630 Read next file byte (A68C).
If not at end of file, go to A644.
Otherwise, close file.
If state is not 3 (EXEC) issue "END OF DATA" message.
Exit to caller.
A644 If data byte is lower case character, turn its most
significant bit off to fool GETIN routine in monitor.
Store data byte in A register saved at entry to DOS.
Using line index, turn high bit back on in previous
data byte stored at $200 (input line buffer) to make
it lower case if necessary.
Exit DOS (9FB3).
A65E-A678 Test to see if BASIC is running a program or is in
immediate command mode.
If active BASIC is INTEGER, go to A672.
If line number is greater than 65280 and prompt is
"]" then APPLESOFT is in immediate mode.
Otherwise, it is executing a program.
Exit to caller with appropriate return code.
A672 Check $D9 to determine whether BASIC is executing a
program and exit with proper return code.
A679-A681 Close current file and warmstart DOS.
A682-A68B EXEC read one byte from file.
Select EXEC file buffer.
Copy file buffer addresses to file manager parmlist.
Set state to 3 (input echo).
Go to A62D to read a file byte.
A68C-A69C Read next text file byte.
Set up file manager parmlist to read one byte.
Call file manager driver.
Return to caller with the data byte.
A69D-A6A7 Set $40,$41 to point to EXEC file buffer.
A6A8-A6C3 File manager driver routine.
Call the file manager itself (AB06).
If no errors, exit to caller.
Otherwise, point $40,$41 at file buffer.
If found, release it by storing a zero on the file
name field.
If error was not "END OF DATA", print error message.
Otherwise, pretend a $00 was read and return to
caller.
A6C4-A6D4 Miscellaneous error messages.
A6C4 "COMMAND SYNTAX ERROR"
A6C8 "NO FILE BUFFERS AVAILABLE"
A6CC "PROGRAM TOO LARGE"
A6D0 "FILE TYPE MISMATCH"
A6D5-A701 Error handler.
Set warmstart flag and clear status (BFE6).
If APPLESOFT ONERR is active, go to A6EF.
Otherwise, print RETURN BELL RETURN.
Print text of error message (A702).
Print another RETURN.
A6EF Replace DOS intercepts.
If a BASIC program is in execution, pass error code
to BASIC's error handler.
Otherwise, warmstart BASIC.
A702-A719 Print text of error message.
Using the error number as an index, print the message
text from the message table (A971) byte by byte.
Last character has most significant bit on.
A71A-A742 Complete file manager parameter list.
Copy Volume value to parmlist.
Copy Drive value to parmlist.
Copy Slot value to parmlist.
Copy address of primary filename buffer to parmlist.
Save file buffer address in $40,$41.
Return to caller.
A743-A74D Copy primary filename to file buffer filename field.
A74E-A75A Copy current buffer pointers to file manager parmlist
Copy file manager workarea buffer pointer.
Copy T/S List sector buffer pointer.
Copy data sector buffer address.
Copy next file buffer link address.
Return to caller.
A75B-A763 Reset state to 0 and set warmstart flag.
A764-A791 Locate an open or free file buffer.
Assume there are no free file buffers by zeroing $45.
Point $40,$41 at first buffer on chain.
Go to A773.
A76E Point $40,$41 at next buffer on chain.
If at end of chain, exit with file not open code.
A773 Get first byte of filename field.
If zero (file buffer free), save file buffer address
at $44,$45 as an available buffer and go to A76E.
Otherwise, see if name in primary filename buffer
matches the name in this file buffer.
If not, go to A76E to get next buffer.
If so, return to caller with open file found code.
A792-A799 Point $40,$41 at first file buffer on chain.
A79A-A7A9 Point $40,$41 at next file buffer on chain.
A7AA-A7AE Get first byte of file name in file buffer.
A7AF-A7C3 See if current buffer belongs to EXEC.
Is EXEC active?
If not, exit.
If so, does current buffer address match EXEC's?
Return to caller with appropriate code.
A7C4-A7D3 Check file type.
Does file type of open file match desired file type?
If so, exit.
Otherwise, turn lock bit off and test again.
If ok, exit.
Otherwise, close file and issue "FILE TYPE MISMATCH".
A7D4-A850 Initialize (build) DOS file buffer chain.
Set $40,$41 to point to first buffer.
Set counter to MAXFILES value.
A7E5 Store zero on filename field to mark as free.
Set up link pointers in buffer to point to file
manager workarea (45 bytes prior to filename field).
Set up link pointer to T/S List sector buffer (-256
bytes from file manager workarea buffer).
Set up link pointer to data sector buffer 256 bytes
before that.
Decrement counter.
If zero, go to A82D to set HIMEM.
Otherwise, set link to next file buffer as 38 bytes
prior to data sector buffer.
Go to A7E5 to set up next buffer.
A82D Set link of last buffer to $0000.
If INTEGER BASIC is active, go to A846.
Otherwise, set APPLESOFT's HIMEM and STRING START
pointers in zeropage to point just below the last
buffer.
Exit to caller.
A846 Set INTEGER BASIC's HIMEM and PROGRAM START pointers
to point just below the last buffer.
Exit to caller.
A851-A883 Replace DOS keyboard/video intercept vectors.
Is DOS keyboard (KSWL) vector still set?
If so, go to A86A.
Otherwise, save current KSWL vector ($38,$39) at
AA55,AA56 and replace with DOS intercept routine's
address.
A86A Is DOS video (CSWL) vector still set?
If so, exit to caller.
Otherwise, save current CSWL vector ($36,$37) at
AA53,AA54 and replace with DOS intercept routine's
address.
Exit to caller.
A884-A908 DOS command name text table.
This table consists of the ASCII name for each DOS
command in order of command index values, with the
last character of each indicated by the MSB being
on. Commands in order are:
INIT,LOAD,SAVE,RUN,CHAIN,DELETE,LOCK,UNLOCK,CLOSE,
READ,EXEC,WRITE,POSITION,OPEN,APPEND,RENAME,
CATALOG,MON,NOMON,PR#,IN#,MAXFILES,FP,INT,BSAVE,
BLOAD,BRUN,VERIFY.
Example: INIT is $49 $4E $49 $D4 (I N I T)
A909-A940 Command valid keywords table.
This table is used to determine which keywords are
required or may be given for any DOS command.
Each command has a two byte entry with 16 flags,
indicating which keywords may be given. The flag
bit settings are as follows:
BIT MEANING
0 Filename legal but optional
1 Command has no positional operand
2 Filename #1 expected
3 Filename #2 expected
4 Slot number positional operand expected
5 MAXFILES value expected as positional operand
6 Command may only be issued from within a program
7 Command may create a new file if file not found
8 C, I, O keywords legal
9 V keyword legal
10 D keyword legal
11 S keyword legal
12 L keyword legal
13 R keyword legal
14 B keyword legal
15 A keyword legal
Thus, for a typical command, OPEN, where the value
is $2378, bits 2, 6, 7, 9, 10, 11, and 12 are set so
the command has one filename operand, may only be
issued from within a program, may create a new file,
and the V, D, S, and L keywords are legal.
The command entries are:
INIT 2170
LOAD A070
SAVE A170
RUN A070
CHAIN 2070