-
Notifications
You must be signed in to change notification settings - Fork 78
/
kernal_mlr.txt
957 lines (800 loc) · 55 KB
/
kernal_mlr.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
- C64 KERNAL API (Machine Language Routines)
-
- Heimarck, Todd D; Parrish, Patrick:
- Machine Language Routines for the Commodore 64 and 128
- ISBN 0874550858
-
- 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 ACPTR
This low-level I/O routine retrieves a byte from a serial device
without checking for a previous I/O error. If the operation is
successful, the accumulator will hold the byte received from
the device. The contents of .X and .Y are preserved. The suc-
cess of the operation will be indicated by the value in the se-
rial status flag upon return. (See READST for details.)
For the routine to function properly, the serial device
must currently be a talker on the serial bus, which requires a
number of setup steps. Generally, it's preferable to use the
higher-level CHRFN routine instead.
$FFC6 CHKIN CHKIN
This routine specifies a logical file as the source of input in
preparation for using the CHRIN or GETIN routines. The logi-
cal file should be opened before this routine is called. (See the
OPEN routine.) The desired logical file number should be in
.X when this routine is called. The contents of .Y are un-
affected, but the accumulator value will be changed.
The routine sets the input channel (location $99) to the
device number for the specified file. If the device is RS-232
(device number 2), the CIA #2 interrupts for RS-232 reception
are enabled. Ef a serial device (device number 4 or greater) was
specified, the device is made a talker on the serial bus,
If the file is successfully set for input, the status-register
carry bit will be clear upon return. If carry is set, the operation
was unsuccessful and the accumulator will contain a Kernal
error-code value indicating which error occurred. Possible er-
ror codes include 3 (file was not open), 5 (device did not re-
spond), and 6 (file was not opened for input). The RS-232 and
serial status-flag locations also reflect the success of operations
for those devices. (See READST for details.)
The JMP to the CEDGN execution routine is by way of the
ICHKDN indirect vector at 798-799 ($031E-$031F). You can
modify the actions of CHfQN by changing the vector to point
to a routine of your own.
$FFC9 CHKOUT CHKOUT
This routine (some Commodore references call it CKOUT)
specifies a logical file as the recipient of output in preparation
for using the CHROUT routine. The logical file should be
opened before this routine is called. (See the OPEN routine.)
The desired logical file number should be in .X when this rou-
tine is called. The contents of .Y are unaffected, but the accu-
mulator will be changed.
The routine sets the output channel (location $9A) to the
device number for the specified file. If the device is RS-232
(device number 2), the routine also enables the CLA #2 inter-
rupts for RS-232 transmission. fi a serial device (device num-
ber 4 or greater) is specified, the device is also made a listener
on the serial bus.
If the file is successfully set for output, the status-register
carry bit will be clear upon return. If the carry is set, the op-
eration was unsuccessful, and the accumulator will contain a
Kernal error-code value indicating which error occurred. Pos-
sible error codes include 3 (file was not open), 5 (device did
not respond), and 7 (file was not opened for output). The RS-
232 and serial status-flag locations also reflect the success of
operations for those devices. (See READST for details.)
The JMP to the CHKOUT execution routine is by way of
the ICKOUT indirect vector at $0320-$0321. You can modify
the actions of the routine by changing the vector to point to a
routine of your own.
$FFCF CHRIN CHRIN
This high-level I/O routine (some Commodore references may
call it BASIN) receives a byte from the logical file currently
specified for input (to change the default input device, see
CHKIN above). Except to use the routine to retrieve input
from the keyboard when the system is set for default I/O, you
must open a logical file to the desired device and specify the
file as the input source before calling this routine. (See the
OPEN and CHKIN routines.)
For keyboard input (device 0), the routine accepts
keypresses until RETURN is pressed, and then returns charac-
ters from the input string one at a time on each subsequent
call. The character code for RETURN, 13, is returned when the
end of an input string is reached. (The Kernal GETIN routine
is better for retrieving individual keypresses.)
For tape (device 1), the routine retrieves the next character
from the cassette buffer. If all characters have been read from
the buffer, the next data block is read from tape into the
buffer.
For RS-232 (device 2), the routine returns the next avail-
able character from the RS-232 input buffer. If the buffer is
empty, the routine waits until a character is received—unless
the RS-232 status flag indicates that the DSR signal from the
external device is missing, in which case a RETURN character
code, 13, is returned.
CHRIN from the screen (device 3) retrieves characters one
at a time from the current screen line, ending with a RETURN
character code when the last nonspace character on the logical
line is reached. (Note that CHRIN from the screen does not
work properly in the original version of the 128 Kernal.) For
serial devices (device numbers 4 and higher), the routine re-
turns the next available character from the serial bus, unless
the serial status flag contains a nonzero value. In that case, the
RETURN character code is returned.
For all input devices, the received byte will be in the
accumulator upon return. The contents of .X and .Y are pre-
served during input from the keyboard, screen, or RS-232. For
input from tape, only .X is preserved. For input from serial de-
vices, only .Y is preserved. For input from the screen, key-
board, or serial devices, the status-register carry bit will always
be clear upon return. For tape input, the carry bit will be clear
unless the operation was aborted by pressing the RUN/STOP
key. For tape, serial, or RS-232 input, the success of the opera-
tion will be indicated by the value in the status-flag location.
(See the entry for READST.) The RS-232 portion of the orig-
inal 128 version of CHRRsJ has a bug: The carry bit will be set
if a byte was successfully received, and will be clear only if
the DSR signal is missing—the opposite of the settings for the
64. It's better to judge the success of an RS-232 operation by
the value in the status-flag location rather than by the carry-
bit setting. (See the READST routine.)
TheJMP to the CHREN execution routine is by way of the
ICHRfN indirect vector at $0324-$0325. You can modify the
actions of the routine by changing the vector to point to a rou-
tine of your own.
$FFD2 CHROUT CHROUT
This routine (some Commodore references call it BSOUT)
sends a byte to the logical file currently specified for output.
Except to send output to the screen when the system is set for
default I/O, you must open a logical file to the desired device
and specify the file as the output target before calling this rou-
tine. (See the OPEN and CHKOUT routines.)
For output to tape (device 1), the character is stored at the
next available position in the cassette buffer. When the buffer
is full, the data block is written to tape.
For output to RS-232 (device 2), the character is stored in
the next available position in the RS-232 output buffer, if the
buffer is full, the routine waits until a character is sent.
For output to the screen (device 3), the character is
printed at the current cursor position. For serial devices (device
numbers 4 and higher), the CIOUT routine is called.
Regardless of the output device, the contents of the accu-
mulator, .X, and .Y are preserved during this routine. The
status-register carry bit will always be clear upon return, un-
less output to tape is aborted by pressing the RUN/STOP key.
(In that case, the accumulator will also be set to 0, setting the
status-register Z bit as well.) For tape, serial, or RS-232 output,
the success of the operation will be indicated by the value in
the status flag. (See READST for details.)
The JMP to the CHROUT execution routine is by way of
the ICHROUT indirect vector at $0326-$0327. You can modify
the actions of the routine by changing the vector to point to a
routine of your own.
$FF81 CINT CINT
This routine initializes all RAM locations used by the screen
editor, returning screen memory to its default position and set-
ting default screen and border colors. The routine also clears
the screen and homes the cursor. All processor registers are
affected.
For the 64 only, this routine initializes all VIC chip reg-
isters to their default values (that's done during the Kernal
IOINIT routine in the 128). For the 128, CINT clears both dis-
plays and redirects printing to the display indicated by the po-
sition of the 40/80 DISPLAY key. The 128 routine also sets
SID volume to zero and resets programmable function keys to
their default definitions. It does not, however, reinitialize the
80-column character set. (That's also part of IOINIT.)
$FFA8 CIOUT CIOUT
This low-level I/O routine sends a byte to a serial device. The
accumulator should hold the byte to be sent. All register val-
ues are preserved. The success of the operation will be in-
dicated by the value in the serial status flag. (See READST for
details.)
For the routine to function properly, the target serial de-
vice must currently he a listener on the serial bus, which re-
quires a number of setup steps. However, if you have already
performed all the preparatory steps necessary for CHROUT to
a serial device, then you can freely substitute CIOUT for
CHROUT, since, for a serial device, CHROUT simply jumps to
the CIOUT routine.
$FFE7 CLALL CLALL
This routine resets the number of open files (location $98) to
zero, then falls through into the CLRCH routine to reset de-
fault t/O. The contents of .A and .X are changed, but .Y is
unaffected.
Despite its name, the routine doesn't actually close any
files that may be open to tape, disk, or RS-232 devices. Un-
closed files may cause problems, particularly on disks, so this
routine is of limited usefulness. The 128 Kernal provides an
alternate routine that does properly close all files open to a se-
rial device. (See CLOSE_ALL.)
The JMP to the CLALL execution routine is by way of the
JCLALL indirect vector at $032C-$032D. You can modify the
actions of the routine by changing the vector to point to a rou-
tine of your own.
$FFC3 CLOSE CLOSE
This routine closes a specified logical file. Call the routine with
the accumulator holding the number of the logical file to be
closed. If no file with the specified logical file number is cur-
rently open, no action is taken and no error is indicated. If a
file with the specified number is open, its entry in the logical
file number, device number, and secondary address tables will
be removed. For RS-232 files, the driving CLA #2 interrupts will
also be disabled. For tape files, the final block of data will be
written to tape (followed by an end-of-tape marker, if one was
specified). For disk files, the EOI sequence will be performed.
The 128 version of the routine offers a special close func-
tion for disk files: Ff this routine is called with the status-
register carry bit set, and if the device number for the file is 8
or greater, and if the file was opened with a secondary address
of 15, then the EOI sequence is skipped. (The table entries for
the file are deleted, but that's all.) This solves a problem in
earlier versions of the Kernal for disk files opened with a
secondary address of 15, the command channel to the drive.
An attempt to close the command channel will result in an
EOI sequence that closes all files currently open to the drive,
not just the command-channel file, This special mode allows
the command-channel file to be closed without disturbing
other files that may be open to the drive.
The JMP to the CLOSE execution routine is by way of the
ICLOSE indirect vector at $031C-$031D. You can modify the
actions of the routine by changing the vector to point to a rou-
tine of your own.
$FFCC CLRCHN CLRCHN
This routine restores the default I/O sources for the operating
system. The output channel (location $9A) is reset to device 3,
the video display. (If the previous output channel was a serial
device, it is sent an UNLISTEN command.) The input channel
(location $99) is reset to device 0, the keyboard, (if the pre-
vious input channel was a serial device, it is sent an UNTALK
command.) The contents of .X and .A are changed, but .Y is
unaffected.
The JMP to the CLRCHN execution routine is by way of
the lCLRCH indirect vector at $0322-$0323. You can modify
the actions of the routine by changing the vector to point to a
routine of your own.
$FFE4 GETIN GETIN
This routine retrieves a single character from the current input
device. The routine first checks to see whether the input de-
vice number is 0 (keyboard) or 2 (RS-232). If it's not either of
these, the Kernal CHRIN routine is called instead. For key-
board or RS-232, the retrieved character will be in the accu-
mulator upon return, and the status-register carry bit wall be
clear. If no character is available, the accumulator will contain
0. (CHREM, by contrast, will wait for a character.) The contents
of .Y are unaffected, but .X will be changed. For RS-232, bit 3
of the status flag will also be set if no characters are available.
(See READST for details.)
The JMP to the GETIN execution routine is by way of the
IGETIN indirect vector at $032A-$032B. You can modify the
actions of the routine by changing the vector to point to a rou-
tine of your own.
$FFF3 IOBASE IOBASE
This routine returns a constant 1/0 chip base-address value in
.X (low byte) and .Y (high byte). The accumulator is un-
affected. For the 64, the value returned is $DC00—the address
of CLA #1. For the 128, the value is $D000—the address of
the VIC chip.
$FF84 IOINIT IOINIT
This routine initializes the CIA chips' registers to their default
values, along with related RAM locations. All processor reg-
isters are affected. For the 128, the routine also initiatizes the
VIC and VDC chip registers (a step which is part of the Kernal
CINT routine on the 64). In addition, the 128 routine sets all
SID chip registers to zero and calls the Kernal DLCHR routine
to initiahze the character set for the 80-column chip.
$FFB1 LISTEN LISTEN
This low-level serial I/O routine sends a LISTEN command to
a specified serial device. Call the routine with the accumulator
holding the device number (4-31) of the serial device to re-
ceive the command. The contents of .A and .X will be changed;
.Y is unaffected. The success of the operation will be indicated
by the value in the serial status flag upon return. (See
READST for details.)
$FFD5 LOAD LOAD
This routine loads a program file from tape or disk into a
specified area of memory, or verifies a program file against the
contents of a specified area of memory. A number of prepara-
tory routines must be called before LOAD: SETLFS, SETNAM,
and (for the 128 only) SETBNK. See the discussions of those
routines for details.
SETLFS establishes the device number and secondary ad-
dress for the operation. fThe logical file number isn't significant
for loading or verifying.) The secondary-address value deter-
mines whether the load/verify will be absolute or relocating.
If bit 0 of the secondary address is %0 (if the value is 0 or any
even number, for example), a relocating load will be performed:
The file will be loaded starting at the address specified in .X
and .Y. If the bit is %1 (if the value is 1 or any odd number,
for example), an absolute load will be performed: The data
will be loaded starting at the address specified in the file itself.
For tape files, the secondary-address specification can be over-
ridden by the file's internal type specification. Nonrelocatable
tape program files always load at their absolute address,
regardless of the secondary address.
When calling the LOAD routine, the accumulator should
hold the operation type value (0 for a load, or any nonzero
value for a verify). If the secondary address specifies a relocat-
ing load, the starting address at which data is to be loaded
should be stored in .X (low byte) and .Y (high byte). The val-
ues of .X and .Y are irrelevant for an absolute load.
The status-register carry bit will be clear upon return if
the file was successfully loaded, or set if an error occurred or if
the RUN/STOP key was pressed to abort the load. When
carry is se t upon return, the accumulator will hold a Kernal er-
ror-code value indicating the problem. Possible error codes in-
clude 4 (file was not found), 5 (device was not present), 8 (no
name was specified for a serial load), 9 (an illegal device num-
ber was specified).
On the 128 only, the load will be aborted if it extends be-
yond address $FEFF. This prevents corruption of the MMU
configuration register at $FFQ0. Ln this case, an error code of
16 will be returned. The success of the operation will also be
indicated by the value in the tape/serial status flag. (See
READST for details.)
$FF9C MEMBOT MEMBOT
See MEMTOP.
$FF99 MEMTOP MEMTOP
These routines read or set the Kernal's bottom-of-memory
pointer and top-of-memory pointer, respectively. (The bottom-
of-memory pointer is at locations $0281-$0282 for the 64 or
$0A05-$0A06 for the 128; the top-of-memory pointer is at
locations $0283-$0284 for the 64 or $0A07-$0A08 for the
128.) To read the pointer, call the routine with the carry flag
set; the pointer value will be returned in .X (low byte) and .Y
(high byte). To set the pointer, call the routine with the carry
flag clear and with .X and .Y containing the low and high
bytes, respectively, of the desired pointer value.
$FFC0 OPEN OPEN
This routine opens a logical file to a specified device in
preparation for input or output. At least one preparatory step
is required before the standard OPEN routine is called:
SETLFS must be called to establish the logical file number, de-
vice number, and secondary address, For tape (device 1), RS-
232 (device 2), or serial (device 4 or higher), SETNAM is also
required to specify the length and address of the associated
filename. Tor the 128, SETBNK must be called to establish the
bank number where the filename can he found.
It is not necessary to load any registers before calling
OPEN, and all processor register values may be changed dur-
ing the routine. The carry will be clear if the file was success-
fully opened, or it will be set if it could not be opened. When
carry is set upon return, the accumulator will hold an error
code indicating the problem. Possible error-code values in-
clude 1 (ten files—the maximum allowed—are already open),
2 (a currently open file already uses the specified logical file
number), and 5 (specified device did not respond). The RS-232
and tape/serial status flags will also reflect the success of the
operation for those devices, (See READST for details.)
On the 128, there is an exception to the carry-bit rule. Be-
cause of a bug in the 128's RS-232 OPEN routine, carry will
be set if the RS-232 device is present when x-line handshaking
is used (if the DSR line is high), or clear if the device is ab-
sent—the opposite of the proper setting.
The JMP to the OPEN execution routine is by way of the
IOPEN indirect vector $031A-$031B. You can modify the ac-
tions of the routine by changing the vector to point to a rou-
tine of your own,
$FFF0 PLOT PLOT
This routine reads or sets the cursor position on the active dis-
play, if it is called with the status-register carry bit clear, the
value in .X specifies the new cursor row (vertical position),
and the value in .Y specifies the column (horizontal position).
The carry bit will be set upon return if the specified column or
row values are beyond the right or bottom margins of the cur-
rent output window, or it will be clear if the cursor was
successfully positioned.
If the routine is called with the carry bit set, the row num-
ber for the current cursor position is returned in .X and the
current column number is returned in .Y. For the Commodore
128, the cursor position will be relative to the home position
of the current output window rather than to the upper left cor-
ner of the screen. Of course, in the case of a full-screen output
window—the default condition—the upper left comer of the
screen is the home position of the window,
$FF87 RAMTAS RAMTAS
This routine clears zero-page RAM (locations $02-$FF) and
initializes Kernal memory pointers in zero page. For the 64
only, the routine also clears pages 2 and 3 (locations
$0200-$03FF), tests all RAM locations from $0400 upwards
until ROM is encountered, and sets the top-of-memory
pointer. For the 128, the routine sets the BASIC restart vector
($0A00) to point to BASIC's cold-start entry address, $4000.
$FFDE RDTIM RDTIM
This routine returns the current value of the jiffy dock. The
dock value corresponds to the number of jiffies (1 /60-second
intervals) that have elapsed since the system was turned on or
reset, or the number of jiffies since midnight if the dock value
has been set. The low byte of the clock value (location $A2) is
returned in .A, the middle byte (location $A1) in .X, and the
high byte loocation $A0) in .Y.
$FFB7 READST READST
This routine (some Commodore references call it READSS) re-
turns the status of the most recent I/O operation. The status
value will be in the accumulator upon return; the contents of
.X and .Y are unaffected. If the current device number is 2 (in-
dicating an RS-232 operation), the status value is retrieved
from the RS-232 status flag (location $0297 for the 64 or
$0A14 for the 128), and the flag is cleared. Otherwise, the sta-
tus value is retrieved from the tape/serial status flag (location
$90). That flag is not cleared after being read.
| Bit | Value | Meaning if set Serial | Meaning if set Tape | Meaning if set RS-232 |
|-----|---------|-----------------------|---------------------------------------|--------------------------|
| 0 | 1/$01 | write timeout | | parity error |
| 1 | 2/$02 | read timeout | | framing error |
| 2 | 4/$04 | | short block | receiver buffer overflow |
| 3 | 8/$08 | | long block | receiver buffet empty |
| 4 | 16/$10 | verify mismatch | unrecoverable read or verify mismatch | CTS missing |
| | | | | |
| 5 | 32/$20 | | checksum mismatch | |
| 6 | 64/$40 | EOI (end of file) | end of file | DSR missing |
| 7 | 128/$80 | device nol present | end of tape | break |
$FF8A RESTOR RESTOR
This routine resets the Kernal indirect vectors ($0314-$0333)
to their default values. All processor registers are affected.
$FFD8 SAVE SAVE
This routine saves the contents of a block of memory to disk
or tape. It could be a BASIC or ML program, but it doesn't
have to be. A number of preparatory routines must be called
first: SETLFS, SETNAM, and (for the 128 only) SETBNK. See
the discussions of those routines for details.
SETLFS establishes the device number and secondary ad-
dress for the operation. (The logical file number isn't signifi-
cant for saving.) The secondary address is irrelevant for saves
to serial devices, but for tape it specifies the header type. If bit
0 of the secondary address value is %1 (if the value is 1, for
example), the data will be stored in a nonrelocatable file—one
that will always load to the same memory address from which
it was saved. Otherwise, the data will be stored in a file that
can be loaded to another location. If bit 1 of the secondary ad-
dress is %1 (if the value is 2 or 3, for example), the file will be
followed by an end-of-tape marker.
Before calling SAVE, you must also set up a two-byte
zero-page pointer containing the starting address of the block
of memory to be saved and then store the address of the zero-
page pointer in the accumulator. The ending address (plus
one) for the save should be stored in .X (low byte) and .Y
(high byte). To save the entire contents of the desired area, it's
important to remember that .X and .Y must hold an address
that is one location beyond the desired ending address.
When the save is complete, the carry will be clear if the
file was successfully saved, or set if an error occurred (or if the
RUN/STOP key was pressed to abort the save). When carry is
set upon return, the accumulator will hold the Kernal error
code indicating the problem. Possible error-code values in-
clude 5 (serial device was not present), 8 (no name was speci-
fied for a serial save), and 9 (an illegal device number was
specified). The success of the operation will also be indicated
by the value in the tape/serial status flag. (See READST for
details.)
$FF9F SCNKEY SCNKEY
This routine scans the keyboard matrix to determine which
keys, if any, are currently pressed. The standard KQ service
routine calls SCNKEY, so it's not usually necessary to call it
explicitly to read the keyboard. The character code for the key
currently pressed is loaded into the keyboard buffer, from
where it can be retrieved using the Kernal GETIN routine. The
matrix code of the keypress read during this routine can also
be read in location $CB (64) or $D4 (128), and the status of
the shift keys can be read in location $028D (64) or $D3 (128).
$FFED SCREEN SCREEN
This routine (Commodore 128 literature calls it SCRORG) re-
turns information on the size of the screen display. For the 64,
the routine always returns the same values—the screen width
in columns (40) in .X and the screen height in rows (25) in .Y.
The accumulator is unaffected. For the 128, the values returned
reflect the size of the current output window. The X register
will contain in the current window the number of columns mi-
nus one, and .Y will contain the number of rows minus one.
The accumulator will hold the maximum column number for
the display currently active (39 for the 40-column screen or 79
for the 80-column screen).
$FF93 SECOND SECOND
This low-level serial I/O routine sends a secondary address to
a device which has been commanded to listen. The value in
the serial status flag upon return will indicate whether the op-
eration was successful.
$FFBA SETLFS SETLFS
This routine assigns the logical file number (location $B8), de-
vice number (location $BA), and secondary address location
$B9) for the current I/O operation. Call the routine with the
accumulator holding the logical file number, .X holding the
device number, and .Y holding the secondary address. All reg-
ister values are preserved during the routine. Refer to the
LOAD and SAVE routines for the special significance of the
secondary address in those cases. When OPENing files to se-
rial devices, it's vital that each logical file have a unique
secondary address, In the 128 Kernal, the LKUPLA and
LKUPSA routines can be used to find unused logical file num-
bers and secondary addresses.
$FF90 SETMSG SETMSG
SETMSG sets the value of the Kernal message flag (location
$9D). Call the routine with the accumulator holding the de-
sired flag value (.X and .Y are unaffected,) Valid flag values
are 0 (no Kernal messages are displayed), 64 (only error mes-
sages are displayed), 128 (only control messages—PRESS
PLAY ON TAPE, for example—are displayed), and 192 (both
error and control messages are displayed).
$FFBD SETNAM SETNAM
This routine assigns the length (location $B7) and address
locations $BB-$BC) of the filename for the current I/O opera-
tion. Call the routine with the length of the filename in .A and
the address of the first character of the name in .X (low byte)
and .Y (high byte). If no name is used for the current opera-
tion, load the accumulator with 0; the values in .X and .Y are
then irrelevant, All register values are preserved during this
routine.
$FFDB SETTIM SETTIM
This routine sets the value in the software jiffy dock. The
value in the accumulator is transferred to the low byte (loca-
tion $A2), the value in .X to the middle byte (location $A1),
and the value in .Y to the high byte (location $A0). The speci-
fied value should be less than $4F1A01, which corresponds to
24:00:00 hours.
$FFA2 SETTMO SETTMO
The SETTMO routine stores the contents of the accumulator in
the IEEE timeout flag. (.X and .Y are unaffected.) This routine
is superfluous, since the flag isn't used by any 64 or 128 ROM
routine. It is present merely to maintain consistency with pre-
vious versions of the Kernal. For the 64, the flag location is
$0285; for the 128, it's at $0A0E.
$FFE1 STOP STOP
This routine checks whether the RUN/STOP key is currently
pressed. It returns with the status-register Z bit clear if the key
is not pressed, or with the bit set if it is pressed. Additionally,
if RUN/STOP is pressed the CLRCH routine is called to re-
store default I/O channels, and the count of keys in the key-
board buffer is reset to zero.
The JMP to the STOP execution routine is by way of the
ISTOP indirect vector at $0328-$0329. You can modify the ac-
tions of the routine by changing the vector to point to a rou-
tine of your own.
$FFB4 TALK TALK
This low-level 1/0 routine sends a TALK command to a serial
device, Call the routine with the accumulator holding the
number (4-31) of the device. The success of the operation will
be indicated by the value in the serial status flag upon return,
(See READST for details.)
$FF96 TKSA TKSA
This low-level serial 1/0 routine sends a secondary address to
a device which has previously been commanded to taLk. The
success of the operation will be indicated by the value in the
serial status flag upon return. (See READST for details.)
$FFEA UDTIM UDTIM
This routine increments the software jiffy dock and scans the
keyboard column containing the RUN/STOP key. (The 128
version of the routine also decrements a countdown timer.)
This routine is normally called every 1 /60 second as part of
the standard lRQ service routine.
$FFAE UNLSN UNLSN
This low-level I/O routine sends an UNLISTEN command to
aH devices on the serial bus. Any devices which are currently
listeners will cease accepting data.
$FFAB UNTLK UNTLK
This low-level 1/0 routine sends an UNTALK command to all
devices on the serial bus. Any devices which are currently
talkers will cease sending data.
$FF8D VECTOR VECTOR
This routine can be used either to store the current values of
Kernal indirect vectors at $0314-$0333 or to write new values
to the vectors. When calling this routine, .X and .Y should be
loaded with the address of a 32-byte table (low byte in .X,
high byte in .Y). If the status-register carry bit is clear when
the routine is called, the vectors will be loaded with the values
from the table. If carry is set, the 16 two-byte address values
currently in the vectors will be copied to the table.
$FF53 BOOT_CALL BOOT_CALL
This routine attempts to load and execute boot sectors from a
specified disk drive. Call the routine with .X holding the de-
vice number for the drive (usually 8) and with the accu-
mulator holding the character code corresponding to the drive
number—not the actual drive number. The single drive in
1541 and 1571 units is drive 0; in this case, use 48, the charac-
ter code for zero. If the specified drive is not present or is
tumed off, or if the disk in the drive does not contain a valid
boot sector, the routine will return with the status-register
carry bit set. If a boot sector is found, it will be loaded into
locations $0B00-$0BFF. Additional boot sectors may be loaded
into other areas of memory, and the boot code may not return
to this routine.
$FF4A CLOSE_ALL CLOSE_ALL
This routine closes all files currently opened to a specified de-
vice, providing an improved version of CLALL. Enter the rou-
tine with the accumulator holding the number of the device
on which files are to be closed. Lf the specified device is the
current input or output device, the input or output channel
will be reset to the default device (screen or keyboard). If all
files to the device were successfully closed, the status-register
carry bit w01 clear upon return. A set carry bit indicates that a
device error occurred.
$FF4D C64_MODE C64_MODE
This is the equivalent of the BASIC command GO 64. It per-
forms an immediate cold start of 64 mode. To get back to 128
mode, it is necessary to reset the computer, or to tum it off
and back on.
$FF62 DLCHR DLCHR
This routine copies character shape data for both standard
ROM character sets into the VDC video chip's private block of
RAM, providing character definitions for the 80-column dis-
play. (The VDC has no character ROM.) This routine is also
called as part of IOEMFI for the 128.
$FF50 DMA_CALL DMA_CALL
This routine passes a command to a DMA (Direct Memory Ac-
cess) device. The DMA device will then take control of the
system to execute the command. The routine is written to sup-
port the REC (RAM Expansion Controller) chip in the 1700
and 1750 Memory Expansion Modules, the only DMA periph-
erals currently available. Call the routine with .Y holding the
command for the DMA device and .X holding the bank number
for the operation. Other preparatory steps may be required,
depending on the command.
$FF6B GETCFG GETCFG
This routine translates a bank number (0-15) into the
corresponding MMU register setting to configure the system
for that bank. Call the routine with .X holding the bank num-
ber. Upon return, the accumulator will hold the corresponding
MMU configuration register value. (.Y is unaffected.) Once you
have this value, you can store it into $FF00 to change banks.
The input bank number is not checked for validity, and a
number outside the acceptable range will return a meaningless
value.
$FF7A INDCMP INDCMP
This routine compares .A to the number held in a memory
location in a specified bank. In preparing to call EMDCMP,
load a two-byte zero-page pointer with the address of the
location with which the accumulator is to be compared (or
with the base location if a series of bytes is to be compared),
then store the address of this pointer in location $02C8. Call
the routine with the accumulator holding the byte to be com-
pared, .X holding the bank number (0-15) for the target loca-
tion, and .Y holding an offset value which will be added to
the address in the pointer. (Load .Y with 0 if no offset is de-
sired.) Upon return, the accumulator will still hold the byte
value, and the status-register N, Z, and C (carry) bits will re-
flect the result of the comparison. The value in .Y will also be
preserved, but it is necessary to reload .X with the bank num-
ber before every call to this routine. You can compare up to
256 sequential locations without changing the address in the
zero-page pointer by simply incrementing .Y between calls.
$FF74 INDFET INDFET
This routine reads the contents of a location in a specified
bank. Prior to calling this routine; you must load a two-byte
zero-page pointer with the address of the location to be read
(or with the base location if a series of bytes is to be read).
Call the routine with the accumulator holding the address
of the zero-page pointer, .X holding the bank number (0-15)
for the target location, and .Y holding an offset value which
will be added to the address in the pointer. (Load .Y with 0 if
no offset is desired.) Upon return, the accumulator will hold
the byte from the specified address. The value in .Y is not
changed.
To read from a series of locations, it is necessary to reload
the accumulator and .X values before every call to this routine,
but you can read up to 256 sequential locations without
changing the address in the zero-page pointer by incrementing
.Y between calls.
$FF77 INDSTA INDSTA
This routine stores a value at an address in a specified bank.
Before calling the routine, you must load a two-byte zero-page
pointer with the address of the location at which the byte is to
be stored (or with the base location if a series of bytes is to be
stored), and then store the address of this pointer in location
$02B9. Call the routine with the accumulator holding the byte
to be stored, .X holding the bank number (0-15) for the target
location, and .Y holding an offset value which will be added
to the address in the pointer. (Load Y with 0 if no offset is de-
sired.) Upon return, the accumulator will still hold the byte
value; .Y is also preserved. To write to a series of locations,
you must reload .X with the bank number before every call,
but you can write to up to 256 sequential locations without
changing the address in the zero-page pointer by simply in-
crementing .Y between calls.
$FF71 JMPFAR JMPFAR
JMPFAR jumps to a routine in a specified bank, with no return
to the calling bank. Prior to calling this routine, you must store
the bank number (0-15) of the target routine in location 2 and
the address of the target routine in locations 3-4 in high-
byte/low-byte order, opposite from the usual arrangement.
Load location 5 with the value you want placed in the status
register when the target routine is entered. (The behavior of
many operating-system routines is influenced by the status-
register setting, particularly the state of the carry bit. Load 5
with the value 0 to clear carry or with 1 to set carry.) To pass
other register values, store the desired accumulator value in
location 6, the value for .X in 7, and the value for .Y in 8.
$FF6E JSRFAR JSRFAR
This routine jumps to a subroutine in a specified bank and re-
turns to the calling routine in bank 15. Prior to calling this
routine, you must store the bank number (0-15) of the target
routine in location 2 and the address of the target routine in
locations 3-4 (in high-byte/low-byte order, opposite from the
usual arrangement). Load location 5 with the value you want
placed in the status register when the target routine is called.
(The behavior of many operating system routines is influenced
by the status-register setting, particularly the state of the carry
bit. Load 5 with the value 0 to clear carry, or with 1 to set
carry.) To pass other register values to the routine you will be
calling, store the desired accumulator value in location 6, the
value for .X in 7, and the value for .Y in 8. Upon return, loca-
tion 5 will hold the status-register value at the time of exit, 6
will hold the accumulator value, 7 will hold the .X value, 8
will hold the .Y value, and 9 will hold the stack-pointer value.
The system is always configured for bank 15 upon exit.
$FF59 LKUPLA LKUPLA
This routine checks whether a specified logical file number is
currently used. Call the routine with the accumulator holding
the logical-file-number value in question. If that file number is
available, the carry bit will be set upon return. (The logical file
number will still be in the accumulator.) However, if the num-
ber is used for a currently open file, then the carry bit will be
clear upon return, the accumulator will still hold the logical
file number, .X will hold the corresponding device number,
and .Y will hold the corresponding secondary address.
$FF5C LKUPSA LKUPSA
This routine checks whether a specified secondary address is
currently in use. Call the routine with .Y holding the secondary-
address value in question. If that secondary address is not
currently used, the status-register carry bit will be set upon re-
turn. (The secondary-address value will still be in .Y.) How-
ever, ii the number is used for a currently open file, the carry
bit will be clear upon return, .Y will still hold the secondary
address, the accumulator will hold the associated logical file
number, and .X will hold the corresponding device number.
$FF65 PFKEY PFKEY
When you turn on the 128, its function keys are predefined.
Pressing F3 prints DIRECTORY, F7 holds the LIST command,
and so on. The PFKEY Kernal routine assigns a new definition
to one of the 10 programmable function keys (F1-F8, SHIFT-
RUN/STOP, and HELP).
Call the routine with the accumulator holding the address
of a three-byte zero-page string descriptor, .X holding the key
number (1-10), and .Y holding the length of the new defi-
nition string. The first two bytes of the descriptor in zero page
should contain the address of the definition string (in the
usual low-byte/high-byte order); the final byte should hold
the bank number where the definition string is located. PFKEY
doesn't check the key number for validity; a value outside the
acceptable range may garble existing definitions. Upon return,
the carry bit will be clear if the new definition was success-
fully added, or set if there was insufficient room in the defi-
nition table for the new definition.
$FF56 PHOENIX PHOENIX
This routine initializes function ROMs and attempts to boot a
disk from the default drive. The presence of function ROMs in
cartridges or in the 128's spare ROM socket is recorded during
the power-on/reset sequence. This routine initializes the func-
tion ROMs by calling their recorded cold-start entry addresses.
If ROMs are present, they may or may not return to this rou-
tine, depending on the initialization steps performed. If no
ROMs are present, or if all ROMs return after initialization,
the routine attempts to boot a disk in drive 0 of device 8 using
the BOOT_CALL routine,
$FF7D PRIMM PRIMM
This routine prints the string of character codes which im-
mediately follows the JSR to this routine. (You must always
call this routine with JSR, never with JMP. Only JSR places the
required address information on the stack.) The routine contin-
ues printing bytes as character codes until a byte containing
zero is encountered. When the ending marker is found, the
routine returns to the address immediately following the zero
byte. All registers (.A, .X, and .Y) are preserved during this
routine.
$FF68 SETBNK SETBNK
This Kernal routine establishes the current memory bank from
which data will be read or to which data will be written dur-
ing load/save operations, as well as the bank where the file-
name for the I/O operations can be found. Call the routine
with the accumulator holding the bank number for data and
.X holding the bank for the filename. All registers (.A, .X, and
.Y) are preserved during this routine.
$FF47 SPIN_SPOUT SPIN_SPOUT
This low-level serial I/O routine sets up the serial bus for fast
(burst mode) communications. Unless you're writing a custom
data-transfer routine, it's not necessary to call this routine
explicitly. All higher-level serial 1/0 routines already include
this setup step. The routine should be called with the status-
register carry bit clear to establish fast serial input or with the
bit set to establish fast serial output.
$FF5F SWAPPER SWAPPER
This routine switches active screen displays. The active display
is the one which has a live cursor, and to which screen
CHROUT output is directed. The routine exchanges the active
and inactive screen-editor variable tables, tab-stop bitmaps,
and line-link bitmaps; and it toggles the active screen flag
(location $D7). The routine doesn't physically tum either
video chip on or off—both chips always remain enabled.