Merge pull request #2844 from picocomputer/master

Support for RP6502 Version 0.14
This commit is contained in:
Bob Andrews
2025-11-03 13:39:25 +01:00
committed by GitHub
48 changed files with 456 additions and 274 deletions

14
libsrc/rp6502/chdir.s Normal file
View File

@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 2003-08-12
;
; int __fastcall__ chdir (const char* name);
;
.export _chdir
.import __syschdir
;--------------------------------------------------------------------------
_chdir = __syschdir

View File

@@ -1,8 +1,8 @@
#include <rp6502.h>
#include <errno.h>
#include <fcntl.h>
int __fastcall__ close (int fd)
{
ria_set_ax (fd);
return ria_call_int_errno (RIA_OP_CLOSE);
return ria_call_int (RIA_OP_CLOSE);
}

View File

@@ -0,0 +1,7 @@
#include <rp6502.h>
int __fastcall__ code_page (int cp)
{
ria_set_ax (cp);
return ria_call_int (RIA_OP_CODE_PAGE);
}

View File

@@ -1,6 +0,0 @@
#include <rp6502.h>
int __fastcall__ codepage (void)
{
return ria_call_int (RIA_OP_CODEPAGE);
}

View File

@@ -46,6 +46,6 @@ _exit:
sta RIA_A
plx
stx RIA_X
lda #$FF ; exit()
lda #RIA_OP_EXIT
sta RIA_OP
stp

25
libsrc/rp6502/errno.s Normal file
View File

@@ -0,0 +1,25 @@
;
; 2003-08-12, Ullrich von Bassewitz
; 2015-09-24, Greg King
;
; extern int __errno;
; /* Library errors go here. */
;
.include "rp6502.inc"
.include "errno.inc"
.export ___errno
.import _ria_call_int
.constructor _errno_opt_constructor
; The errno on the RIA is the errno for cc65
___errno := RIA_ERRNO
.code
; Request the RIA use cc65 values for RIA_ERRNO
_errno_opt_constructor:
lda #$01 ; 1 = cc65
sta RIA_A
lda #RIA_OP_ERRNO_OPT
jmp _ria_call_int

16
libsrc/rp6502/f_chdrive.c Normal file
View File

@@ -0,0 +1,16 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_chdrive (const char* name)
{
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int (RIA_OP_CHDRIVE);
}

19
libsrc/rp6502/f_chmod.c Normal file
View File

@@ -0,0 +1,19 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_chmod (const char* path, unsigned char attr, unsigned char mask)
{
size_t pathlen;
ria_set_a (mask);
pathlen = strlen (path);
if (pathlen > 255) {
errno = EINVAL;
return -1;
}
while (pathlen) {
ria_push_char (path[--pathlen]);
}
ria_push_char (attr);
return ria_call_int (RIA_OP_CHMOD);
}

View File

@@ -0,0 +1,7 @@
#include <rp6502.h>
int __fastcall__ f_closedir (int dirdes)
{
ria_set_ax (dirdes);
return ria_call_int (RIA_OP_CLOSEDIR);
}

18
libsrc/rp6502/f_getcwd.c Normal file
View File

@@ -0,0 +1,18 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_getcwd (char* name, int size)
{
int i, ax;
ax = ria_call_int (RIA_OP_GETCWD);
if (ax > size) {
RIA.op = RIA_OP_ZXSTACK;
errno = ENOMEM;
return -1;
}
for (i = 0; i < ax; i++) {
name[i] = ria_pop_char ();
}
return ax;
}

22
libsrc/rp6502/f_getfree.c Normal file
View File

@@ -0,0 +1,22 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_getfree (const char* name, unsigned long* free, unsigned long* total)
{
int ax;
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
ax = ria_call_int (RIA_OP_GETFREE);
if (ax >= 0) {
*free = ria_pop_long ();
*total = ria_pop_long ();
}
return ax;
}

View File

