cc65/include/rp6502.h

247 lines
8.4 KiB
C

/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#ifndef _RP6502_H
#define _RP6502_H
/* RP6502 VIA $FFD0-$FFDF */
#include <_6522.h>
#define VIA (*(volatile struct __6522 *)0xFFD0)
/* RP6502 RIA $FFE0-$FFF9 */
struct __RP6502
{
const unsigned char ready;
unsigned char tx;
const unsigned char rx;
const unsigned char vsync;
unsigned char rw0;
unsigned char step0;
unsigned int addr0;
unsigned char rw1;
unsigned char step1;
unsigned int addr1;
unsigned char xstack;
unsigned char errno_lo;
unsigned char errno_hi;
unsigned char op;
unsigned char irq;
const unsigned char spin;
const unsigned char busy;
const unsigned char lda;
unsigned char a;
const unsigned char ldx;
unsigned char x;
const unsigned char rts;
unsigned int sreg;
};
#define RIA (*(volatile struct __RP6502 *)0xFFE0)
#define RIA_READY_TX_BIT 0x80
#define RIA_READY_RX_BIT 0x40
#define RIA_BUSY_BIT 0x80
/* XSTACK helpers */
void __fastcall__ ria_push_long(unsigned long val);
void __fastcall__ ria_push_int(unsigned int val);
#define ria_push_char(v) RIA.xstack = v
long __fastcall__ ria_pop_long(void);
int __fastcall__ ria_pop_int(void);
#define ria_pop_char() RIA.xstack
/* Set the RIA fastcall register */
void __fastcall__ ria_set_axsreg(unsigned long axsreg);
void __fastcall__ ria_set_ax(unsigned int ax);
#define ria_set_a(v) RIA.a = v
/* Run an OS operation */
int __fastcall__ ria_call_int(unsigned char op);
long __fastcall__ ria_call_long(unsigned char op);
/* These run _mappederrno() on error */
int __fastcall__ ria_call_int_errno(unsigned char op);
long __fastcall__ ria_call_long_errno(unsigned char op);
/* OS operation numbers */
#define RIA_OP_EXIT 0xFF
#define RIA_OP_ZXSTACK 0x00
#define RIA_OP_XREG 0x01
#define RIA_OP_PHI2 0x02
#define RIA_OP_CODEPAGE 0x03
#define RIA_OP_LRAND 0x04
#define RIA_OP_STDIN_OPT 0x05
#define RIA_OP_CLOCK_GETRES 0x10
#define RIA_OP_CLOCK_GETTIME 0x11
#define RIA_OP_CLOCK_SETTIME 0x12
#define RIA_OP_CLOCK_GETTIMEZONE 0x13
#define RIA_OP_OPEN 0x14
#define RIA_OP_CLOSE 0x15
#define RIA_OP_READ_XSTACK 0x16
#define RIA_OP_READ_XRAM 0x17
#define RIA_OP_WRITE_XSTACK 0x18
#define RIA_OP_WRITE_XRAM 0x19
#define RIA_OP_LSEEK 0x1A
#define RIA_OP_UNLINK 0x1B
#define RIA_OP_RENAME 0x1C
/* C API for the operating system. */
int __cdecl__ xreg(char device, char channel, unsigned char address, ...);
int __fastcall__ phi2(void);
int __fastcall__ codepage(void);
long __fastcall__ lrand(void);
int __fastcall__ stdin_opt(unsigned long ctrl_bits, unsigned char str_length);
int __fastcall__ read_xstack(void *buf, unsigned count, int fildes);
int __fastcall__ read_xram(unsigned buf, unsigned count, int fildes);
int __fastcall__ write_xstack(const void *buf, unsigned count, int fildes);
int __fastcall__ write_xram(unsigned buf, unsigned count, int fildes);
/* XREG location helpers */
#define xreg_ria_keyboard(...) xreg(0, 0, 0, __VA_ARGS__)
#define xreg_ria_mouse(...) xreg(0, 0, 1, __VA_ARGS__)
#define xreg_vga_canvas(...) xreg(1, 0, 0, __VA_ARGS__)
#define xreg_vga_mode(...) xreg(1, 0, 1, __VA_ARGS__)
/* XRAM structure helpers */
#define xram0_struct_set(addr, type, member, val) \
RIA.addr0 = (unsigned)(&((type *)0)->member) + (unsigned)addr; \
switch (sizeof(((type *)0)->member)) \
{ \
case 1: \
RIA.rw0 = val; \
break; \
case 2: \
RIA.step0 = 1; \
RIA.rw0 = val & 0xff; \
RIA.rw0 = (val >> 8) & 0xff; \
break; \
case 4: \
RIA.step0 = 1; \
RIA.rw0 = (unsigned long)val & 0xff; \
RIA.rw0 = ((unsigned long)val >> 8) & 0xff; \
RIA.rw0 = ((unsigned long)val >> 16) & 0xff; \
RIA.rw0 = ((unsigned long)val >> 24) & 0xff; \
break; \
}
#define xram1_struct_set(addr, type, member, val) \
RIA.addr1 = (unsigned)(&((type *)0)->member) + (unsigned)addr; \
switch (sizeof(((type *)0)->member)) \
{ \
case 1: \
RIA.rw1 = val; \
break; \
case 2: \
RIA.step1 = 1; \
RIA.rw1 = val & 0xff; \
RIA.rw1 = (val >> 8) & 0xff; \
break; \
case 4: \
RIA.step1 = 1; \
RIA.rw1 = (unsigned long)val & 0xff; \
RIA.rw1 = ((unsigned long)val >> 8) & 0xff; \
RIA.rw1 = ((unsigned long)val >> 16) & 0xff; \
RIA.rw1 = ((unsigned long)val >> 24) & 0xff; \
break; \
}
typedef struct
{
unsigned char x_wrap; // bool
unsigned char y_wrap; // bool
int x_pos_px;
int y_pos_px;
int width_chars;
int height_chars;
unsigned xram_data_ptr;
unsigned xram_palette_ptr;
unsigned xram_font_ptr;
} vga_mode1_config_t;
typedef struct
{
unsigned char x_wrap; // bool
unsigned char y_wrap; // bool
int x_pos_px;
int y_pos_px;
int width_tiles;
int height_tiles;
unsigned xram_data_ptr;
unsigned xram_palette_ptr;
unsigned xram_tile_ptr;
} vga_mode2_config_t;
typedef struct
{
unsigned char x_wrap; // bool
unsigned char y_wrap; // bool
int x_pos_px;
int y_pos_px;
int width_px;
int height_px;
unsigned xram_data_ptr;
unsigned xram_palette_ptr;
} vga_mode3_config_t;
typedef struct
{
int x_pos_px;
int y_pos_px;
unsigned xram_sprite_ptr;
unsigned char log_size;
unsigned char has_opacity_metadata; // bool
} vga_mode4_sprite_t;
typedef struct
{
int transform[6];
int x_pos_px;
int y_pos_px;
unsigned xram_sprite_ptr;
unsigned char log_size;
unsigned char has_opacity_metadata; // bool
} vga_mode4_asprite_t;
/* Values in __oserror are the union of these FatFs errors and errno.h */
typedef enum
{
FR_OK = 32, /* Succeeded */
FR_DISK_ERR, /* A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* Assertion failed */
FR_NOT_READY, /* The physical drive cannot work */
FR_NO_FILE, /* Could not find the file */
FR_NO_PATH, /* Could not find the path */
FR_INVALID_NAME, /* The path name format is invalid */
FR_DENIED, /* Access denied due to prohibited access or directory full */
FR_EXIST, /* Access denied due to prohibited access */
FR_INVALID_OBJECT, /* The file/directory object is invalid */
FR_WRITE_PROTECTED, /* The physical drive is write protected */
FR_INVALID_DRIVE, /* The logical drive number is invalid */
FR_NOT_ENABLED, /* The volume has no work area */
FR_NO_FILESYSTEM, /* There is no valid FAT volume */
FR_MKFS_ABORTED, /* The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* Could not get a grant to access the volume within defined period */
FR_LOCKED, /* The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* Given parameter is invalid */
} FRESULT;
#endif /* _RP6502_H */