add rp6502 target

This commit is contained in:
rumbledethumps
2023-11-16 18:46:16 -08:00
parent d7d1d89698
commit b17c4d3434
37 changed files with 1253 additions and 0 deletions

View File

@@ -33,6 +33,7 @@ TARGETS = apple2 \
none \
osic1p \
pce \
rp6502 \
sim6502 \
sim65c02 \
supervision \

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

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <errno.h>
int __fastcall__ close(int fd)
{
ria_set_ax(fd);
return ria_call_int_errno(RIA_OP_CLOSE);
}

14
libsrc/rp6502/codepage.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
int __fastcall__ codepage(void)
{
return ria_call_int(RIA_OP_CODEPAGE);
}

54
libsrc/rp6502/crt0.s Normal file
View File

@@ -0,0 +1,54 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
; Boilerplate crt0.s
.export _init, _exit
.import _main
.export __STARTUP__ : absolute = 1
.import __RAM_START__, __RAM_SIZE__
.import copydata, zerobss, initlib, donelib
.include "rp6502.inc"
.include "zeropage.inc"
.segment "STARTUP"
; Essential 6502 startup the CPU doesn't do
_init:
ldx #$FF
txs
cld
; Set cc65 argument stack pointer
lda #<(__RAM_START__ + __RAM_SIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__)
sta sp+1
; Initialize memory storage
jsr zerobss ; Clear BSS segment
jsr copydata ; Initialize DATA segment
jsr initlib ; Run constructors
; Call main()
jsr _main
; Back from main() also the _exit entry
; Stack the exit value in case destructors call OS
_exit:
phx
pha
jsr donelib ; Run destructors
pla
sta RIA_A
plx
stx RIA_X
lda #$FF ; exit()
sta RIA_OP
stp

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

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <time.h>
extern int __clock_gettimespec(struct timespec *ts, unsigned char op);
int clock_getres(clockid_t clock_id, struct timespec *res)
{
ria_set_ax(clock_id);
return __clock_gettimespec(res, RIA_OP_CLOCK_GETRES);
}

20
libsrc/rp6502/gettime.c Normal file
View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <time.h>
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);
return __clock_gettimespec(tp, RIA_OP_CLOCK_GETTIME);
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <time.h>
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);
if (ax >= 0)
{
ts->tv_sec = ria_pop_long();
ts->tv_nsec = ria_pop_long();
}
return ax;
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <time.h>
int clock_gettimezone(clockid_t clock_id, struct _timezone *tz)
{
int ax;
ria_set_ax(clock_id);
ax = ria_call_int_errno(RIA_OP_CLOCK_GETTIMEZONE);
if (ax >= 0)
{
char i;
for (i = 0; i < sizeof(struct _timezone); i++)
((char *)tz)[i] = ria_pop_char();
}
return ax;
}

16
libsrc/rp6502/initenv.s Normal file
View File

@@ -0,0 +1,16 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
.constructor initenv, 24
.import __environ, __envcount, __envsize
.segment "ONCE"
.proc initenv
rts
.endproc

51
libsrc/rp6502/irq.s Normal file
View File

@@ -0,0 +1,51 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
.export initirq, doneirq
.import callirq, _exit
.include "rp6502.inc"
.segment "ONCE"
initirq:
lda #<handler
ldx #>handler
sei
sta $FFFE
stx $FFFF
cli
rts
.code
doneirq:
sei
rts
.segment "LOWCODE"
handler:
cld
phx
tsx
pha
inx
inx
lda $100,X
and #$10
bne break
phy
jsr callirq
ply
pla
plx
rti
break:
lda #$FF
sta RIA_A
jmp _exit

14
libsrc/rp6502/lrand.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
long __fastcall__ lrand(void)
{
return ria_call_long(RIA_OP_LRAND);
}

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

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <unistd.h>
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);
}

16
libsrc/rp6502/mainargs.s Normal file
View File

@@ -0,0 +1,16 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
.constructor initmainargs, 24
.import __argc, __argv
.segment "ONCE"
.proc initmainargs
rts
.endproc

26
libsrc/rp6502/open.c Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <errno.h>
#include <string.h>
int __cdecl__ open(const char *name, int flags, ...)
{
size_t namelen = strlen(name);
if (namelen > 255)
{
return _mappederrno(EINVAL);
}
while (namelen)
{
ria_push_char(name[--namelen]);
}
ria_set_ax(flags);
return ria_call_int_errno(RIA_OP_OPEN);
}

86
libsrc/rp6502/oserrlist.s Normal file
View File

@@ -0,0 +1,86 @@
;
; 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"

66
libsrc/rp6502/oserror.s Normal file
View File

@@ -0,0 +1,66 @@
;
; 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)

14
libsrc/rp6502/phi2.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
int __fastcall__ phi2(void)
{
return ria_call_int(RIA_OP_PHI2);
}

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

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <stdlib.h>
// Non-standard cc65
void _randomize(void)
{
srand(ria_call_int(RIA_OP_LRAND));
}

