Skip to content

enable stdio on rp6502 target #395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mos-platform/rp6502/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ add_platform_library(rp6502-c
lrand.c
lseek.c
open.c
oserror.s
phi2.c
putchar.c
read_xram.c
read_xstack.c
read.c
ria.s
stdin_opt.c
sysremove.c
sysrename.c
Expand Down
9 changes: 2 additions & 7 deletions mos-platform/rp6502/clock.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#include <rp6502.h>
#include "rp6502.h"
#include <time.h>

long clock(void) {
RIA.op = RIA_OP_CLOCK;
while (RIA.busy & RIA_BUSY_BIT)
;
return (long)RIA.a | ((long)RIA.x << 8) | ((long)RIA.sreg << 16);
}
long clock(void) { return ria_call_long(RIA_OP_CLOCK); }
19 changes: 5 additions & 14 deletions mos-platform/rp6502/clock_getres.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
#include <rp6502.h>
#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.a = clock_id;
RIA.x = clock_id >> 8;
RIA.op = RIA_OP_CLOCK_GETRES;
while (RIA.busy & RIA_BUSY_BIT)
;
int ax = RIA.a | (RIA.x << 8);
if (ax >= 0) {
res->tv_sec = (long)RIA.xstack | ((long)RIA.xstack << 8) |
((long)RIA.xstack << 16) | ((long)RIA.xstack << 24);
res->tv_nsec = (long)RIA.xstack | ((long)RIA.xstack << 8) |
((long)RIA.xstack << 16) | ((long)RIA.xstack << 24);
}
return ax;
ria_set_ax(clock_id);
return __clock_gettimespec(res, RIA_OP_CLOCK_GETRES);
}
21 changes: 6 additions & 15 deletions mos-platform/rp6502/clock_gettime.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
#include <rp6502.h>
#include "rp6502.h"
#include <time.h>

int clock_gettime(clockid_t clock_id, struct timespec *res) {
RIA.a = clock_id;
RIA.x = clock_id >> 8;
RIA.op = RIA_OP_CLOCK_GETTIME;
while (RIA.busy & RIA_BUSY_BIT)
;
int ax = RIA.a | (RIA.x << 8);
if (ax >= 0) {
res->tv_sec = RIA.xstack | (RIA.xstack << 8) | ((long)RIA.xstack << 16) |
((long)RIA.xstack << 24);
res->tv_nsec = RIA.xstack | (RIA.xstack << 8) | ((long)RIA.xstack << 16) |
((long)RIA.xstack << 24);
}
return ax;
extern int __clock_gettimespec(struct timespec *ts, unsigned char op);

int clock_gettime(clockid_t clock_id, struct timespec *tp) {
ria_set_ax(clock_id);
return __clock_gettimespec(tp, RIA_OP_CLOCK_GETTIME);
}
13 changes: 13 additions & 0 deletions mos-platform/rp6502/clock_gettimespec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#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;
}
20 changes: 5 additions & 15 deletions mos-platform/rp6502/clock_settime.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
#include <rp6502.h>
#include "rp6502.h"
#include <time.h>

int clock_settime(clockid_t clock_id, const struct timespec *tp) {
RIA.a = clock_id;
RIA.x = clock_id >> 8;
RIA.xstack = tp->tv_nsec >> 24;
RIA.xstack = tp->tv_nsec >> 16;
RIA.xstack = tp->tv_nsec >> 8;
RIA.xstack = tp->tv_nsec;
RIA.xstack = tp->tv_sec >> 24;
RIA.xstack = tp->tv_sec >> 16;
RIA.xstack = tp->tv_sec >> 8;
RIA.xstack = tp->tv_sec;
RIA.op = RIA_OP_CLOCK_SETTIME;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
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);
}
11 changes: 4 additions & 7 deletions mos-platform/rp6502/close.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#include <rp6502.h>
#include <fcntl.h>
#include "rp6502.h"

int close(int fd) {
RIA.a = fd;
RIA.x = fd >> 8;
RIA.op = RIA_OP_CLOSE;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
ria_set_ax(fd);
return ria_call_int_errno(RIA_OP_CLOSE);
}
7 changes: 1 addition & 6 deletions mos-platform/rp6502/codepage.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#include "rp6502.h"

