15. Intrinsic functions¶
This chapter covers predefined intrinsic and built-in functions.
Intrinsics functions appear as ordinary calls but are special compiler
constructs, emitting specific instruction sequences. To enable them,
include the calypsi/intrinsics6502.h header file.
Built-in functions are similar, but they are not declared in
calypsi/intrinsics6502.h.
15.1. Intrinsic functions reference¶
The calypsi/intrinsics6502.h file appears as follows:
/****************************************************************************
*
* Copyright Håkan Thörngren
*
* This file is part of the Calypsi C library.
* Permission to use with the Calypsi tool chain is hereby granted.
*
****************************************************************************/
#ifndef __INTRINSICS_6502_H
#define __INTRINSICS_6502_H
#ifdef __CALYPSI_TARGET_6502__
typedef unsigned char __interrupt_state_t;
typedef void (*__return_address_t)(void);
typedef unsigned short __return_address16_t;
__attribute__((intrinsic)) void __disable_interrupts(void);
__attribute__((intrinsic)) void __enable_interrupts(void);
__attribute__((intrinsic)) __interrupt_state_t __get_interrupt_state(void);
__attribute__((intrinsic)) void __restore_interrupt_state(__interrupt_state_t);
__attribute__((intrinsic)) __return_address_t __get_return_address(void);
__attribute__((intrinsic)) void __set_return_address(__return_address_t);
__attribute__((intrinsic)) void __set_return_address_low16(__return_address16_t);
__attribute__((intrinsic)) void __no_operation(void);
__attribute__((intrinsic)) _Bool __kernel_call_failed(_Bool);
#ifndef __CALYPSI_CORE_65B02__
__attribute__((intrinsic)) void __break_instruction(void);
__attribute__((intrinsic)) void __break_with(unsigned char);
#endif
#ifdef __CALYPSI_CORE_65C02__
__attribute__((intrinsic)) void __wait_for_interrupt(void);
__attribute__((intrinsic)) void __stop_processor(void);
#endif // __CALYPSI_CORE_65C02__
#endif // __CALYPSI_TARGET_6502__
#endif // __INTRINSICS_6502_H
Summary of intrinsic functions¶
Function name |
Description |
|---|---|
|
Disable interrupts |
|
Enable interrupts |
|
Get the current interrupt state |
|
Restore to a previous interrupt state |
|
Gets the return address of the current function |
|
Alters the return address of the current function |
|
Generates a |
|
Generates a |
|
Generates a |
|
Waits for an interrupt (65C02 and 65CNR02 cores only) |
|
Stops the processor (65C02 and 65CNR02 cores only) |
|
Counts leading zeroes in an |
|
Counts leading zeroes in a |
|
Counts leading zeroes in a |
|
Gets the value of the sign bit |
|
Checks for failure after a system call in a kernel, returning status in the carry flag |
Description of intrinsic functions¶
This section details each intrinsic function.
__disable_interrupts¶
Emits a machine instruction that disables interrupts.
__enable_interrupts¶
Emits a machine instruction that enables interrupts.
__get_interrupt_state¶
Returns the current interrupt state as a
__interrupt_state_t value, which can be used as follows:
int global;
void safe_increment () {
__interrupt_state_t state = __get_interrupt_state();
__disable_interrupts;
global++;
__restore_interrupt_state(state);
}
In the example the current state of interrupts is obtained and saved
Returns the current interrupt state as a __interrupt_state_t value,
do the real work. Finally, the interrupt state is restored to what it
was when the function was entered.
__restore_interrupt_state¶
Restores to a previous interrupt state, see example above.
__get_return_address¶
Reads the return address of the current function from its stack frame.
__set_return_address¶
Replaces the current function return address
with the address provided in the argument to __set_return_address().
__no_operation¶
Emits a NOP machine instruction.
__break_instruction¶
Emits a machine instruction that causes a break exception.
__break_with¶
Emits a break exception instruction. This variant takes an opcode
argument for the BRK instruction second byte.
__wait_for_interrupt¶
Emits an instruction that causes the 65C02 (or 65CNR02) to wait for an interrupt. Execution then resumes with the interrupt, followed by normal execution. This functionality is not available on the plain 6502.
__stop_processor¶
Emits an instruction that causes the 65C02 (or 65CNR02) to halt execution. This functionality is not available on the plain 6502.
__builtin_clz¶
Count the number of leading zeroes in a provided int value.
Returns an undefined result if input is zero.
__builtin_clzl¶
Count the number of leading zeroes in a provided long value.
Returns an undefined result if input is zero.
__builtin_clzll¶
Count the number of leading zeroes in a provided long long value.
Returns an undefined result if input is zero.
__builtin_signbit¶
Returns the value (0 or 1) of the signbit of its input.
__kernel_call_failed¶
This intrinsic wraps a Commodore-style kernel system call, testing the carry flag return value. It can be used as follows:
#include <microkernel.h>
void bcd_time() {
if (__kernel_call_failed(MicroKernelGetTime())) {
// Handle failure
...
} else {
// Success
...
}
}
Note
This intrinsic assumes that it surrounds a MicroKernel call expression, if that is not the case the result is unpredictable.