From 86eb2b49dcfffd31858c15e94889c2b1be419e8c Mon Sep 17 00:00:00 2001 From: Piotr Fusik Date: Sun, 11 Aug 2024 15:32:11 +0200 Subject: [PATCH] WIP: [atari] fgetpos/fsetpos using NOTE/POINT --- mos-platform/atari8-common/CMakeLists.txt | 3 ++ mos-platform/atari8-common/note.s | 42 +++++++++++++++++++ mos-platform/atari8-common/point.s | 42 +++++++++++++++++++ mos-platform/atari8-common/update_diskpos.c | 8 ++++ mos-platform/common/c/stdio-full.c | 22 ++++------ .../common/include/__stdio-internal.h | 24 +++++++++++ 6 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 mos-platform/atari8-common/note.s create mode 100644 mos-platform/atari8-common/point.s create mode 100644 mos-platform/atari8-common/update_diskpos.c create mode 100644 mos-platform/common/include/__stdio-internal.h diff --git a/mos-platform/atari8-common/CMakeLists.txt b/mos-platform/atari8-common/CMakeLists.txt index 7e43b57a..7f6c0185 100644 --- a/mos-platform/atari8-common/CMakeLists.txt +++ b/mos-platform/atari8-common/CMakeLists.txt @@ -28,6 +28,7 @@ target_link_libraries(atari8-common-crt0 PRIVATE common-asminc) add_platform_library(atari8-common-c putchar.c getchar.c + update_diskpos.c close.s fdtab.s @@ -35,8 +36,10 @@ add_platform_library(atari8-common-c fdtoiocb.s findfreeiocb.s getfd.s + note.s open.s oserror.s + point.s rwcommon.s sysremove.s write.s diff --git a/mos-platform/atari8-common/note.s b/mos-platform/atari8-common/note.s new file mode 100644 index 00000000..a4a496b6 --- /dev/null +++ b/mos-platform/atari8-common/note.s @@ -0,0 +1,42 @@ +; 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. + +; char __note (int fd, fpos_t *pos); + + .include "atari.inc" + .include "imag.inc" + + .globl __note + +__note: + jsr fdtoiocb + bmi error + tax + lda #NOTE + sta ICCOM,x + jsr CIOV + bmi error + ldy #0 + lda ICAX5,x + sta (__rc2),y + iny + lda ICAX3,x + sta (__rc2),y + iny + lda ICAX4,x + sta (__rc2),y + iny + lda #0 + sta (__rc2),y + rts + +error: + ldy #3 + lda #$ff +store_error: + sta (__rc2),y + dey + bpl store_error + rts diff --git a/mos-platform/atari8-common/point.s b/mos-platform/atari8-common/point.s new file mode 100644 index 00000000..08bb18b6 --- /dev/null +++ b/mos-platform/atari8-common/point.s @@ -0,0 +1,42 @@ +; 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. + +; char __point (int fd, const fpos_t *pos); + + .include "atari.inc" + .include "imag.inc" + + .globl __point + +__point: + jsr fdtoiocb + bmi invalid + tax + ldy #3 + lda (__rc2),y + bne invalid + lda #POINT + sta ICCOM,x + dey + lda (__rc2),y + sta ICAX4,x + dey + lda (__rc2),y + sta ICAX3,x + dey + lda (__rc2),y + sta ICAX5,x + jsr CIOV + bmi cioerr + lda #0 + rts + +invalid: + lda # +#include <__stdio-internal.h> + +char __note(int fd, fpos_t *pos); + +void __update_diskpos(FILE *stream) { + __note(stream->handle, &stream->diskpos); +} diff --git a/mos-platform/common/c/stdio-full.c b/mos-platform/common/c/stdio-full.c index 46013031..d2c4e40c 100644 --- a/mos-platform/common/c/stdio-full.c +++ b/mos-platform/common/c/stdio-full.c @@ -8,12 +8,13 @@ #include #include #include -#include #include #include #include #include +#include <__stdio-internal.h> + // Flags for representing mode (see fopen()). Note these must fit the same // status field as the _IO?BF flags in and the internal flags below. #define FREAD (1u << 3) @@ -37,20 +38,6 @@ // File associated with stream should be remove()d on closing (tmpfile()). #define DELONCLOSE (1u << 14) -struct _FILE { - signed char handle; // OS file handle - char *buffer; // Pointer to buffer memory - size_t bufsize; // Size of buffer - size_t bufidx; // Index of current position in buffer - size_t bufend; // Index of last pre-read character in buffer - fpos_t pos; // Offset and multibyte parsing state - char ungetc_buf; // ungetc() buffer - bool ungetc_buf_full; // Number of ungetc()'ed characters - unsigned status; // Status flags; see above - char *filename; // Name the current stream has been opened with - FILE *next; // Pointer to next struct (internal) -}; - // Buffer one-two lines; write() implementations have constant overhead, and // buffering amortizes it. static char serr_buf[80]; @@ -130,6 +117,9 @@ static unsigned filemode(const char *const mode) { return rc; } +__attribute__((weak)) void __update_diskpos(FILE *stream) { +} + static FILE *init_file(FILE *stream) { FILE *rc = stream; @@ -563,6 +553,8 @@ static int prep_read(FILE *stream) { } static int fill_buffer(FILE *stream) { + __update_diskpos(stream); + /* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */ int rc = read(stream->handle, stream->buffer, stream->bufsize); diff --git a/mos-platform/common/include/__stdio-internal.h b/mos-platform/common/include/__stdio-internal.h new file mode 100644 index 00000000..d446b689 --- /dev/null +++ b/mos-platform/common/include/__stdio-internal.h @@ -0,0 +1,24 @@ +#ifndef __STDIO_INTERNAL_H_ +#define __STDIO_INTERNAL_H_ + +#include +#include + +struct _FILE { + signed char handle; // OS file handle + char *buffer; // Pointer to buffer memory + size_t bufsize; // Size of buffer + size_t bufidx; // Index of current position in buffer + size_t bufend; // Index of last pre-read character in buffer + fpos_t pos; // Offset and multibyte parsing state + char ungetc_buf; // ungetc() buffer + bool ungetc_buf_full; // Number of ungetc()'ed characters + unsigned status; // Status flags; see above + char *filename; // Name the current stream has been opened with + fpos_t diskpos; // Atari NOTE position + FILE *next; // Pointer to next struct (internal) +}; + +void __update_diskpos(FILE *stream); + +#endif // __STDIO_INTERNAL_H_