@@ -0,0 +1,21 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_getlabel (const char* path, char* label)
{
int i, ax;
size_t pathlen = strlen (path);
if (pathlen > 255) {
errno = EINVAL;
return -1;
}
while (pathlen) {
ria_push_char (path[--pathlen]);
}
ax = ria_call_int (RIA_OP_GETLABEL);
for (i = 0; i < ax; i++) {
label[i] = ria_pop_char ();
}
return ax;
}

9
libsrc/rp6502/f_lseek.c Normal file
View File

@@ -0,0 +1,9 @@
#include <rp6502.h>
long __fastcall__ f_lseek (long offset, int whence, int fildes)
{
ria_set_ax (fildes);
ria_push_long (offset);
ria_push_char (whence);
return ria_call_long (RIA_OP_LSEEK);
}

16
libsrc/rp6502/f_mkdir.c Normal file
View File

@@ -0,0 +1,16 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_mkdir (const char* name)
{
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int (RIA_OP_MKDIR);
}

16
libsrc/rp6502/f_opendir.c Normal file
View File

@@ -0,0 +1,16 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_opendir (const char* name)
{
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int (RIA_OP_OPENDIR);
}

12
libsrc/rp6502/f_readdir.c Normal file
View File

@@ -0,0 +1,12 @@
#include <rp6502.h>
int __fastcall__ f_readdir (f_stat_t* dirent, int dirdes)
{
int i, ax;
ria_set_ax (dirdes);
ax = ria_call_int (RIA_OP_READDIR);
for (i = 0; i < sizeof (f_stat_t); i++) {
((char*)dirent)[i] = ria_pop_char ();
}
return ax;
}

View File

@@ -0,0 +1,7 @@
#include <rp6502.h>
int __fastcall__ f_rewinddir (int dirdes)
{
ria_set_ax (dirdes);
return ria_call_int (RIA_OP_REWINDDIR);
}

View File

@@ -0,0 +1,8 @@
#include <rp6502.h>
int __fastcall__ f_seekdir (long offs, int dirdes)
{
ria_set_ax (dirdes);
ria_push_long (offs);
return ria_call_int (RIA_OP_SEEKDIR);
}

View File

@@ -0,0 +1,16 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_setlabel (const char* name)
{
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int (RIA_OP_SETLABEL);
}

21
libsrc/rp6502/f_stat.c Normal file
View File

@@ -0,0 +1,21 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_stat (const char* path, f_stat_t* dirent)
{
int i, ax;
size_t pathlen = strlen (path);
if (pathlen > 255) {
errno = EINVAL;
return -1;
}
while (pathlen) {
ria_push_char (path[--pathlen]);
}
ax = ria_call_int (RIA_OP_STAT);
for (i = 0; i < sizeof (f_stat_t); i++) {
((char*)dirent)[i] = ria_pop_char ();
}
return ax;
}

View File

@@ -0,0 +1,7 @@
#include <rp6502.h>
long __fastcall__ f_telldir (int dirdes)
{
ria_set_ax (dirdes);
return ria_call_long (RIA_OP_TELLDIR);
}

21
libsrc/rp6502/f_utime.c Normal file
View File

@@ -0,0 +1,21 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ f_utime (const char* path, unsigned fdate, unsigned ftime, unsigned crdate, unsigned crtime)
{
size_t pathlen;
ria_set_ax (crtime);
pathlen = strlen (path);
if (pathlen > 255) {
errno = EINVAL;
return -1;
}
while (pathlen) {
ria_push_char (path[--pathlen]);
}
ria_push_int (fdate);
ria_push_int (ftime);
ria_push_int (crdate);
return ria_call_int (RIA_OP_UTIME);
}

View File

