-
Notifications
You must be signed in to change notification settings - Fork 78
/
kernal_dh.txt
1915 lines (1442 loc) · 99.4 KB
/
kernal_dh.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
- C64 KERNAL API (Tool Kit)
-
- Dan Heeb: COMPUTE!'s VIC-20 and Commodore 64 Tool Kit: Kernal
- ISBN 0942386337
-
- Corrections (typos as well as content), translations etc.
- welcome at: https://github.com/mist64/c64ref
-
----------------------------------------------
-
# This plain text file is formatted so that it can be automatically
# parsed in order to create cross-references etc.
# * Lines starting with "-" is top-level information. The first line
# is the title. Lines starting with "--" are separators.
# * Lines starting with "#" are internal comments.
# * Hex addresses start at column 0.
# * Symbols start at column 7.
# * The description starts at column 15.
# * All lines of the description until the first blank line are
# combined into the heading.
# * The remaining text is in MarkDown format.
# The encoding is UTF-8.
$FFA5 ACPTR Get a byte from serial bus
**Called by**: None.
**Setup routines**: TALK, TKSA
The vector is JMP EE13/EF19. At EE13/EF19 the com-
puter goes through a handshake sequence with the serial bus.
During this sequence, the EOI handshake is performed if the
serial clock input line does not go low within 250 micro-
seconds as expected. If the EOI handshake sequence is per-
formed, the routine sets the EOI status in the I/O status word,
location 90. It can set the time-out status in the status word if
serial clock in fails to go low within a certain time range.
If the preparation to receive handshaking signals detects
no problems, and if the eight bits are received without
handshaking error, the routine returns the byte received in the
accumulator.
**Exit conditions**: The accumulator contains the byte received from the serial
bus.
$FFC6 CHKIN Open channel for input
**Called by**: JSR at E11E/E11B in BASIC's Set Input Device.
**Setup routines**: OPEN
**Entry requirements**: The X register should contain the logical file number.
JMP (031E) with a default of F20E/F2C7. If the logical file
is in the logical file number table, the routine obtains the de-
vice number and secondary address for this logical file from
the corresponding entries in the device number and secondary
address tables. If the logical file is not in the logical file num-
ber table, it displays FILE NOT OPEN, and returns with carry
set and accumulator set to 3.
If the current device is the screen or the keyboard, the
routine stores 0 for the keyboard or 3 for the screen in 99, the
location holding the device number of the current input de-
vice. You don't have to use OPEN and CHRIN to input from
the keyboard.
If the current device is the tape, the routine also checks
the secondary address. If the current secondary address is not
$60, the routine displays the NOT INPUT FILE message, and
returns with carry set and accumulator set to 6. If the current
secondary address is $60, then location 99 is set to 1 to make
tape the current input device. OPEN does an ORA $60 of the
secondary address.
If the current device is a serial device, it opens the input
channel by sending a TALK command to the device, and send-
ing the secondary address if the value for secondary address
held in B9 is < 128 (decimal). If the serial device does not re-
spond, it displays the DEVICE NOT PRESENT error message
and returns with carry set and accumulator set to 5. Other-
wise, it stores the serial device number in 99.
If the current device is RS-232, the routine opens an RS-
232 input channel. This RS-232 routine sets the current input
device, location 99, to 2 for RS-232, then handles either the 3-
line handshaking or the x-line handshaking opening sequence.
$F20E CHKIN Execution F20E/F2C7-F236/F2EF
**Called by**:
Indirect JMP through (031E) from Kernal CHKIN vector at FFC6.
If the current logical file passed in the X register is in the
logical file number table, obtain its corresponding device num-
ber and secondary address from the device number and
secondary address tables. If it is not in the logical file number
table, exit with FILE NOT OPEN error message.
If the device is the screen or the keyboard, set location 99,
the current input device number, from BA, the current device
number, and exit.
If the current device is an RS-232 device, JMP to the
Open RS-232 Device routine.
If the current device is a serial device, JMP to the Open
Serial Input Channel routine.
If the current device is tape, see if the secondary address
indicates reading from tape. If not, JMP to display the NOT
INPUT FILE message.
Store the current device number in the input device num-
ber, 99, CLC, and exit.
**Operation**:
1. JSR F30F/F3CF to see if the logical file number in the X
register exists. If the logical file passed in the X register is
not in the logical file number table, JMP F701/F784 to FILE
NOT OPEN error message, set accumulator to 3, set the
carry, and exit.
2. JSR F31F/F3DF to set the current logical file number in B8,
the current device number in BA, and the current secondary
address in B9 from the tables for the logical file, device
number, and secondary address.
3. If the current device, BA, is the keyboard (0), or the screen
(3), branch to step 8.
4. If the current device number is > 3, the current device is a
serial device; branch to F237/F2F0 to open a logical file for
a serial device.
5. If the current device is an RS-232 device, JMP F04D/F116
to open an RS-232 logical file as an input channel.
6. If the current device is tape, see if the secondary address is
$60. If the secondary address is $60, branch to step 8. The
secondary address of $60 is set during the OPEN Execution
routine when the secondary address is ORed with $60.
7. If the secondary address is not $60, JMP F70A/F78D to dis-
play the NOT INPUT FILE message and exit with the accu-
mulator set to 6 and the carry set.
8. STA (the current device number is in the accumulator) into
99, the input device number.
9. CLC and RTS.
$FFC9 CHKOUT Open channel for output
**Called by**: JSR at E4AE/E115 in BASIC's Set Output Device.
**Entry requirements**: Set X register to logical file number.
JMP (0320) with default of F250/F309. If the logical file is
in the logical file number table, obtain the device number and
secondary address for this logical file from the corresponding
entries in the device number and secondary address tables. If
the logical file is not in the logical file number table, display
the FILE NOT OPEN message, and return with carry set and
accumulator set to 3.
If the current device is the keyboard, display the NOT
OUTPUT FILE message, and return with carry set and accu-
mulator set to 7.
If the current device is the screen, just set 9A, the current
output device, to 3, and exit. You do not have to call OPEN
and CHROUT to display on the screen.
If the current device is tape, also check the secondary ad-
dress. If the secondary address is not $61, display the NOT
OUTPUT FILE message, and return with carry set and accu-
mulator set to 7. If the current secondary address is $61, set
9A to 1 for tape. Note: OPEN does an ORA $60 of the
secondary address.
If the current device is a serial device, open the output
channel for a serial device. Do this by commanding the cur-
rent device to listen. Then for secondary addresses < 128, set
the serial attention output line high. If the serial device does
not handshake as expected, display DEVICE NOT PRESENT,
and return with carry set and accumulator set to 5. Otherwise,
set 9A to the serial device number.
If the current device is RS-232, then open an RS-232 out-
put channel. This routine sets 9A to 2, and then it handles the
3-line or x-line handshaking sequence.
$F250 CHKOUT Execution F250/F309-F278/F331
**Called by**: Indirect JMP through (0320) from Kernal CHKOUT vector at
FFC9.
If the logical file number passed in the accumulator at en-
try is not in the logical file table, display the FILE NOT OPEN
error message.
If the logical file is in the file number table, obtain the
current device number and secondary address for this logical
file.
If the device is the keyboard, display the NOT OUTPUT
FILE error message.
If the device is the screen, store the device number in the
output device number, 9A, and exit.
If the device is a serial device, branch to Open Serial Out-
put Channel.
If the device number is 2 (RS-232), jump to Open RS-232
Output Channel.
If the device is tape, the secondary address must not be
$60 because this indicates read from tape. If $60 is found, dis-
play the NOT OUTPUT FILE error message. If the secondary
address is legal, set the output device number, 9A, to the
value 1.
**Operation**:
1. JSR F30F/F3CF to see if the logical file number passed in
the X register is in the logical file number table. If not, JMP
F701/F784 to display the FILE NOT OPEN error message
and return with 3 in accumulator and carry set, then exit.
2. JSR F31F/F3DF to obtain the current device number and
the current secondary address from their respective tables.
3. If the current device is the keyboard, JMP F70D/F790 to
display the NOT OUTPUT FILE error message, set accu-
mulator to 7, set carry, and exit.
4. If the current device is the screen, store the device number
in 9A, the output device number, then CLC, and exit.
5. If the current device is a serial device, branch to F279/F332
to Open Serial Output Channel.
6. If the current device is an RS-232 device, JMP EFE1/F0BC
to Open RS-232 Output Channel.
7. If the current device is tape, the secondary address must not
be $60 (read tape). If the secondary address is $60, JMP to
NOT OUTPUT FILE error, set accumulator to 7, set carry,
and exit. If the secondary address is legal, set the output de-
vice number, 9A, to 1 (tape).
8. CLC and RTS.
$FFCF CHRIN Get a byte from input channel
**Called by**: JSR at E112/E10F in BASIC's Input a Character.
**Setup routines**: OPEN, CHKIN (not required in retrieving from keyboard).
JMP (0324) with default of F157/F20E.
If the current input device, 99, is tape, then return the
next byte from the tape buffer. Also, read one byte ahead to
see if the next byte is zero, indicating end of file, and if true,
set end-of-file status in 90.
If the current input device, 99, is a serial device, the accu-
mulator returns the byte received over the serial bus. How-
ever, if there are any I/O status errors, return with
accumulator set to $0D
If the current input device, 99, is RS-232, return with the
next character from the RS-232 receive buffer. However, if the
receive buffer is empty, the RS-232 routine on the VIC just
loops until the receive buffer contains a character. The VIC
can hang in an infinite loop if the RS-232 receive buffer never
gets another character. If the receive buffer is empty on the 64,
the routine returns with $0D in the accumulator.
If the current input device is the keyboard, each character
typed (except for control characters such as the cursor keys) is
displayed on the screen until the unshifted RETURN is en-
tered. Once an unshifted RETURN is typed, reset the input
routine to retrieve a character from this screen line. After each
character is retrieved from the screen line, increment the
pointer to the character being retrieved in this logical line. The
screen POKE code is converted to the equivalent ASCII code,
which is returned in the accumulator. If the end of the screen
line has been reached, then return $0D, the ASCII code for a
carriage return. The screen editor routines limit the size of a
logical line to 80/88 characters. The way this CHRIN from the
keyboard is typically used is to fill a buffer as BASIC does.
BASIC calls the CHRIN routine to fill the BASIC input buffer
at 0200. The BASIC routine keeps putting characters in the
buffer until CHRIN retrieves a carriage return (ASCII $0D).
If the current input device, 99, is the screen, then return
the ASCII code for the screen character in the current logical
line pointed to by D3, the column the cursor is on. D3 is then
incremented to point to the next character in the line. If D3
has reached the end of the line, return $0D signifying carriage
return, and set D0 to 0 to force the next CHRIN to come from
the keyboard.
When doing CHRIN from the keyboard, the keyboard
routine uses this CHRIN from the screen once the carriage re-
turn has been entered. After processing the screen characters,
the screen CHRIN then resets a flag at D0 to 0 to force input
from the keyboard for the next CHRIN.
**Exit conditions**: Accumulator holds byte returned from channel.
$F157 Determine Input Device F157/F20E-F178/F22F
**Called by**: Indirect JMP through (0324) from Kernal CHRIN vector at
FFCF.
Call the appropriate character input routine based on the
input device number, 99.
**Operation**:
1. If 99 is set to 0 (keyboard), save D3 in CA, save D6 in C9,
and JMP E632/E64F (see chapter 7) to receive a character
from the keyboard.
2. If 99 is set to 3 (screen), store 3 in DO, save D5 in C8, and
JMP E632/E64F (see chapter 7) to receive a character from
the screen.
3. If 99 is set to 2 (RS-232), branch to F1B8/F26F (see chapter
9) to receive a character from the RS-232 device.
4. If the value in 99 > 3 (serial), branch to F1AD/F264 (see
chapter 8) to receive a character from the serial device.
5. If 99 is set to 1 (tape), fall through to F179/F230 to receive
a character from tape.
$FFD2 CHROUT Send a byte to output channel
**Called by**: JSR at E10C/E109 in BASIC's Output a Character, JSR at
F135/F1EC in Display Kernal Message, JSR at F5C9/F661 in
Display Filename, JSR at F726/F7A9 in Error Message
Handler, JSR at F759/F7DC in Find Next Tape Header.
**Setup routines**: OPEN, CHKOUT (not required if output device is the screen).
**Entry requirements**: Accumulator should contain the character to be output, in
CBM ASCII. JMP (0326) with a default of F1CA/F27A.
If 9A, the current output device, is the screen (3), the
ASCII code is displayed on the screen unless the ASCII code is
a screen control function (cursor key, DELete, INSerT, and so
on). If the character is a control code, the routine performs the
action. If the ASCII code is a valid screen display code, the
code is displayed on the screen at the current cursor position
and then the cursor is advanced to the next position on the
screen.
If the current output device, 9A, is a serial device, (> 3),
then JMP EDDD/EEE4 to send the character to all open serial
devices. When sending a character to a serial device, a one-
byte buffer, 95, is maintained. If this buffer is empty, the
character to be output is simply stored in the buffer. If the
buffer already contains a character, the routine sends the
character from the buffer onto the serial bus and stores the
character to be output in the buffer. When the serial file is
closed or the serial device is commanded to unlisten, the final
byte in the buffer is sent.
If the current output device, 9A, is RS-232 (2), the charac-
ter to be output is stored in the RS-232 transmit buffer, and
transmission is started if this is the first byte to be sent.
If the current output device, 9A, is tape (1), store the
character in the currently available position in the tape buffer
and increment the index to the available position in the tape
buffer. Once the index is set to 192, write the tape buffer to
tape. Then set the first byte of the tape buffer to 2 (identifica-
tion for a data buffer) and reset the index to point to the sec-
ond byte of the tape buffer.
Although the character to be output is in ASCII code for
output to the screen, this is not the case for RS-232, serial, or
tape. For example, if you are storing bytes to tape containing a
code other than ASCII, CHROUT will send them to the tape
buffer. For the screen, though, the 64/VIC screen editor is set
up to convert ASCII codes to screen codes or screen functions,
and would not function well if you did not use ASCII.
$F1CA Determine Output Device F1CA/F27A-F1E4/F28E
**Called by**: Indirect JMP through (0326) from Kernal CHROUT vector at
FFD2.
Call the appropriate character output routine based on the
output device number, 9A.
**Operation**:
1. If the output device is the screen, JMP E716/E742 (see
chapter 7) to output a character to the screen.
2. If the output device is a serial device, JMP EDDD/EEE4 (see
chapter 8) to output a character to the serial device.
3. If the output device is an RS-232 device, branch to
F208/F2B9 (see chapter 9) to output a character to an RS-
232 device.
4. If the output device is tape, fall through to F1E5/F28F (see
chapter 10) to handle CHROUT to tape.
$FF81 CINT Initialize screen editor
**Called by**: None.
JMP FF5B to initialize the VIC-II (6567) chip registers,
clear the screen, set the cursor pointer, initialize the screen line
link table, set the PAL/NTSC flag, set value for CIA #1 timer
A, enable interrupts for CIA #1 timer A, and start timer A.
This Kernal jump instruction is only available on the 64.
The nearest equivalent on the VIC is to JSR E518 to set the
VIC (6560-6561) chip registers, clear the screen, set the cursor
pointers, and initialize the screen line link table. The 6560 and
6561 chips are, respectively, the NTSC and PAL versions of
the VIC's video chip. The VIC equivalent of CINT for enabling
the IRQ timer interrupt is to JMP FE39 to enable VIA #2 timer
1 interrupts and to set a timer 1 value.
Thus, a VIC version might be something like this:
JMP 02A1
02A1 JSR E518
02A4 JSR FE39
02A7 RTS
CINT, or its VIC equivalent, is only needed if you write
an autostart cartridge program and need to use the screen edi-
tor or IRQ timer A/timer 1 interrupts. If no autostart cartridge
exists, the 64/VIC performs the actions in CINT during system
reset.
$FFA8 CIOUT Send a byte to serial bus
**Called by**: None.
**Setup routines**: LISTEN, SECOND (if serial device requires a secondary
address)
**Entry requirements**: Accumulator should contain character to output. JMP EDDD/
EEE4 to execute the Send Serial Byte Deferred routine.
When sending a character to a serial device, the routine
maintains a one byte buffer at 95. If this buffer is empty, the
character to be output is simply stored in the buffer. If the
buffer already contains a character, the character from the
buffer is sent onto the serial bus and the character to be out-
put is stored in the buffer. When the serial file is closed or the
serial device commanded to unlisten, the final byte in the
buffer is sent. The character is sent to all open devices on the
serial bus.
$FFE7 CLALL Close all channels and files
**Called by**: JSR at A660/C660 in BASIC's CLR.
JMP (0322) with a default of F32F/F3EF.
Set 98, the number of currently open files, to 0.
If the current output device is a serial device, send an
UNLISTEN command on the serial bus.
If the current input device is a serial device, send an
UNTALK command on the serial bus.
Set 99, the current input device, to be the keyboard.
Set 9A, the current output device, to be the screen.
$F32F Reset to No Open Files F32F/F3EF-F332/F3F2
**Called by**: Indirect JMP through (032C) from Kernal CLALL vector at
FFE7.
Reset location 98, the number of open files, to zero and
fall through to F333/F3F3 to reset any open serial channels
and reset the default device numbers.
**Operation**:
1. Set 98, the number of open files, to 0.
2. Fall through to F333/F3F3, Clear Serial Channels and Reset
Default Devices routine.
$FFC3 CLOSE Close logical file
**Called by**: JSR at E1CC/E1C9 in BASIC's CLOSE
**Entry requirements**:
Accumulator should contain the number of the logical file to
be closed.
JMP(031C) with a default of F291/F34A.
If the logical file number in the accumulator is found in
the logical file number table, also retrieve the current device
number from the device number table and the secondary ad-
dress from the secondary address table.
Then, execute the appropriate CLOSE routine for this cur-
rent device.
If accessing a serial device, for secondary addresses < 128
(decimal), command the current device to LISTEN, send a
CLOSE secondary address, and command the serial device to
UNLISTEN. For secondary addresses > 128, this close se-
quence is omitted.
For an RS-232 device, bring the transmitted data line
high, which is the idle state for RS-232 communications. Also,
reset the pointers to the end of memory by reclaiming the
space used for the RS-232 transmit and receive buffers.
When closing a logical tape file, determine whether writ-
ing to or reading from tape. If writing to tape then store a final
byte of 0 in the tape buffer and write the buffer to tape.
For all types of devices, a common CLOSE exit is used.
The number of open files, 98, is decremented, and the entry for
this logical file is deleted from the logical file number table, the
device number table, and the secondary address table.
$F291 Determine Device for CLOSE F291/F34A-F2AA/F363
**Called by**: Indirect JMP through (031C) from Kernal CLOSE vector at
FFC3.
Upon entry, the accumulator contains the logical file num-
ber to be closed. First, it calls a routine to determine if the
logical file number is in the logical file number table. If the
number is not in the table, then it will exit with carry clear. If
the number is in the table, then it will retrieve the current de-
vice number and secondary address corresponding to this file.
Push the current index into the tables corresponding to
the logical file number onto the stack. Determine the type of
device the logical file is using and branch to the appropriate
routine for closing screen, keyboard, serial, or tape devices, or
fall through to following code for closing RS-232 devices.
**Entry requirements**:
Accumulator should contain the number of the logical file to
be closed.
**Operation**:
1. JSR F314/F3D4 to see if the logical file number is in the
logical file number table. Return with X as the index into
table corresponding to this logical file if it exists; return with
Z = 1 (detected with BEQ) if the logical file is found.
2. If the file is not found CLC and RTS.
3. If the file is found, then JSR F31F/F3DF to retrieve the cur-
rent device number, BA, the current secondary address, B9,
and the current logical file number, B8, from the tables for
these with entries corresponding to the location of current
logical file number in the logical file number table.
4. Transfer index into tables to accumulator and push on stack
for later retrieval by the individual CLOSE routines for RS-
232 and serial devices.
5. If current device is the keyboard or screen, branch to
F2F1/F3B1 to decrement number of open files and remove
current file entry from the three tables.
6. If current device is a serial device, branch to F2EE/F3AE for
a JMP to the routine to close a serial device.
7. If current device is tape, branch to F2C8/F38D to close tape
files.
8. If current device is RS-232, fall through to the routine at
F2AB/F364 to close an RS-232 device.
$F2F1 Common Exit for Close Logical File Routines F2F1/F3B1-F30E/F3CE
**Called by**: Falls through after JSR to Close Logical File for Serial Device
at F2EE/FEAE, BEQ at F29F/F358 and F2A3/F35C in Deter-
mine Device to Close, BEQ at in F2CC/F391 Close Logical File
for Tape, BNE at F2E4/F3A4 in Close Logical File for Tape ,
JMP at F2EB/F3AB in Close Logical File for Tape; alternate en-
try at F2F2/F3B2 by JSR at F2AC/F365 in Close Logical File
for RS-232 Device.
The index into the file tables for the current logical file is
retrieved from the stack (except for the alternate entry from
RS-232 which has already pulled it from the stack).
The number of open files, 98, is decremented and com-
pared to the index into the file tables. If equal, the current
logical file is the last entry in the file table. In this case, there
is no need to delete the actual entries in the tables since the
pointer to the tables will now cause the next OPEN to over-
write these entries.
If the current logical file index is not equal to the number
of open files (after the decrement), replace the current entries
of the logical file number, device number, and secondary ad-
dress tables with the last entries in the table. As the order
within a particular table is unimportant, this rearrangement
effectively deletes the current entries for the logical file, de-
vice, and secondary address.
Entry conditions:
Index into file tables for current logical file is pulled from the
stack at entry.
**Operation**:
1. Pull index into file tables for current logical file from stack.
2. Transfer the index into the tables to X register.
3. Decrement the number of open files (plus one), location 98.
4. If X register equals the value in 98, the logical file being
closed is the last entry in the tables. Since 98 points to the
next available space in the tables, the next OPEN will over-
write the entries for this current logical file. Thus, just CLC
and RTS.
5. If the number of open files (plus one) after decrement is not
equal to the value in the X register, the current logical file
being closed is not the last entry in the table. In this case,
move the last entries in the three tables (device number,
secondary address, logical file number) to the current logical
file entries. Before this move,the last entry is pointed to by
98 and the current entry by the X register.
6. CLC and RTS.
$FFCC CLRCH Reset I/O channels
**Called by**: JSR at A447/C447 in BASIC's Error Message Handler, JSR at
ABB7/CBB7 in BASIC's INPUT#, JSR at E37B/E467 in BA-
SIC's Warm Start, JSR at F6F4/F777 in Test for STOP Key, JSR
at F716/F799 in Error Message Handler.
JMP(0322) with a default of F333/F3F3.
If the current output device is a serial device, send an
UNLISTEN command on the serial bus. If the current input
device is a serial device, send an UNTALK command on the
serial bus.
Set 99, the current input device, to be the keyboard.
Set 9A, the current output device, to be the screen.
$F333 Clear Serial Channels and Reset Default Devices F333/F3F3-F349/F409
**Called by**: Indirect JMP through (0322) from Kernal CLRCHN vector at
FFCC, fall through from F331/F3F1 in Reset to No Open Files.
**Operation**:
1. If the current output device is a serial device, JSR
EDFE/EF04 to command the serial device to unlisten.
2. If the current input device is a serial device, JSR
EDEF/EEF6 to command the serial device to untalk.
3. Reset 9A, the current output device, to the screen (3).
4. Reset 99, the current input device, to the keyboard (0).
$FFE4 GETIN Retrieve character from channel
**Called by**: JSR at E121 in BASIC's Get a Character.
**Setup routines**: OPEN, CHKIN
JMP(032A) with a default of F13E/F1F5.
When retrieving characters from the keyboard, if any
characters are in the keyboard buffer, the first character (an
ASCII value) in the buffer is returned in the accumulator, and
the rest of the characters are moved up one position in the
buffer. If no characters are in the keyboard buffer, return with
accumulator cleared to 0.
You would use GETIN to retrieve the first character in the
keyboard buffer. Contrast this to CHRIN, which does not re-
trieve anything until RETURN is entered, then returns a
character from the logical screen line.
If retrieving from device 2, RS-232, see if the RS-232 re-
ceive buffer contains any characters. If it is empty, return with
accumulator set to 0. If it contains characters, return with
accumulator containing next character in the receive buffer and
increment the pointer into the receive buffer.
If retrieving from channel 3 (the screen), channels >= 4
(serial devices), or channel 1 (tape), do the same routines for
GETIN that CHRIN does for these devices.
For screen GETIN, return the ASCII code for the screen
character in the current logical line pointed to by D3, the col-
umn the cursor is on. D3 is then incremented to point to the
next character in the line. If D3 is on the end of the line, re-
turn the ASCII code $0D for return.
For serial GETIN, the accumulator returns the byte re-
ceived over the serial bus. However, if any I/O status errors
occur, return with accumulator containing $0D.
For tape GETIN, return the next byte from the tape buffer.
Also, read one byte ahead to see if the next byte is zero, in-
dicating end of file, and if true, set end-of-file status in 90.
$F13E GETIN Preparation F13E/F1F5-F14D/F204
**Called by**: Indirect JMP through (032A) from Kernal GETIN vector at
FFE4.
This routine first determines if the current input device is
the keyboard. If not, GETIN falls through to F14E/F205 for an
RS-232 device or branches to F166/F21D for other devices
using the same routines as are used by CHRIN.
If the current input device is the keyboard and if the key-
board buffer contains characters, JMP E5B4/E5CF to retrieve
the first character from the keyboard buffer.
**Operation**:
1. If 99, the current input device, is not 0 (the keyboard),
branch to step 5.
2. If 99 is 0 for the keyboard, see if any characters are in the
keyboard buffer as indicated by C6, the number of charac-
ters in the keyboard buffer.
3. If no characters are in the keyboard buffer, just CLC and
RTS, thus returning with the accumulator set to 0.
4. If characters do exist in the keyboard buffer, disable IRQ
interrupts and JMP E5B4/E5CF to retrieve the first character
from the keyboard buffer and exit.
5. If the current input device, 99, is 2 for RS-232, fall through
to F14E/F205 for the routine to get characters from RS-232.
6. If the current input device is neither 0 nor 2, branch to
F166/F21D to get a character from other devices. F166/F21D
is located in the Determine Input Device routine used by
CHRIN; thus, other devices (tape, screen, serial) perform
the same routines for both GETIN and CHRIN.
$FFF3 IOBASE Return base address of I/O registers
**Called by**: JSR at E09E/E09B BASIC's in RND
JMP E500.
This routine returns (to the X and Y registers) the address
of the start of the I/O registers that control the 6526
CIA/6522 VIA chips. You can write programs that refer to the
I/O registers without knowing the exact address of the I/O
register. To write a program in this manner, you would call
IOBASE to get the starting address of the I/O registers and
add an index to the particular I/O register to which you are
referring.
IOBASE for the VIC returns with X register set to $10 and
Y register set to $91 (the address of the first register of VIA #1
is 9110). IOBASE for the 64 returns with X register set to $00
and Y register set to $DC (the address of the first register of
CIA #1 is DC00). By calling IOBASE, you can determine both
the starting address of the I/O registers and which computer
the program is running on. Thus, your program could test
which computer it is running on and read or write to the
appropriate I/O register for this computer, giving you the abil-
ity to write one program that works on both the 64 and the
VIC. You still will have to know what the CIA/VIA registers
do and how to modify them, since what works for a VIA reg-
ister does not necessarily work the same way on the
corresponding CIA register.
BASIC's RND uses this routine to access the CIA/VIA
timer registers in generating a random number.
$FF84 IOINIT Initialize I/O devices
**Called by**: None.
JMP FDA3 to initialize the CIA registers, the 6510 I/O
data registers, the SID chip registers, start CIA #1 timer A, en-
able CIA #1 timer A interrupts, and set the serial clock output
line high.
The closest equivalent to this routine on the VIC is JMP
FDF9 to initialize the 6522 registers, set VIA #2 timer 1 value,
start timer 1, and enable timer 1 interrupts.
Since these routines are called during system reset, the
main use for IOINIT is for an autostart cartridge that wants to
use the same I/O settings that the Kernal normally uses.
$FFB1 LISTEN Send listen with attention to serial devices
**Called by**: None.
JMP ED0C/EE17.
At ED0C/EE17 the accumulator, which contains the de-
vice number, is ORed with $20, turning on bit 5 to prepare to
send a LISTEN command on the serial data output line. The
device number should be 0-31 (decimal). (If you specify a
value > 31, you mess up the high nybble which is used for
sending commands on the serial bus.)
RS-232 interrupts are disabled.
Finally, the LISTEN command for this device is sent on
the serial bus. To send the LISTEN, the 64/VIC brings the se-
rial attention output line low to cause all devices on the serial
bus to listen for a command coming on the bus.
$FFD5 LOAD LOAD/VERIFY to RAM
**Called by**: JSR at E175/E172 in BASIC's LOAD /VERIFY.
**Setup routines**: SETLFS, SETNAM
**Entry requirements**:
Accumulator should be set to 0 for LOAD; accumulator set to
1 for VERIFY.
If relocatable load desired: Set X register to the low byte
of load starting address, and Y register to the high byte of load
starting address.
JMP F49E/F542 to store the X register and Y register in
(C3), the starting address of the load, and then JMP(0330)
with a default of F4A5/F549.
At F4A5/F549, determine the device. The keyboard,
screen, and RS-232 are illegal devices.
For a serial device you must specify a filename. If you
don't, the MISSING FILE NAME error message is displayed.
With a valid filename, the computer commands the current se-
rial device to listen and sends the secondary address of $60,
indicating a load, followed by the filename. Then it tells the
device to unlisten. Next, it tells the current serial device to
talk, sends the current secondary address of $60, and receives
a byte from the serial bus. If the I/O status word indicates the
byte was not returned fast enough, a read time-out has oc-
curred and the FILE NOT FOUND error message is displayed.
The first two bytes received from the serial device are used as
a pointer to the start of the load area (AE). However, if a
secondary address of 0 is specified at entry to load, the X and
Y registers stored in (C3) at entry are used as the starting ad-
dress of the load—thus providing for a relocatable load. Then
it receives bytes from the serial bus and stores or verifies them
until the EOI status is received. Once the EOI status is re-
ceived, the serial device is commanded to untalk, and the se-
rial device sends the last buffered character. The serial device
then is sent a CLOSE and told to untalk.
For tape LOAD/VERIFY, the LOAD routine first checks if
the tape buffer is located in memory >= 0200. If so, it loads
the tape buffer with a header retrieved from the tape. If a file-
name has been specified, a specific he,ader with this filename
is loaded; if there is no filename, it loads the next header on
the tape. Only tape headers with tape identifiers of 1 or 3 are
acceptable for LOAD/VERIFY. A tape identifier of 5 indicates
an end-of-tape header, and in this case the routine will exit
with carry set and accumulator set to 5. Tape identifiers of 2 or
4 are for sequential files.
A tape identifier of 3 causes a nonrelocatable load even if
you have specified values in the X and Y registers at entry and
a secondary address of 0. That is, you can't override a tape
identifier of 3—it forces a nonrelocatable load.
A tape identifier of 1 allows a relocatable load. If the tape
identifier is 1 and the secondary address is 0, the X and Y reg-
ister values at entry are used to determine the starting address
for the load.
For a nonrelocatable load, the starting address for the load
is taken from the tape header. The ending address for the load
(in both relocatable and nonrelocatable loads) is determined
by adding the length of the program to the starting address.
After determining whether to do a relocatable or non-
relocatable load, it loads RAM from the next two program
blocks on tape (two blocks are used for error correcting pur-
poses; they should be identical copies of each other).
$F49E Jump to LOAD Vector F49E/F542-F4A4/F548
**Called by**: JMP from Kernal LOAD vector at FFD5.
The starting address for a possible relocatable load, speci-
fied in the X and Y registers at entry, is stored in (C3), fol-
lowed by JMP (0330) with the default vector of F4A5/F549.
**Operation**:
1. STX C3.
2. STY C4.
3. JMP(0330).
$F4A5 Determine Device for LOAD F4A5/F549-F4B7/F55B and F533/F5CA-F538/F5D0
**Called by**: Indirect JMP through (0330) at F4A2/F546 in Jump to LOAD
Vector.
This routine determines which device is being used for
the load. Invalid devices are the screen, keyboard, or RS-232.
Valid devices are serial devices or tape, and for these the rou-
tine passes control to the appropriate serial or tape load
routine.
**Operation**:
1. STA 93, thus setting the LOAD/VERIFY flag to 0 for LOAD
or to 1 for VERIFY.
2. Reset 90, the I/O status, to 0.
3. LDA from BA, the current device number.
4. If the current device is the keyboard (0) or the screen (3),
JMP F713/F796 to display the ILLEGAL DEVICE NUMBER
error message.
5. If the current device number is less than 3, branch to step 7.
6. If the current device number is greater than 3, it's a serial
device. Fall through to F4B8/F55C to load from a serial
device.
7. If the current device is RS-232, JMP F713/F0B9 to display
ILLEGAL DEVICE NUMBER.
8. If the current device number is not 2 (RS-232), the only
number left is 1 (tape). Fall through to F539/F5D1 to load
from tape.
$FF9C MEMBOT Read or set the start-of-memory pointer
**Called by**: JSR at E403/E3E5 in BASIC's Cold Start.
**Entry requirements**:
Carry should be set or clear, depending on function desired:
Set carry to read bottom of memory.
Clear carry to set bottom of memory. The X register is the
low byte of the address of the bottom of memory, and the Y
register is the high byte of the address of the bottom of
memory.
JMP FE34/FE82.
If the carry is clear at entry, set the pointer to bottom of
memory (0281) from X and Y registers.
If the carry is set at entry, load X and Y registers from
(0281), the pointer to the bottom of memory.
The initial values of (0281) are 1000 for an unexpanded
VIC, 0400 for a VIC with 3K expansion, 1200 for a VIC with
8K or more expanded, and 0800 for the 64.
$FE34 MEMBOT Execution FE34/FE82-FE42/FE90
**Called by**: JMP from Kernal MEMBOT vector at FF9C.
If the carry is clear at entry, set (0281), the pointer to the
bottom of memory, from the X and Y registers. If carry is set at
entry, load X and Y registers from (0281).
**Operation**:
1. If carry is clear, branch to step 3.
2. Load X and Y registers from pointer to bottom of memory
(0281), and fall through to step 3.
3. Set (0281) from values in X and Y registers.
4. RTS.
$FF99 MEMTOP Read or set the end-of-memory pointer
**Called by**: JSR at E40B/E3ED in BASIC's Cold Start.
**Entry requirements**:
Carry should be set or clear, depending on function desired:
Set carry to read end of memory.
Clear carry to set end of memory. The X register contains
the low byte of the address of the start of memory, and the Y
register contains the high byte of the address of the start of
memory.
JMP FE25/FE73.
If carry is clear at entry, set pointer to top of memory
(0283) from X and Y registers.
If carry is set at entry, load X and Y registers from (0283),