31
libsrc/rp6502/read.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <unistd.h>
int __fastcall__ read(int fildes, void *buf, unsigned count)
{
int total = 0;
while (count)
{
unsigned blockcount = (count > 256) ? 256 : count;
int bytes_read = read_xstack(&((char *)buf)[total], blockcount, fildes);
if (bytes_read < 0)
{
return bytes_read;
}
total += bytes_read;
count -= bytes_read;
if (bytes_read < blockcount)
{
break;
}
}
return total;
}

17
libsrc/rp6502/read_xram.c Normal file
View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
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);
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
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);
for (i = 0; i < ax; i++)
{
((char *)buf)[i] = ria_pop_char();
}
return ax;
}

90
libsrc/rp6502/ria.s Normal file
View File

@@ -0,0 +1,90 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
.include "rp6502.inc"
.export _ria_push_long, _ria_push_int
.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 sp, sreg
.import ___mappederrno, incsp1
.code
; void __fastcall__ ria_push_long(unsigned long val);
_ria_push_long:
ldy sreg+1
sty RIA_XSTACK
ldy sreg
sty RIA_XSTACK
; void __fastcall__ ria_push_int(unsigned int val);
_ria_push_int:
stx RIA_XSTACK
sta RIA_XSTACK
rts
; long __fastcall__ ria_pop_long(void);
_ria_pop_long:
jsr _ria_pop_int
ldy RIA_XSTACK
sty sreg
ldy RIA_XSTACK
sty sreg+1
rts
; int __fastcall__ ria_pop_int(void);
_ria_pop_int:
lda RIA_XSTACK
ldx RIA_XSTACK
rts
; void __fastcall__ ria_set_axsreg(unsigned long axsreg);
_ria_set_axsreg:
ldy sreg
sty RIA_SREG
ldy sreg+1
sty RIA_SREG+1
; void __fastcall__ ria_set_ax(unsigned int ax);
_ria_set_ax:
stx RIA_X
sta RIA_A
rts
; int __fastcall__ ria_call_int(unsigned char op);
_ria_call_int:
sta RIA_OP
jmp RIA_SPIN
; long __fastcall__ ria_call_long(unsigned char op);
_ria_call_long:
sta RIA_OP
jsr RIA_SPIN
ldy RIA_SREG
sty sreg
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

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

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <time.h>
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);
}

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

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#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);
}

26
libsrc/rp6502/sysremove.c Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <errno.h>
#include <string.h>
unsigned char __fastcall__ _sysremove(const char *name)
{
size_t namelen;
namelen = strlen(name);
if (namelen > 255)
{
return _mappederrno(EINVAL);
}
while (namelen)
{
ria_push_char(name[--namelen]);
}
return ria_call_int_errno(RIA_OP_UNLINK);
}

32
libsrc/rp6502/sysrename.c Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <errno.h>
#include <string.h>
unsigned char __fastcall__ _sysrename(const char *oldpath, const char *newpath)
{
size_t oldpathlen, newpathlen;
oldpathlen = strlen(oldpath);
newpathlen = strlen(newpath);
if (oldpathlen + newpathlen > 254)
{
return _mappederrno(EINVAL);
}
while (oldpathlen)
{
ria_push_char(oldpath[--oldpathlen]);
}
ria_push_char(0);
while (newpathlen)
{
ria_push_char(newpath[--newpathlen]);
}
return ria_call_int_errno(RIA_OP_RENAME);
}

31
libsrc/rp6502/write.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
#include <unistd.h>
int __fastcall__ write(int fildes, const void *buf, unsigned count)
{
int ax, total = 0;
while (count)
{
int blockcount = (count > 256) ? 256 : count;
ax = write_xstack(&((char *)buf)[total], blockcount, fildes);
if (ax < 0)
{
return ax;
}
total += ax;
count -= ax;
if (ax < blockcount)
{
break;
}
}
return total;
}

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
int __fastcall__ write_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_WRITE_XRAM);
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023 Rumbledethumps
*
* SPDX-License-Identifier: Zlib
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: Unlicense
*/
#include <rp6502.h>
int __fastcall__ write_xstack(const void *buf, unsigned count, int fildes)
{
unsigned i;
for (i = count; i;)
{
ria_push_char(((char *)buf)[--i]);
}
ria_set_ax(fildes);
return ria_call_int_errno(RIA_OP_WRITE_XSTACK);
}

40
libsrc/rp6502/xreg.s Normal file
View File

@@ -0,0 +1,40 @@
; Copyright (c) 2023 Rumbledethumps
;
; SPDX-License-Identifier: Zlib
; SPDX-License-Identifier: BSD-3-Clause
; SPDX-License-Identifier: Unlicense
; CC65 will promote variadic char arguments to int. It will not demote longs.
; int __cdecl__ xreg(char device, char channel, unsigned char address, ...);
.export _xreg
.importzp sp
.import addysp, _ria_call_int_errno
.include "rp6502.inc"
.code
.proc _xreg
; save variadic size in X
tya
tax
@copy: ; copy stack
dey
lda (sp),y
sta RIA_XSTACK
tya
bne @copy
; recover variadic size and move sp
txa
tay
jsr addysp
; run RIA operation
lda #RIA_OP_XREG
jmp _ria_call_int_errno
.endproc