@@ -5,8 +5,6 @@ extern int __clock_gettimespec (struct timespec* ts, unsigned char op);
int clock_gettime (clockid_t clock_id, struct timespec* tp)
{
(void)clock_id;
/* time.s doesn't set the stack value for clock_id (bug?) */
ria_set_ax (CLOCK_REALTIME);
ria_set_ax (clock_id);
return __clock_gettimespec (tp, RIA_OP_CLOCK_GETTIME);
}

View File

@@ -4,7 +4,7 @@
int __clock_gettimespec (struct timespec* ts, unsigned char op)
/* Internal method shared by clock_getres and clock_gettime. */
{
int ax = ria_call_int_errno (op);
int ax = ria_call_int (op);
if (ax >= 0) {
ts->tv_sec = ria_pop_long ();
ts->tv_nsec = ria_pop_long ();

View File

@@ -1,11 +1,12 @@
#include <rp6502.h>
#include <time.h>
int clock_gettimezone (clockid_t clock_id, struct _timezone* tz)
int clock_gettimezone (time_t time, clockid_t clock_id, struct _timezone* tz)
{
int ax;
ria_set_ax (clock_id);
ax = ria_call_int_errno (RIA_OP_CLOCK_GETTIMEZONE);
ria_push_long (time);
ax = ria_call_int (RIA_OP_CLOCK_GETTIMEZONE);
if (ax >= 0) {
char i;
for (i = 0; i < sizeof (struct _timezone); i++) {

View File

@@ -3,9 +3,8 @@
off_t __fastcall__ lseek (int fd, off_t offset, int whence)
{
/* Modified argument order for short stacking offset */
ria_push_long (offset);
ria_push_char (whence);
ria_set_ax (fd);
return ria_call_long_errno (RIA_OP_LSEEK);
return ria_call_long (RIA_OP_LSEEK);
}

View File

@@ -1,16 +1,18 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
int __cdecl__ open (const char* name, int flags, ...)
{
size_t namelen = strlen (name);
if (namelen > 255) {
return _mappederrno (EINVAL);
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
ria_set_ax (flags);
return ria_call_int_errno (RIA_OP_OPEN);
return ria_call_int (RIA_OP_OPEN);
}

View File

@@ -1,86 +0,0 @@
;
; 2002-07-18, Ullrich von Bassewitz
; 2022, ChaN
; 2023, Rumbledethumps
;
; Defines the platform-specific error list.
;
; The table is built as a list of entries:
;
; .byte entrylen
; .byte errorcode
; .asciiz errormsg
;
; and, terminated by an entry with length zero that is returned if the
; error code could not be found.
;
.export __sys_oserrlist
.include "rp6502.inc"
.include "errno.inc"
;----------------------------------------------------------------------------
; Macros used to generate the list (may get moved to an include file?)
; Regular entry
.macro sys_oserr_entry code, msg
.local Start, End
Start:
.byte End - Start
.byte code
.asciiz msg
End:
.endmacro
; Sentinel entry
.macro sys_oserr_sentinel msg
.byte 0 ; Length is always zero
.byte 0 ; Code is unused
.asciiz msg
.endmacro
;----------------------------------------------------------------------------
; The error message table
.rodata
__sys_oserrlist:
sys_oserr_entry ENOENT , "No such file or directory"
sys_oserr_entry ENOMEM , "Out of memory"
sys_oserr_entry EACCES , "Permission denied"
sys_oserr_entry ENODEV , "No such device"
sys_oserr_entry EMFILE , "Too many open files"
sys_oserr_entry EBUSY , "Device or resource busy"
sys_oserr_entry EINVAL , "Invalid argument"
sys_oserr_entry ENOSPC , "No space left on device"
sys_oserr_entry EEXIST , "File exists"
sys_oserr_entry EAGAIN , "Try again"
sys_oserr_entry EIO , "I/O error"
sys_oserr_entry EINTR , "Interrupted system call"
sys_oserr_entry ENOSYS , "Function not implemented"
sys_oserr_entry ESPIPE , "Illegal seek"
sys_oserr_entry ERANGE , "Range error"
sys_oserr_entry EBADF , "Bad file number"
sys_oserr_entry ENOEXEC , "Exec format error"
sys_oserr_entry EUNKNOWN , "Unknown OS specific error"
sys_oserr_entry FR_DISK_ERR , "A hard error occurred in the low level disk I/O layer"
sys_oserr_entry FR_INT_ERR , "Assertion failed"
sys_oserr_entry FR_NOT_READY , "The physical drive cannot work"
sys_oserr_entry FR_NO_FILE , "Could not find the file"
sys_oserr_entry FR_NO_PATH , "Could not find the path"
sys_oserr_entry FR_INVALID_NAME , "The path name format is invalid"
sys_oserr_entry FR_DENIED , "Access denied due to prohibited access or directory full"
sys_oserr_entry FR_EXIST , "Access denied due to prohibited access"
sys_oserr_entry FR_INVALID_OBJECT , "The file/directory object is invalid"
sys_oserr_entry FR_WRITE_PROTECTED , "The physical drive is write protected"
sys_oserr_entry FR_INVALID_DRIVE , "The logical drive number is invalid"
sys_oserr_entry FR_NOT_ENABLED , "The volume has no work area"
sys_oserr_entry FR_NO_FILESYSTEM , "There is no valid FAT volume"
sys_oserr_entry FR_MKFS_ABORTED , "The f_mkfs() aborted due to any problem"
sys_oserr_entry FR_TIMEOUT , "Could not get a grant to access the volume within defined period"
sys_oserr_entry FR_LOCKED , "The operation is rejected according to the file sharing policy"
sys_oserr_entry FR_NOT_ENOUGH_CORE , "LFN working buffer could not be allocated"
sys_oserr_entry FR_TOO_MANY_OPEN_FILES , "Number of open files > FF_FS_LOCK"
sys_oserr_entry FR_INVALID_PARAMETER , "Given parameter is invalid"
sys_oserr_sentinel "Unknown error"

View File

@@ -1,66 +0,0 @@
;
; 2000-05-17, Ullrich von Bassewitz
; 2022, ChaN
; 2023, Rumbledethumps
;
; int __fastcall__ __osmaperrno (unsigned char oserror);
;
; RP6502 will respond with a union of CC65 and FatFs errnos.
; This will map FatFs errors into the CC65 range for portable code.
EFATFS_START := 32
.include "rp6502.inc"
.include "errno.inc"
.code
___osmaperrno:
cmp #EFATFS_START
bmi @L2
ldx #ErrTabSize
@L1:
cmp ErrTab-2,x ; Search for the error code
beq @L3 ; Jump if found
dex
dex
bne @L1 ; Next entry
; Code not found, return EUNKNOWN
lda #<EUNKNOWN
ldx #>EUNKNOWN
@L2:
rts
; Found the code
@L3:
lda ErrTab-1,x
ldx #$00 ; High byte always zero
rts
.rodata
ErrTab:
.byte FR_DISK_ERR , EIO ; A hard error occurred in the low level disk I/O layer
; .byte FR_INT_ERR , EUNKNOWN ; Assertion failed
.byte FR_NOT_READY , EBUSY ; The physical drive cannot work
.byte FR_NO_FILE , ENOENT ; Could not find the file
.byte FR_NO_PATH , ENOENT ; Could not find the path
.byte FR_INVALID_NAME , EINVAL ; The path name format is invalid
.byte FR_DENIED , EACCES ; Access denied due to prohibited access or directory full
.byte FR_EXIST , EEXIST ; Access denied due to prohibited access
.byte FR_INVALID_OBJECT , EINVAL ; The file/directory object is invalid
.byte FR_WRITE_PROTECTED , EACCES ; The physical drive is write protected
.byte FR_INVALID_DRIVE , ENODEV ; The logical drive number is invalid
; .byte FR_NOT_ENABLED , EUNKNOWN ; The volume has no work area
; .byte FR_NO_FILESYSTEM , EUNKNOWN ; There is no valid FAT volume
; .byte FR_MKFS_ABORTED , EUNKNOWN ; The f_mkfs() aborted due to any problem
; .byte FR_TIMEOUT , EUNKNOWN ; Could not get a grant to access the volume within defined period
.byte FR_LOCKED , EBUSY ; The operation is rejected according to the file sharing policy
.byte FR_NOT_ENOUGH_CORE , ENOMEM ; LFN working buffer could not be allocated
.byte FR_TOO_MANY_OPEN_FILES , EMFILE ; Number of open files > FF_FS_LOCK
.byte FR_INVALID_PARAMETER , EINVAL ; Given parameter is invalid
ErrTabSize = (* - ErrTab)

View File

@@ -5,5 +5,5 @@ int __fastcall__ read_xram (unsigned buf, unsigned count, int fildes)
ria_push_int (buf);
ria_push_int (count);
ria_set_ax (fildes);
return ria_call_int_errno (RIA_OP_READ_XRAM);
return ria_call_int (RIA_OP_READ_XRAM);
}

View File

@@ -5,7 +5,7 @@ int __fastcall__ read_xstack (void* buf, unsigned count, int fildes)
int i, ax;
ria_push_int (count);
ria_set_ax (fildes);
ax = ria_call_int_errno (RIA_OP_READ_XSTACK);
ax = ria_call_int (RIA_OP_READ_XSTACK);
for (i = 0; i < ax; i++) {
((char*)buf)[i] = ria_pop_char ();
}

14
libsrc/rp6502/remove.s Normal file
View File

@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 2003-08-12
;
; int __fastcall__ remove (const char* name);
;
.export _remove
.import __sysremove
;--------------------------------------------------------------------------
_remove = __sysremove

14
libsrc/rp6502/rename.s Normal file
View File

@@ -0,0 +1,14 @@
;
; Ullrich von Bassewitz, 2003-08-12
;
; int __fastcall__ rename (const char* oldname, const char* newname);
;
.export _rename
.import __sysrename
;--------------------------------------------------------------------------
_rename = __sysrename

View File

@@ -9,10 +9,8 @@
.export _ria_pop_long, _ria_pop_int
.export _ria_set_axsreg, _ria_set_ax
.export _ria_call_int, _ria_call_long
.export _ria_call_int_errno, _ria_call_long_errno
.importzp c_sp, sreg
.import ___mappederrno, incsp1
.importzp sreg
.code
@@ -69,21 +67,3 @@ _ria_call_long:
ldy RIA_SREG+1
sty sreg+1
rts
; int __fastcall__ ria_call_int_errno(unsigned char op);
_ria_call_int_errno:
sta RIA_OP
jsr RIA_SPIN
ldx RIA_X
bmi ERROR
rts
; long __fastcall__ ria_call_long_errno(unsigned char op);
_ria_call_long_errno:
jsr _ria_call_long
bmi ERROR
rts
ERROR:
lda RIA_ERRNO
jmp ___mappederrno

View File

@@ -0,0 +1,9 @@
#include <rp6502.h>
#include <time.h>
int clock_gettimezone (time_t time, clockid_t clock_id, struct _timezone* tz);
void ria_tzset (unsigned long time)
{
clock_gettimezone (time, CLOCK_REALTIME, &_tz);
}

View File

@@ -6,5 +6,5 @@ int clock_settime (clockid_t clock_id, const struct timespec* tp)
ria_set_ax (clock_id);
ria_push_long (tp->tv_nsec);
ria_push_long (tp->tv_sec);
return ria_call_int_errno (RIA_OP_CLOCK_SETTIME);
return ria_call_int (RIA_OP_CLOCK_SETTIME);
}

View File

@@ -1,9 +1,8 @@
#include <rp6502.h>
int __fastcall__ stdin_opt (unsigned long ctrl_bits, unsigned char str_length)
{
ria_push_long (ctrl_bits);
ria_set_a (str_length);
return ria_call_int_errno (RIA_OP_STDIN_OPT);
return ria_call_int (RIA_OP_STDIN_OPT);
}

8
libsrc/rp6502/syncfs.c Normal file
View File

@@ -0,0 +1,8 @@
#include <rp6502.h>
#include <unistd.h>
int __fastcall__ syncfs (int fd)
{
ria_set_ax (fd);
return ria_call_int (RIA_OP_SYNCFS);
}

16
libsrc/rp6502/syschdir.c Normal file
View File

@@ -0,0 +1,16 @@
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __fastcall__ _syschdir (const char* name)
{
size_t namelen = strlen (name);
if (namelen > 255) {
errno = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int (RIA_OP_CHDIR);
}

View File

@@ -2,15 +2,16 @@
#include <errno.h>
#include <string.h>
unsigned char __fastcall__ _sysremove (const char* name)
int __fastcall__ _sysremove (const char* name)
{
size_t namelen;
namelen = strlen (name);
if (namelen > 255) {
return _mappederrno (EINVAL);
RIA.errno_ = EINVAL;
return -1;
}
while (namelen) {
ria_push_char (name[--namelen]);
}
return ria_call_int_errno (RIA_OP_UNLINK);
return ria_call_int (RIA_OP_UNLINK);
}

View File

@@ -2,13 +2,14 @@
#include <errno.h>
#include <string.h>
unsigned char __fastcall__ _sysrename (const char* oldpath, const char* newpath)
int __fastcall__ _sysrename (const char* oldpath, const char* newpath)
{
size_t oldpathlen, newpathlen;
oldpathlen = strlen (oldpath);
newpathlen = strlen (newpath);
if (oldpathlen + newpathlen > 510) {
return _mappederrno (EINVAL);
errno = EINVAL;
return -1;
}
while (oldpathlen) {
ria_push_char (oldpath[--oldpathlen]);
@@ -17,5 +18,5 @@ unsigned char __fastcall__ _sysrename (const char* oldpath, const char* newpath)
while (newpathlen) {
ria_push_char (newpath[--newpathlen]);
}
return ria_call_int_errno (RIA_OP_RENAME);
return ria_call_int (RIA_OP_RENAME);
}

View File

@@ -2,8 +2,8 @@
int __fastcall__ write_xram (unsigned buf, unsigned count, int fildes)
{
ria_set_ax (fildes);
ria_push_int (buf);
ria_push_int (count);
ria_set_ax (fildes);
return ria_call_int_errno (RIA_OP_WRITE_XRAM);
return ria_call_int (RIA_OP_WRITE_XRAM);
}

View File

@@ -5,11 +5,12 @@ int __fastcall__ write_xstack (const void* buf, unsigned count, int fildes)
{
unsigned i;
if (count > 512) {
return _mappederrno (EINVAL);
errno = EINVAL;
return -1;
}
for (i = count; i;) {
ria_push_char (((char*)buf)[--i]);
}
ria_set_ax (fildes);
return ria_call_int_errno (RIA_OP_WRITE_XSTACK);
return ria_call_int (RIA_OP_WRITE_XSTACK);
}

View File

@@ -6,7 +6,7 @@
.export _xreg
.importzp c_sp
.import addysp, _ria_call_int_errno
.import addysp, _ria_call_int
.include "rp6502.inc"
@@ -32,6 +32,6 @@
; run RIA operation
lda #RIA_OP_XREG
jmp _ria_call_int_errno
jmp _ria_call_int
.endproc

View File

@@ -15,5 +15,5 @@ int __cdecl__ xregn (char device, char channel, unsigned char address, unsigned
RIA.xstack = v;
}
va_end (args);
return ria_call_int_errno (RIA_OP_XREG);
return ria_call_int (RIA_OP_XREG);
}