mirror of https://github.com/cc65/cc65.git
247 lines
8.4 KiB
C
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 */
|