Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

11KB


name: kernal-routines description: > Use this skill for using the C64 Kernal (OS) routines from machine language. Covers all Kernal jump table entries, input parameters, output values, error handling, screen I/O, serial I/O, tape I/O, RS-232, system vectors, and interrupt handling. Sources: COMPUTE!‘s VIC-20 and C64 Tool Kit: Kernal, The Anatomy of the C64, The Complete C64 ROM Disassembly.

Kernal Routines Reference

Overview

The Kernal is the C64's operating system ROM, occupying $E000–$FFFF (57344–65535). It provides a jump table at $FF81–$FFF3 that remains accessible regardless of the current ROM banking state. Always call through the jump table, never directly into ROM routines, as addresses may differ between ROM revisions.


System and Reset Routines

$FF81 — CINT: Initialize Screen Editor

Input:  None
Output: Screen cleared, cursor home
Clobbers: A, X, Y
Use: Called automatically at reset; call to reinitialize screen

$FF84 — IOINIT: Initialize I/O Devices

Input:  None
Output: CIA chips, VIC-II, SID reset to defaults; IRQ enabled
Clobbers: A, X, Y

$FF87 — RAMTAS: Test and Initialize RAM

Input:  None
Output: Zero page and stack cleared, tape buffer zeroed, memory size set
Clobbers: A, X, Y

$FF8A — RESTOR: Restore Default Vectors

Input:  None
Output: RAM vectors at $0314-$0333 restored to Kernal defaults
Clobbers: A, X
Note: Vectors are copied from ROM table at $E518

$FF8D — VECTOR: Read or Set RAM Vectors

Input:  Carry clear  → copy RAM vectors to user area ($FB/$FC points to destination)
        Carry set    → copy user area to RAM vectors ($FB/$FC points to source)
        X = low byte, Y = high byte of 2-byte pointer at $FB/$FC
Output: Vectors read or written
Clobbers: A, X, Y

$FF90 — SETMSG: Control OS Messages

Input:  A = flag byte
          bit 7 = 1: enable BASIC error messages
          bit 6 = 1: enable status messages (FOUND, SAVING, etc)
Output: Previous flag value in A

$FF99 — MEMTOP: Read/Set Top of Memory

Input:  Carry set   → set: X = low byte, Y = high byte of new top address
        Carry clear → read current top
Output: X = low byte, Y = high byte of top of memory

$FF9C — MEMBOT: Read/Set Bottom of Memory

Input:  Carry set   → set: X = low byte, Y = high byte of new bottom
        Carry clear → read current bottom
Output: X = low byte, Y = high byte of bottom of memory

Screen I/O Routines

$FFED — SCREEN: Return Screen Format

Input:  None
Output: X = number of columns (40), Y = number of rows (25)

$FFF0 — PLOT: Read/Set Cursor Position

Input:  Carry set   → set cursor: X = row (0-24), Y = column (0-39)
        Carry clear → read cursor position
Output: (read) X = current row, Y = current column
Note: Cursor blink is reset

$FFD2 — BSOUT: Output Character to Current Channel

Input:  A = character to output (PETSCII)
Output: Character sent to current output channel (screen or file)
Clobbers: A
Note: Also accessible via KERNAL vector at $0326/$0327

$FFCF — BASIN: Input Character from Current Channel

Input:  None
Output: A = character received (PETSCII)
Note: Waits for input if keyboard; also accessible at $0324/$0325

$FFE4 — GETIN: Get Character from Input Queue

Input:  None
Output: A = character (0 if no character available)
Note: Non-blocking keyboard read; does not wait for keypress

$FFE1 — STOP: Test STOP Key

Input:  None
Output: Zero flag set if STOP key pressed
        A = current value of keyboard row (matrix scan)
Note: Also restores registers if STOP held (calls CLRCH)

File I/O: Setup Routines

$FFBA — SETLFS: Set Logical File, Device, Command

Input:  A = logical file number (1-127)
        X = device number (0=keyboard, 1=tape, 2=RS232, 3=screen, 4-7=serial, 8-15=disk)
        Y = secondary address (0-15; 255=no secondary address)
Output: Values stored in OS variables ($B8, $B9, $BA, $BB)

$FFBD — SETNAM: Set Filename

Input:  A = length of filename (0 if no name)
        X = low byte of filename address
        Y = high byte of filename address
Output: Filename parameters stored in OS variables

$FFC0 — OPEN: Open Logical File

Input:  Parameters set by SETLFS and SETNAM
Output: Carry clear = success
        Carry set   = error; A = error code
Error codes: 1=file open, 2=too many files, 4=file not found, 5=device not present, 6=not input file, 7=not output file

$FFC3 — CLOSE: Close Logical File

Input:  A = logical file number to close
Output: File closed, channels freed
Clobbers: A, X, Y

$FFC6 — CHKIN: Open Channel for Input

Input:  X = logical file number (must be open)
Output: Carry clear = success; subsequent BASIN reads from this file
        Carry set = error; A = error code

$FFC9 — CHKOUT: Open Channel for Output

Input:  X = logical file number (must be open)
Output: Carry clear = success; subsequent BSOUT writes to this file
        Carry set = error; A = error code

$FFCC — CLRCH: Clear Input/Output Channels

Input:  None
Output: Default channels restored (keyboard input, screen output)
Clobbers: A, X

$FFE7 — CLALL: Close All Files and Channels

Input:  None
Output: All logical files closed, channels restored to defaults
Clobbers: A, X

File I/O: Load and Save

$FFD5 — LOAD: Load from Device

Input:  A = 0 for LOAD, 1 for VERIFY
        X = low byte of load address (if SA=0, ignored — file provides address)
        Y = high byte of load address
        SA (set by SETLFS): 0 = load to file's own start address
                             1 = load to X/Y address
