-
Notifications
You must be signed in to change notification settings - Fork 50
/
appendix-kernal-jumptable.tex
2588 lines (2081 loc) · 84.5 KB
/
appendix-kernal-jumptable.tex
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{KERNAL Jump Table}
\label{cha:kernal-jump-table}
\section{Using the KERNAL Jump Table}
The \emph{KERNAL} is the centerpiece of the MEGA65 operating system. It is responsible for setting up the operating system when the computer is switched on or reset, interfacing with peripherals, invoking disk operations, managing input and output streams, and driving key features of the screen editor and BASIC. While it is running, the KERNAL owns the CPU memory map and interrupt handlers, and reserves regions of memory to support its features.
The KERNAL provides an \emph{Application Programming Interface} (API) so that machine code programs can take advantage of its features, such as to read a file from disk, by calling subroutines. A program accesses these subroutines by calling addresses in a \emph{jump table}, a region of ROM code that is guaranteed by the API to always access the same subroutines in the same way, even across different versions of the ROM code. The program uses \texttt{jsr} or \texttt{jmp} (as required by the routine) using the jump table address as an absolute target. Memory at the jump table address contains a \texttt{jmp} instruction to the appropriate internal address.
For example, to write a character to the output stream (the screen terminal, by default), a program sets the accumulator (A) register to the PETSCII code to write, then calls the CHROUT subroutine with the jump table address \$FFD2:
\begin{asmcode}
lda #$41
jsr $ffd2
\end{asmcode}
\subsection{Prerequisites of Jump Table Routines}
All KERNAL jump table routines expect the following conditions to be true when called:
\begin{enumerate}
\item The 16-bit address range \$E000 -- \$FFFF must be mapped to the KERNAL ROM at 3.E000 -- 3.FFFF.
\item The 16-bit address range \$0000 -- \$1FFF must be mapped to KERNAL internal variable memory at 0.0000 -- 0.1FFF.
\item The CPU base page register (B) must be \$00.
\end{enumerate}
Some jump table routines have additional prerequisites. See the reference below.
The KERNAL BASIC and SYS memory maps maintain these conditions by default. If a machine code program does not change the MAP or B registers, it can call KERNAL jump table routines without additional set-up.
The KERNAL makes use of other regions of memory. See \bookref{cha:memory}.
Unless otherwise noted, a program must assume that a call to a KERNAL routine overwrites data in all CPU registers and value-related status flags. Implications for the stack and mode-related status flags (interrupts) are noted explicitly.
\subsection{History and Compatibility}
The MEGA65 KERNAL jump table is based on, and compatible with, the Commodore 65 jump table. This API is derived from, but \emph{not} entirely compatible with, the KERNAL APIs of the Commodore 64 and Commodore 128.
This documentation adopts the names of the routines from Commodore 65 documentation where possible, and invents unique names for routines new to the MEGA65. A routine with a name similar to C64 or C128 documentation may \emph{not} be API compatible. Differences are noted in this reference, where known.
The MEGA65's ``GO64'' mode uses the C64 KERNAL. Refer to a C64 programming reference for information on how to use the C64 KERNAL.
For a complete history of the KERNAL jump table across all Commodore computers, see: \url{https://www.pagetable.com/?p=926}
\newpage
\section{MEGA65 KERNAL Jump Table Quick Reference}
The following is a quick reference for the MEGA65 KERNAL jump table, in address order. See the full reference for details and examples.
\begin{longtable}{|L{2cm}|p{2cm}|p{2cm}|L{6cm}|}
\hline
\textbf{Address} & \textbf{Category} & \textbf{Name} & \textbf{Description} \\
\hline
\endfirsthead
\multicolumn{4}{l@{}}{\ldots continued}\\
\hline
\textbf{Address} & \textbf{Category} & \textbf{Name} & \textbf{Description} \\
\hline
\endhead
\multicolumn{4}{l@{}}{continued \ldots}\\
\endfoot
\hline
\endlastfoot
\$FF41 & I/O & GETIO & Read the current input and output devices \\
\hline
\$FF44 & Files & GETLFS & Read file, device, secondary address \\
\hline
\$FF47 & Editor & KEYLOCKS & Read/set keyboard locks \\
\hline
\$FF4A & Editor & ADDKEY & Add a character to the soft keyboard input buffer \\
\hline
\$FF4D & Reserved & SPIN\_SPOUT & Set up fast serial ports \\
\hline
\$FF50 & Files & CLOSE\_ALL & Close all files on a device \\
\hline
\$FF53 & OS & C64MODE & Reset to GO64 mode \\
\hline
\$FF56 & OS & MonitorCall & Invoke monitor \\
\hline
\$FF59 & OS & BOOT\_SYS & Boot an alternate system from disk \\
\hline
\$FF5C & OS & PHOENIX & Call cartridge cold start or disk boot loader \\
\hline
\$FF5F & Files & LKUPLA & Search for logical file number in use \\
\hline
\$FF62 & Files & LKUPSA & Search for secondary address in use \\
\hline
\$FF65 & Editor & SWAPPER & Toggle between 40x25 and 80x25 text modes \\
\hline
\$FF68 & Editor & PFKEY & Program an editor function key \\
\hline
\$FF6B & Files & SETBNK & Set bank for I/O and filename memory \\
\hline
\$FF6E & Memory & JSRFAR & Call subroutine in any bank \\
\hline
\$FF71 & Memory & JMPFAR & Jump to address in any bank \\
\hline
\$FF74 & Memory & LDA\_FAR & Read a byte from an address in any bank \\
\hline
\$FF77 & Memory & STA\_FAR & Store a byte to an address in any bank \\
\hline
\$FF7A & Memory & CMP\_FAR & Compare a byte with an address in any bank \\
\hline
\$FF7D & Tools & PRIMM & Print an inline null-terminated short string \\
\hline
\$FF81 & Editor & CINT & Initialize screen editor \\
\hline
\$FF84 & OS & IOINIT & Initialize I/O devices \\
\hline
\$FF87 & OS & RAMTAS & Initialize RAM and buffers \\
\hline
\$FF8A & OS & RESTOR & Initialize KERNAL vector table \\
\hline
\$FF8D & OS & VECTOR & Read/set KERNAL vector table \\
\hline
\$FF90 & OS & SETMSG & Enable/disable KERNAL messages \\
\hline
\$FF93 & Serial & SECND & Send secondary address to listener \\
\hline
\$FF96 & Serial & TKSA & Send secondary address to talker \\
\hline
\$FF99 & Reserved & MEMTOP & RESERVED, DO NOT USE \\
\hline
\$FF9C & Reserved & MEMBOT & RESERVED, DO NOT USE \\
\hline
\$FF9F & Tools & KEY & Scan keyboard \\
\hline
\$FFA2 & OS & MONEXIT & Monitor's exit to BASIC \\
\hline
\$FFA5 & Serial & ACPTR & Accept a byte from talker \\
\hline
\$FFA8 & Serial & CIOUT & Send a byte to listener \\
\hline
\$FFAB & Serial & UNTLK & Send ``untalk'' command \\
\hline
\$FFAE & Serial & UNLSN & Send ``unlisten'' command \\
\hline
\$FFB1 & Serial & LISTN & Send ``listen'' command \\
\hline
\$FFB4 & Serial & TALK & Send ``talk'' command \\
\hline
\$FFB7 & I/O & READSS & Get status of last I/O operation \\
\hline
\$FFBA & Files & SETLFS & Set file, device, secondary address \\
\hline
\$FFBD & Files & SETNAM & Set filename pointers \\
\hline
\$FFC0 & Files & OPEN & Open logical file \\
\hline
\$FFC3 & Files & CLOSE & Close logical file \\
\hline
\$FFC6 & I/O & CHKIN & Set input channel \\
\hline
\$FFC9 & I/O & CKOUT & Set output channel \\
\hline
\$FFCC & I/O & CLRCH & Restore default channels \\
\hline
\$FFCF & I/O & BASIN & Read a character from input device \\
\hline
\$FFD2 & I/O & BSOUT & Write a character to output device \\
\hline
\$FFD5 & Files & LOAD & Load/verify from file \\
\hline
\$FFD8 & Files & SAVE & Save to file \\
\hline
\$FFDB & Tools & SETTIM & Set CIA1 24-hour clock \\
\hline
\$FFDE & Tools & RDTIM & Read CIA1 24-hour clock \\
\hline
\$FFE1 & Tools & STOP & Report Stop key (see ScanStopKey) \\
\hline
\$FFE4 & I/O & GETIN & Read a character from input device, without waiting \\
\hline
\$FFE7 & Files & CLALL & Close all files and channels \\
\hline
\$FFEA & Tools & ScanStopKey & Scan Stop key \\
\hline
\$FFED & Editor & SCRORG & Get current screen window size \\
\hline
\$FFF0 & Editor & PLOT & Read/set cursor position \\
\hline
\$FFF3 & Reserved & IOBASE & RESERVED, DO NOT USE \\
\hline
\end{longtable}
\newpage
\section{MEGA65 KERNAL Jump Table Reference}
\titleformat*{\subsection}{\normalfont\huge\bfseries\color{blue}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ****
% ACPTR
% ****
\newpage
\subsection{ACPTR}
\index{KERNAL Jump Table!ACPTR}
\label{KERNAL Jump Table!ACPTR}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFA5
\item [Description:] Accept a byte from talker
\item [Outputs:]
\textbf{A} The accepted byte
\item [Remarks:]
This is a low-level serial routine. Most programs will prefer the higher level I/O routines (OPEN et al.).
After sending the TALK command to a serial device to tell it to provide output, and optionally a secondary address with TKSA, a program calls ACPTR to read data from the device, one byte at a time. See TALK.
This behavior can be overridden or extended with the IACPTR vector.
\item [Example:]
\begin{asmcode}
acptr = $ffa5
jsr $ffa5
sta data
\end{asmcode}
\end{description}
% ****
% ADDKEY
% ****
\newpage
\subsection{ADDKEY}
\index{KERNAL Jump Table!ADDKEY}
\label{KERNAL Jump Table!ADDKEY}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF4A
\item [Description:] Add a character to the keyboard input buffer
\item [Inputs:]
\textbf{A} The PETSCII code
\item [Outputs:]
\textbf{C flag} 0 on success, 1 on failure
\item [Remarks:]
The MEGA65 KERNAL reads keyboard events from three sources: the active function key macro, a keyboard buffer managed by the KERNAL, and the hardware typing event queue. When GETIN reads from the keyboard, it checks each of these sources, in order.
ADDKEY adds a PETSCII code to the keyboard buffer. This buffer is processed by GETIN when no function key macro is active. It supersedes the hardware typing event queue.
The keyboard buffer has a fixed size. If the buffer is full, the key will not be added, and the C flag will be set.
\underline{NOTE}: For the MEGA65, the buffer is consumed by calls to GETIN, and not by the KERNAL IRQ as on a C64. A program must return to the screen editor for GETIN to be called. If a program needs to enqueue more than a few characters, one option is to use an IIRQ vector to feed characters into the buffer gradually.
\item [Example:]
\begin{asmcode}
addkey = $ff4a
; Cause RUN and a carriage return to be typed
; once control returns to the screen editor.
lda #'R'
jsr addkey
bcs err
lda #'U'
jsr addkey
bcs err
lda #'N'
jsr addkey
bcs err
lda #13
jsr addkey
bcs err
\end{asmcode}
\end{description}
% ****
% BASIN
% ****
\newpage
\subsection{BASIN}
\index{KERNAL Jump Table!BASIN}
\label{KERNAL Jump Table!BASIN}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFCF
\item [Description:] Read a character from input device
\item [Outputs:]
\textbf{A} The character read \\
\textbf{C flag} Set on error
\item [Remarks:]
The default input device is the keyboard. A program can change the input device with OPEN and CHKIN.
BASIN treats the input device as buffered and line oriented, with each line ending in a carriage return (PETSCII 13).
If the device is RS-232 or serial and the buffer is empty, BASIN waits for the next character. If the device is in an error state, BASIN skips input and returns a carriage return.
If the device is the keyboard, the cursor is activated and BASIN waits for the user to type a logical line and press Return. Each call to BASIN returns a character from the line, up to and including the carriage return. This also advances the cursor position to the last character on the logical line---but not after it. (Writing a character at this point, such as with BSOUT, overwrites the last character on the line. It is usually appropriate to write a single carriage return to the screen terminal.)
If the device is the screen, BASIN behaves as if the user pressed Return with keyboard input, and reads from the current cursor position up to the end of the logical line. The final character of a logical line is a carriage return.
To attempt to read a character without waiting on an empty buffer, use GETIN.
This routine can be overridden or extended using the IBASIN vector.
\item [Example:]
\begin{asmcode}
basin = $ffcf
; Read a line into memory, up to
; 255 characters
ldy #0
read_more:
jsr basin
sta data,y
iny
beq out_of_memory
cmp #$0d ; carriage return?
bne read_more
\end{asmcode}
\end{description}
% ****
% BOOT\_SYS
% ****
\newpage
\subsection{BOOT{\_}SYS}
\index{KERNAL Jump Table!BOOT\_SYS}
\label{KERNAL Jump Table!BOOT_SYS}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JMP \$FF59
\item [Description:] Boot an alternate system from disk
\item [Remarks:]
The Commodore 65 intended a feature where a floppy disk in the internal 3-1/2" disk drive could bootstrap software using up to 512 bytes of machine code in a ``home'' sector, at track 0, sector 1.
When the BOOT\_SYS KERNAL routine is called, or the user performs the \textbf{BOOT SYS} command, or the user holds the Alt key during start-up, the KERNAL reads the home sector of the disk. If the first byte is \$4C, the KERNAL loads the sector into memory at 0.0400, then invokes it with JMP. If no disk is present or the first byte is not \$4C, no action is taken.
The boot sector feature is distinct from the BASIC 10 \textbf{BOOT} command that loads and runs a file named \texttt{AUTOBOOT.C65}. It is not compatible with C128-style boot sectors.
This routine does not return. Only use JMP with this routine.
\underline{NOTE}: For the MEGA65, this feature is untested.
\item [Example:]
\begin{asmcode}
boot_sys = $ff59
jmp boot_sys
\end{asmcode}
\end{description}
% ****
% BSOUT
% ****
\newpage
\subsection{BSOUT}
\index{KERNAL Jump Table!BSOUT}
\label{KERNAL Jump Table!BSOUT}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFD2
\item [Description:] Write a character to output device
\item [Inputs:]
\textbf{A} Character to output
\item [Outputs:]
\textbf{C flag} Set on error \\
\textbf{A} Error code, if any
\item [Remarks:]
The default output device is the screen. A program can change the output device with OPEN and CKOUT.
BSOUT treats the output device as buffered.
If the device is RS-232 and the output buffer is full, BSOUT waits until there is room in the buffer.
If the device is serial, a single character buffer is used with CIOUT and the previously buffered character is sent.
If the device is the screen, the character is written to screen memory at the current cursor position.
This routine can be overridden or extended using the IBSOUT vector.
\item [Example:]
\begin{asmcode}
bsout = $ffd2
lda #$0d
jsr bsout
\end{asmcode}
\end{description}
% ****
% C64MODE
% ****
\newpage
\subsection{C64MODE}
\index{KERNAL Jump Table!C64MODE}
\label{KERNAL Jump Table!C64MODE}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JMP \$FF53
\item [Description:] Reset to GO64 mode
\item [Remarks:]
This switches to the GO64 mode memory map, resets the VIC modes, and jumps to the GO64 start routine.
This routine does not return. Only use JMP with this routine.
\item [Example:]
\begin{asmcode}
c64mode = $ff53
jmp c64mode
\end{asmcode}
\end{description}
% ****
% CHKIN
% ****
\newpage
\subsection{CHKIN}
\index{KERNAL Jump Table!CHKIN}
\label{KERNAL Jump Table!CHKIN}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFC6
\item [Description:] Set input channel
\item [Inputs:]
\textbf{X} The logical address of the input device
\item [Outputs:]
\textbf{C flag} Set on error \\
\textbf{A} Error code, if any
\item [Remarks:]
This changes the input channel to use a given device identified by its logical address. Call CHKIN after a call to OPEN. BASIN and GETIN read from the current input channel.
The default input device is the keyboard. A program can call CLRCH to restore default channel settings.
CHKIN performs device-specific tasks, such as sending a TALK command to a serial channel. Setting a non-input device results in an error.
This routine can be overridden or extended using the ICHKIN vector.
\item [Example:]
\begin{asmcode}
chkin = $ffc6
ldx #8
jsr chkin
\end{asmcode}
\end{description}
% ****
% CINT
% ****
\newpage
\subsection{CINT}
\index{KERNAL Jump Table!CINT}
\label{KERNAL Jump Table!CINT}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF81
\item [Description:] Initialize screen editor
\item [Remarks:]
CINT resets all properties of the screen editor, including indirect vectors, function key macros, VIC registers, and SID registers. It also clears the screen.
CINT is typically called along with IOINIT, which resets additional properties of the screen editor.
Because it updates indirect vectors, it must be called with IRQs disabled.
\item [Example:]
\begin{asmcode}
cint = $ff81
sei
jsr cint
cli
\end{asmcode}
\end{description}
% ****
% CIOUT
% ****
\newpage
\subsection{CIOUT}
\index{KERNAL Jump Table!CIOUT}
\label{KERNAL Jump Table!CIOUT}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFA8
\item [Description:] Send a byte to listener
\item [Inputs:]
\textbf{A} The byte to send
\item [Remarks:]
This is a low-level serial routine. Most programs will prefer the higher level I/O routines (OPEN et al.).
After sending the LISTN command to a serial device to tell it to listen for input, and optionally a secondary address with SECND, a program uses CIOUT to send data to the device, one byte at a time.
This behavior can be overridden or extended with the ICIOUT vector.
\item [Example:]
\begin{asmcode}
ciout = $ffa8
lda data
jsr ciout
\end{asmcode}
\end{description}
% ****
% CKOUT
% ****
\newpage
\subsection{CKOUT}
\index{KERNAL Jump Table!CKOUT}
\label{KERNAL Jump Table!CKOUT}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFC9
\item [Description:] Set output channel
\item [Inputs:]
\textbf{X} The logical address of the output device
\item [Outputs:]
\textbf{C flag} Set on error \\
\textbf{A} Error code, if any
\item [Remarks:]
This changes the output channel to use a given device identified by its logical address. Call CKOUT after a call to OPEN. BSOUT writes to the current output channel.
The default output device is the screen terminal. A program can call CLRCH to restore default channel settings.
CKOUT performs device-specific tasks, such as sending a LISTN command to a serial channel. Setting a non-output device results in an error.
This routine can be overridden or extended using the ICKOUT vector.
\item [Example:]
\begin{asmcode}
ckout = $ffc9
ldx #8
jsr chkout
\end{asmcode}
\end{description}
% ****
% CLALL
% ****
\newpage
\subsection{CLALL}
\index{KERNAL Jump Table!CLALL}
\label{KERNAL Jump Table!CLALL}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFE7
\item [Description:] Close all files and channels
\item [Remarks:]
All open logical files are closed, as if closed with CLOSE. This includes performing device-specific closing tasks, as well as restoring the default input and output channels (as if via CLRCH).
This behavior can be overridden or extended with the ICLALL vector.
\item [Example:]
\begin{asmcode}
clall = $ffe7
jsr clall
\end{asmcode}
\end{description}
% ****
% CLOSE
% ****
\newpage
\subsection{CLOSE}
\index{KERNAL Jump Table!CLOSE}
\label{KERNAL Jump Table!CLOSE}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFC3
\item [Description:] Close logical file
\item [Inputs:]
\textbf{A} The logical file to close \\
\textbf{C flag} Set to delete logical file without sending close command
\item [Outputs:]
\textbf{C flag} Set on error \\
\textbf{A} Error code, if error
\item [Remarks:]
This performs device-specific closing tasks for the given open logical file number.
If the file is already closed, or the logical file number refers to the keyboard or screen, CLOSE returns without an error.
If the device is RS-232, this waits for the write buffer to empty before closing.
If the device is serial, any buffered output character is sent, a ``close'' command is sent if appropriate, and the device is told to UNLSTN.
As a special case, if the C flag is set, the device is a disk (FA is 8 or greater), and the secondary address is the command channel (15), no ``close'' command is sent, and the logical file is removed from the file list. This is necessary to prevent the disk from closing other opened files when closing the command channel. See OPEN for a complete example.
\underline{NOTE}: When CLOSE is used on a file that was set as the input or output channel by CHKIN or CKOUT, it does \emph{not} reset the input/output channel, and a subsequent read/write may misbehave. Use CLRCH after CLOSE to reset the input/output channels.
This behavior can be overridden or extended with the ICLOSE vector.
\item [Example:]
\begin{asmcode}
close = $ffc3
clrch = $ffcc
clc ; normal close
lda #$01
jsr close
jsr clrch ; clear I/O channels after
; closing the file
\end{asmcode}
\end{description}
% ****
% CLOSE\_ALL
% ****
\newpage
\subsection{CLOSE{\_}ALL}
\index{KERNAL Jump Table!CLOSE\_ALL}
\label{KERNAL Jump Table!CLOSE_ALL}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF50
\item [Description:] Close all files on a device
\item [Inputs:]
\textbf{A} The device number (0-31)
\item [Remarks:]
This calls CLOSE for each open file for the given device (FA).
If one of the closed files is the current input or output channel, the default is restored.
\item [Example:]
\begin{asmcode}
close_all = $ff50
lda #$08
jsr close_all
\end{asmcode}
\end{description}
% ****
% CLRCH
% ****
\newpage
\subsection{CLRCH}
\index{KERNAL Jump Table!CLRCH}
\label{KERNAL Jump Table!CLRCH}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFCC
\item [Description:] Restore default channels
\item [Remarks:]
This clears all open channels and restores the default system I/O channels, including the keyboard as the input channel and the screen terminal as the output channel.
If the current input or output channels are to serial devices, CLRCH sends UNTLK or UNLSN, as appropriate.
This routine can be overridden or extended using the ICLRCH vector.
\item [Example:]
\begin{asmcode}
clrch = $ffcc
jsr clrch
\end{asmcode}
\end{description}
% ****
% CMP\_FAR
% ****
\newpage
\subsection{CMP{\_}FAR}
\index{KERNAL Jump Table!CMP\_FAR}
\label{KERNAL Jump Table!CMP_FAR}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF7A
\item [Description:] Compare a byte with an address in any bank
\item [Inputs:]
\textbf{A} Data to compare \\
\textbf{X} Base page pointer \\
\textbf{Y} Index from pointed address \\
\textbf{Z} Bank
\item [Outputs:]
CPU status flags based on the comparison
\item [Remarks:]
Conceptually, this is the equivalent of \texttt{cmp (X),y} in bank Z.
This can access any address in the first 1MB of memory. Unlike JMPFAR, this does not change the memory map. It uses a DMA job to access the long address.
For the MEGA65, the 45GS02 supports an instruction that can do this with a 32-bit address stored on the base page, without the need for a KERNAL routine: \texttt{cmp [zp4],z}
\item [Example:]
\begin{asmcode}
cmp_far = $ff7a
; Compare memory at address 4.4502
; to the accumulator
lda #$00
sta $fe
lda #$45
sta $ff
ldx #$fe ; base page pointer -> $4500
ldy #$02 ; Y index
ldz #$04 ; bank
lda #$99 ; data to compare
jsr cmp_far
beq they_are_equal ; ...
\end{asmcode}
\end{description}
% ****
% GETIN
% ****
\newpage
\subsection{GETIN}
\index{KERNAL Jump Table!GETIN}
\label{KERNAL Jump Table!GETIN}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFE4
\item [Description:] Read a character from input device, without waiting
\item [Outputs:]
\textbf{A} The character read \\
\textbf{C flag} Set on error
\item [Remarks:]
The default input device is the keyboard. A program can change the input device with OPEN and CHKIN.
GETIN treats the input device as buffered, but does not wait for input. If the input buffer for the device is empty, GETIN returns \$00.
For the MEGA65, if the input device is the keyboard, GETIN uses several keyboard input buffers: the KERNAL keyboard buffer, the function key macro buffer, and the MEGA65 hardware keyboard buffer. Unlike the C65, the MEGA65 KERNAL does not populate the KERNAL keyboard buffer during the IRQ handler. Instead, GETIN consumes one typing event from the MEGA65 hardware keyboard buffer directly. The KERNAL keyboard buffer is still honored to support software features that inject keystrokes.
If the input device is serial or the screen, it behaves like BASIN.
This routine can be overridden or extended using the IGETIN vector.
\item [Example:]
\begin{asmcode}
getin = $ffe4
get_a_key:
jsr getin
beq get_a_key
sta data
\end{asmcode}
\end{description}
% ****
% GETIO
% ****
\newpage
\subsection{GETIO}
\index{KERNAL Jump Table!GETIO}
\label{KERNAL Jump Table!GETIO}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF41
\item [Description:] Read the current input and output devices
\item [Outputs:]
\textbf{X} current input device (FA) \\
\textbf{Y} current output device (FA)
\item [Remarks:]
An input device of 0 represents the keyboard.
An output device of 3 represents the screen.
These settings are modified by CHKIN and CKOUT.
\item [Example:]
\begin{asmcode}
getio = $ff41
jsr getio
cpy #3
beq is_screen_output
\end{asmcode}
\end{description}
% ****
% GETLFS
% ****
\newpage
\subsection{GETLFS}
\index{KERNAL Jump Table!GETLFS}
\label{KERNAL Jump Table!GETLFS}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF44
\item [Description:] Read file, device, secondary address
\item [Outputs:]
\textbf{A} The logical file number (LA) \\
\textbf{X} The device number (FA) \\
\textbf{Y} The secondary address, or \$FF (SA)
\item [Remarks:]
These settings are modified by SETLFS, as well as other KERNAL calls and BASIC commands that look up information about open files via the logical file number.
A program can use this to determine from which disk drive the program was loaded by calling it just after starting, before performing other disk I/O.
\item [Example:]
\begin{asmcode}
getlfs = $ff44
jsr getlfs
\end{asmcode}
\end{description}
% ****
% IOBASE
% ****
\newpage
\subsection{IOBASE}
\index{KERNAL Jump Table!IOBASE}
\label{KERNAL Jump Table!IOBASE}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FFF3
\item [Description:] RESERVED, DO NOT USE
\item [Remarks:]
Historically, this routine returns the start address of the I/O registers. On the C65, this is always \$D000.
\end{description}
% ****
% IOINIT
% ****
\newpage
\subsection{IOINIT}
\index{KERNAL Jump Table!IOINIT}
\label{KERNAL Jump Table!IOINIT}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF84
\item [Description:] Initialize I/O devices
\item [Remarks:]
IOINIT resets the CIA chips, the 45GS02 port, the VIC chip, the UART, and the DOS.
It must be called with IRQs disabled.
\item [Example:]
\begin{asmcode}
ioinit = $ff84
sei
jsr ioinit
cli
\end{asmcode}
\end{description}
% ****
% JMPFAR
% ****
\newpage
\subsection{JMPFAR}
\index{KERNAL Jump Table!JMPFAR}
\label{KERNAL Jump Table!JMPFAR}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JMP \$FF71
\item [Description:] Jump to address in any bank
\item [Inputs:]
\textbf{\$02} Address bank (0-5) \\
\textbf{\$03} Address high \\
\textbf{\$04} Address low \\
\textbf{\$05} CPU status register \\
\textbf{\$06} CPU A register \\
\textbf{\$07} CPU X register \\
\textbf{\$08} CPU Y register \\
\textbf{\$09} CPU Z register
\item [Remarks:]
This updates the CPU memory map to make a requested address visible as a 16-bit address, then JMPs to it. It does not return.
This routine has similar restrictions as the \textbf{SYS} BASIC command, and cannot reach every address. It can only jump to addresses in non-zero banks from X.2000 -- X.7FFF.
The revised memory map keeps \$0000--\$1FFF and \$8000--\$DFFF un-mapped (so they refer to bank 0 and I/O registers), and \$E000--\$FFFF mapped to KERNAL ROM.
A program sets parameters to JMPFAR by writing to the KERNAL's base page. Parameters include the three address bytes, and the state of the CPU registers expected on entry to the new location.
This routine does not return. Only use JMP to call this routine.
\item [Example:]
\begin{asmcode}
jmpfar = $ff71
; MAP $2000-$7FFF to bank 4, then JMP
; to 4.4500
lda #$04
sta $02
lda #$45
sta $03
lda #$00
sta $04
lda #$04 ; Start routine with
; interrupts disabled
sta $05
jmp jmpfar
\end{asmcode}
\end{description}
% ****
% JSRFAR
% ****
\newpage
\subsection{JSRFAR}
\index{KERNAL Jump Table!JSRFAR}
\label{KERNAL Jump Table!JSRFAR}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF6E
\item [Description:] Call subroutine in any bank
\item [Inputs:]
\textbf{\$02} Address bank (0-5) \\
\textbf{\$03} Address high \\
\textbf{\$04} Address low \\
\textbf{\$05} CPU status register \\
\textbf{\$06} CPU A register \\
\textbf{\$07} CPU X register \\
\textbf{\$08} CPU Y register \\
\textbf{\$09} CPU Z register
\item [Outputs:]
CPU status, A, X, Y, and Z registers are as they were at the end of the subroutine.
\item [Remarks:]
This updates the CPU memory map to make a requested address visible as a 16-bit address, then JSRs to it. On return, it restores the previous KERNAL-managed memory map (e.g. the SYS map).
This routine has similar restrictions as the \textbf{SYS} BASIC command, and cannot reach every address. It can only jump to addresses in non-zero banks from X.2000 -- X.7FFF.
The revised memory map keeps \$0000--\$1FFF and \$8000--\$DFFF un-mapped (so they refer to bank 0 and I/O registers), and \$E000--\$FFFF mapped to KERNAL ROM.
A program sets parameters to JSRFAR by writing to the KERNAL's base page. Parameters include the three address bytes, and the state of the CPU registers expected on entry to the new location.
Only use JSR to call this routine.
\item [Example:]
\begin{asmcode}
jsrfar = $ff6e
; MAP $2000-$7FFF to bank 4, then
; JSR to 4.4500
lda #$04
sta $02
lda #$45
sta $03
lda #$00
sta $04
lda #$04 ; Start routine with
; interrupts disabled
sta $05
jsr jsrfar
; Program continues...
\end{asmcode}
\end{description}
% ****
% KEY
% ****
\newpage
\subsection{KEY}
\index{KERNAL Jump Table!KEY}
\label{KERNAL Jump Table!KEY}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF9F
\item [Description:] Perform a keyboard scan.
\item [Remarks:]
For the MEGA65, typing events are managed by a hardware buffer mechanism and not the KERNAL. A program that wants to consume a typing event can call GETIN, or access the typing event buffer registers directly, without calling KEY.
KEY manages special keyboard behaviors, including Mega + Shift, No Scroll, and Ctrl-S. The MEGA65 KERNAL calls KEY in the KERNAL IRQ handler many times per second, similar to other Commodores. A program that disables the KERNAL IRQ handler but wants to maintain these behaviors can call KEY from a custom handler.
\underline{NOTE}: For the MEGA65, KEY diverges from the C65 and does not offer vector hooks. Keyboard intercept vectors are a work in progress.
\item [Example:]
\begin{asmcode}
key = $ff9f
jsr key
\end{asmcode}
\end{description}
% ****
% KEYLOCKS
% ****
\newpage
\subsection{KEYLOCKS}
\index{KERNAL Jump Table!KEYLOCKS}
\label{KERNAL Jump Table!KEYLOCKS}
\begin{description}[leftmargin=2cm,style=nextline]
\item [Address:] JSR \$FF47
\item [Description:] Read/set keyboard locks
\item [Inputs:]
To set: \\
\textbf{C flag} = 0 \\
\textbf{A} The new locks value
To read: \\
\textbf{C flag} = 1
\item [Outputs:]
When reading:
\textbf{A} The locks value
\item [Remarks:]
Locks bits:
\textbf{Bit 5:} Function keys (0=macros, 1=raw keys) \\
\textbf{Bit 6:} No Scroll locked (0=unlocked, 1=locked) \\
\textbf{Bit 7:} Mega+Shift locked (0=unlocked, 1=locked)
Bits 0--4 are reserved for future use. To maintain future compatibility, always read the locks value and preserve the values of these bits.