int codepage(void) {
RIA.op = RIA_OP_CODEPAGE;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
}
int codepage(void) { return ria_call_int(RIA_OP_CODEPAGE); }
3 changes: 1 addition & 2 deletions mos-platform/rp6502/exit.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "rp6502.h"

void _Exit(int status) {
RIA.a = status;
RIA.x = status >> 8;
ria_set_ax(status);
RIA.op = RIA_OP_EXIT;
}
10 changes: 4 additions & 6 deletions mos-platform/rp6502/getchar.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#include "rp6502.h"
#include <stdio.h>
#include <unistd.h>

int __getchar(void) {
RIA.xstack = 1;
RIA.a = 0;
RIA.op = RIA_OP_READ_XSTACK;
while (RIA.busy & RIA_BUSY_BIT)
;
if (RIA.a)
ria_push_char(1);
ria_set_a(STDIN_FILENO);
if (ria_call_int_errno(RIA_OP_READ_XSTACK) == 1)
return RIA.xstack;
return EOF;
}
7 changes: 1 addition & 6 deletions mos-platform/rp6502/lrand.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#include "rp6502.h"

long lrand(void) {
RIA.op = RIA_OP_LRAND;
while (RIA.busy & RIA_BUSY_BIT)
;
return (long)RIA.a | ((long)RIA.x << 8) | ((long)RIA.sreg << 16);
}
long lrand(void) { return ria_call_long(RIA_OP_LRAND); }
34 changes: 21 additions & 13 deletions mos-platform/rp6502/lseek.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#include <rp6502.h>
#include "rp6502.h"
#include <stdio.h>
#include <unistd.h>