Output: Carry clear = success; X = low byte, Y = high byte of last address+1
        Carry set = error; A = error code
Note: Set SETLFS with SA=0 to load at the address stored in the file header

$FFD8 — SAVE: Save to Device

Input:  A = zero-page address containing 2-byte start address pointer
        X = low byte of end address + 1
        Y = high byte of end address + 1
Output: Carry clear = success
        Carry set = error; A = error code
Example:
        LDA #<STARTADR
        STA $C1
        LDA #>STARTADR
        STA $C2
        LDA #$C1         ; ZP pointer to start address
        LDX #<(ENDADR+1)
        LDY #>(ENDADR+1)
        JSR $FFD8

I/O Status

$FFB7 — READST: Read I/O Status Word

Input:  None
Output: A = status byte (ST variable at $90)
Status bits:
  Bit 0: Write timeout on serial bus
  Bit 1: (serial) Byte lost
  Bit 2: Short block (tape)
  Bit 3: Long block (tape)
  Bit 4: Unrecoverable read error (tape)
  Bit 5: Checksum error (tape)
  Bit 6: End of file
  Bit 7: End of tape / device not present

Serial Bus Routines

$FFB1 — LISTEN: Command Device to Listen

Input:  A = device address (8-30)
Output: Device commanded to LISTEN; subsequent bytes go to device

$FFB4 — TALK: Command Device to Talk

Input:  A = device address (8-30)
Output: Device commanded to TALK; subsequent bytes come from device

$FF93 — SECOND: Send Secondary Address After LISTEN

Input:  A = secondary address (0-31)
Output: Secondary address sent to listening device

$FF96 — TKSA: Send Secondary Address After TALK

Input:  A = secondary address (0-31)
Output: Secondary address sent to talking device

$FFA5 — ACPTR: Input Byte from Serial Bus

Input:  None (a device must be talking)
Output: A = byte received from serial bus

$FFA8 — CIOUT: Output Byte to Serial Bus

Input:  A = byte to send (device must be listening)
Output: Byte sent to serial bus

$FFAB — UNTLK: Send UNTALK

Input:  None
Output: UNTALK sent; talking device releases bus

$FFAE — UNLSN: Send UNLISTEN

Input:  None
Output: UNLISTEN sent; all listening devices release bus

Timing

$FFDB — SETTIM: Set Real-Time Clock

Input:  A = high byte, X = middle byte, Y = low byte of 60Hz jiffy count

$FFDE — RDTIM: Read Real-Time Clock

Input:  None
Output: A = high byte, X = middle byte, Y = low byte of jiffy count
Note: Count increments 60× per second (NTSC) or 50× per second (PAL)

$FFEA — UDTIM: Increment Real-Time Clock

Input:  None
Output: Jiffy count incremented; called by IRQ handler

RAM Vectors (Kernal and BASIC)

The Kernal uses indirect vectors in RAM. These can be patched to intercept OS calls.

Address Vector Default ROM target Purpose
$0314-$0315 CINV $EA31 IRQ handler
$0316-$0317 CBINV $FE66 BRK handler
$0318-$0319 NMINV $FE47 NMI handler
$031A-$031B IOPEN $F34A OPEN routine
$031C-$031D ICLOSE $F2C7 CLOSE routine
$031E-$031F ICHKIN $F20E CHKIN routine
$0320-$0321 ICHKOUT $F250 CHKOUT routine
$0322-$0323 ICLRCH $F333 CLRCH routine
$0324-$0325 IBASIN $F157 BASIN (CHRIN)
$0326-$0327 IBSOUT $F1CA BSOUT (CHROUT)
$0328-$0329 ISTOP $F6ED STOP test
$032A-$032B IGETIN $F13E GETIN
$032C-$032D ICLALL $F32F CLALL
$032E-$032F USRCMD $FE66 User command
$0330-$0331 ILOAD $F4A5 LOAD
$0332-$0333 ISAVE $F5ED SAVE

Intercepting BSOUT (Output) Example

; Install hook on BSOUT to intercept all character output
        SEI
        LDA $0326
        STA OLDBSOUT    ; save original
        LDA $0327
        STA OLDBSOUT+1
        LDA #<MYHOOK
        STA $0326
        LDA #>MYHOOK
        STA $0327
        CLI
        RTS

MYHOOK  ; A = character about to be output
        ; do your interception here
        JMP (OLDBSOUT)  ; chain to original routine
OLDBSOUT .WORD $F1CA

Kernal Usage Template (Assembly)

; Complete file write example
        ; 1. Set LFS
        LDA #1          ; logical file 1
        LDX #8          ; disk drive
        LDY #2          ; SA=2 (write sequential)
        JSR $FFBA       ; SETLFS
        
        ; 2. Set filename
        LDA #FNLEN
        LDX #<FNAME
        LDY #>FNAME
        JSR $FFBD       ; SETNAM
        
        ; 3. Open
        JSR $FFC0       ; OPEN
        BCS OERR        ; branch on error
        
        ; 4. Redirect output
        LDX #1          ; LFN
        JSR $FFC9       ; CHKOUT
        BCS CERR
        
        ; 5. Write data
        LDX #0
WLOOP   LDA DATA,X
        BEQ DONE
        JSR $FFD2       ; BSOUT
        INX
        BNE WLOOP
        
        ; 6. Clean up
DONE    JSR $FFCC       ; CLRCH
        LDA #1
        JSR $FFC3       ; CLOSE
        RTS

OERR    ; handle open error (A = code)
CERR    ; handle channel error
FNAME   .TEXT "MYFILE,S,W"
FNLEN   = * - FNAME
DATA    .TEXT "HELLO WORLD"
        .BYTE 0

Powered by TurnKey Linux.