add rp6502 target
This commit is contained in:
@@ -33,6 +33,7 @@ TARGETS = apple2 \
|
||||
none \
|
||||
osic1p \
|
||||
pce \
|
||||
rp6502 \
|
||||
sim6502 \
|
||||
sim65c02 \
|
||||
supervision \
|
||||
|
||||
16
libsrc/rp6502/close.c
Normal file
16
libsrc/rp6502/close.c
Normal 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
14
libsrc/rp6502/codepage.c
Normal 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
54
libsrc/rp6502/crt0.s
Normal 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
18
libsrc/rp6502/getres.c
Normal 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
20
libsrc/rp6502/gettime.c
Normal 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);
|
||||
}
|
||||
22
libsrc/rp6502/gettimespec.c
Normal file
22
libsrc/rp6502/gettimespec.c
Normal 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;
|
||||
}
|
||||
24
libsrc/rp6502/gettimezone.c
Normal file
24
libsrc/rp6502/gettimezone.c
Normal 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
16
libsrc/rp6502/initenv.s
Normal 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
51
libsrc/rp6502/irq.s
Normal 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
14
libsrc/rp6502/lrand.c
Normal 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
19
libsrc/rp6502/lseek.c
Normal 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
16
libsrc/rp6502/mainargs.s
Normal 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
26
libsrc/rp6502/open.c
Normal 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
86
libsrc/rp6502/oserrlist.s
Normal 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
66
libsrc/rp6502/oserror.s
Normal 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
14
libsrc/rp6502/phi2.c
Normal 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
16
libsrc/rp6502/randomize.c
Normal 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
31
libsrc/rp6502/read.c
Normal 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
17
libsrc/rp6502/read_xram.c
Normal 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);
|
||||
}
|
||||
22
libsrc/rp6502/read_xstack.c
Normal file
22
libsrc/rp6502/read_xstack.c
Normal 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
90
libsrc/rp6502/ria.s
Normal 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
18
libsrc/rp6502/settime.c
Normal 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
16
libsrc/rp6502/stdin_opt.c
Normal 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
26
libsrc/rp6502/sysremove.c
Normal 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
32
libsrc/rp6502/sysrename.c
Normal 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
31
libsrc/rp6502/write.c
Normal 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;
|
||||
}
|
||||
17
libsrc/rp6502/write_xram.c
Normal file
17
libsrc/rp6502/write_xram.c
Normal 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);
|
||||
}
|
||||
20
libsrc/rp6502/write_xstack.c
Normal file
20
libsrc/rp6502/write_xstack.c
Normal 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
40
libsrc/rp6502/xreg.s
Normal 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
|
||||
Reference in New Issue
Block a user