long lseek(int fd, long offset, int whence) {
RIA.a = fd;
RIA.x = fd >> 8;
RIA.xstack = offset >> 24;
RIA.xstack = offset >> 16;
RIA.xstack = offset >> 8;
RIA.xstack = offset;
RIA.xstack = whence;
RIA.op = RIA_OP_LSEEK;
while (RIA.busy & RIA_BUSY_BIT)
;
return (long)RIA.a | ((long)RIA.x << 8) | ((long)RIA.sreg << 16);
off_t lseek(int fd, off_t offset, int whence) {
switch (whence) {
case SEEK_CUR:
ria_push_char(RIA_SEEK_CUR);
break;
case SEEK_END:
ria_push_char(RIA_SEEK_END);
break;
case SEEK_SET:
ria_push_char(RIA_SEEK_SET);
break;
default:
ria_push_int(whence);
break;
}
ria_push_long(offset);
ria_set_ax(fd);
return ria_call_long_errno(RIA_OP_LSEEK);
}
17 changes: 8 additions & 9 deletions mos-platform/rp6502/open.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
#include <errno.h>
#include <rp6502.h>
#include <fcntl.h>
#include "rp6502.h"
#include <string.h>

int __mappederrno(unsigned char code);

int open(const char *name, int flags, ...) {
size_t namelen = strlen(name);
if (namelen > 255) {
RIA.errno = EINVAL;
return -1;
return __mappederrno(RIA.errno);
}
while (namelen)
RIA.xstack = name[--namelen];
RIA.a = flags;
RIA.x = flags >> 8;
RIA.op = RIA_OP_OPEN;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
ria_push_char(name[--namelen]);
ria_set_ax(flags);
return ria_call_int_errno(RIA_OP_OPEN);
}
82 changes: 82 additions & 0 deletions mos-platform/rp6502/oserror.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
; Copyright 2024 LLVM-MOS Project
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions.
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license
; information.

; Originally from cc65. Modified from original version.

;
; 2000-05-17, Ullrich von Bassewitz
; 2014-05-28, Greg King
;
; int __osmaperrno (unsigned char oserror);
; /* Map a system-specific error into a system-independent code. */
;

.include "errno.inc"
.include "rp6502.inc"

.text
.globl __osmaperrno
__osmaperrno:
ldx #ErrTabSize
1: cmp ErrTab-2,x ; Search for the error code
beq 1f ; Jump if found
dex
dex
bne 1b ; Next entry

; Code not found, return EUNKNOWN

lda #<EUNKNOWN
ldx #>EUNKNOWN
rts

; Found the code

1: lda ErrTab-1,x
ldx #$00 ; High byte always zero
rts

.rodata

ErrTab:
.byte RIA_ENOENT , ENOENT
.byte RIA_ENOMEM , ENOMEM
.byte RIA_EACCES , EACCES
.byte RIA_ENODEV , ENODEV
.byte RIA_EMFILE , EMFILE
.byte RIA_EBUSY , EBUSY
.byte RIA_EINVAL , EINVAL
.byte RIA_ENOSPC , ENOSPC
.byte RIA_EEXIST , EEXIST
.byte RIA_EAGAIN , EAGAIN
.byte RIA_EIO , EIO
.byte RIA_EINTR , EINTR
.byte RIA_ENOSYS , ENOSYS
.byte RIA_ESPIPE , ESPIPE
.byte RIA_ERANGE , ERANGE
.byte RIA_EBADF , EBADF
.byte RIA_ENOEXEC , ENOEXEC
; .byte RIA_EUNKNOWN , EUNKNOWN
.byte FR_DISK_ERR , EIO
; .byte FR_INT_ERR , EUNKNOWN
.byte FR_NOT_READY , EBUSY
.byte FR_NO_FILE , ENOENT
.byte FR_NO_PATH , ENOENT
.byte FR_INVALID_NAME , EINVAL
.byte FR_DENIED , EACCES
.byte FR_EXIST , EEXIST
.byte FR_INVALID_OBJECT , EINVAL
.byte FR_WRITE_PROTECTED , EACCES
.byte FR_INVALID_DRIVE , ENODEV
; .byte FR_NOT_ENABLED , EUNKNOWN
; .byte FR_NO_FILESYSTEM , EUNKNOWN
; .byte FR_MKFS_ABORTED , EUNKNOWN
; .byte FR_TIMEOUT , EUNKNOWN
.byte FR_LOCKED , EBUSY
.byte FR_NOT_ENOUGH_CORE , ENOMEM
.byte FR_TOO_MANY_OPEN_FILES , EMFILE
.byte FR_INVALID_PARAMETER , EINVAL

ErrTabSize = . - ErrTab
7 changes: 1 addition & 6 deletions mos-platform/rp6502/phi2.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#include "rp6502.h"

int phi2(void) {
RIA.op = RIA_OP_PHI2;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
}
int phi2(void) { return ria_call_int(RIA_OP_PHI2); }
9 changes: 4 additions & 5 deletions mos-platform/rp6502/putchar.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#include "rp6502.h"
#include <stdio.h>
#include <unistd.h>

void __putchar(char c) {
RIA.xstack = c;
RIA.a = 1;
RIA.op = RIA_OP_WRITE_XSTACK;
while (RIA.busy & RIA_BUSY_BIT)
;
ria_push_char(c);
ria_set_a(STDOUT_FILENO);
ria_call_int_errno(RIA_OP_WRITE_XSTACK);
}
5 changes: 3 additions & 2 deletions mos-platform/rp6502/read.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include <rp6502.h>
#include "rp6502.h"
#include <unistd.h>

int read(int fildes, void *buf, unsigned count) {
int total = 0;
while (count) {
unsigned blockcount = (count > 256) ? 256 : count;
unsigned blockcount = (count > 512) ? 512 : count;
int bytes_read = read_xstack(&((char *)buf)[total], blockcount, fildes);
if (bytes_read < 0)
return bytes_read;
Expand Down
16 changes: 5 additions & 11 deletions mos-platform/rp6502/read_xram.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
#include <rp6502.h>
#include "rp6502.h"

int read_xram(unsigned buf, unsigned count, int fildes) {
RIA.xstack = buf >> 8;
RIA.xstack = buf;
RIA.xstack = count >> 8;
RIA.xstack = count;
RIA.a = fildes;
RIA.x = fildes >> 8;
RIA.op = RIA_OP_READ_XRAM;
while (RIA.busy & RIA_BUSY_BIT)
;
return RIA.a | (RIA.x << 8);
ria_push_int(buf);
ria_push_int(count);
ria_set_ax(fildes);
return ria_call_int_errno(RIA_OP_READ_XRAM);
}
Loading