[Coco] File handling for CMOC in OS9 ?
Pierre Sarrazin
sarrazip at sarrazip.com
Sat Jul 22 22:31:20 EDT 2023
Dixit coco--- via Coco (2023-07-22 11:52):
> The package decbfile (0.1.8) (Public domain) for CMOC provides a library
> that implements read/write access to files with the functions
> decbutil_readFileToMemory() and decbutil_writeMemoryToFile() which read or
> write a file to or from memory in a single call.
>
> Is there a similar library for CMOC to read Nitros09 files ?
Hi Charlie,
There is no similar library to my knowledge, but this should be doable
in a CMOC program by using inline assembly to make OS-9 system calls.
The following program uses the I$Open and I$Read system calls.
It only loads the first 10 bytes of the foo.txt file.
==[ osload.c ]=====================================
#include <cmoc.h>
// filePath: Must end with '\r'.
// Returns the number of bytes read from the file (may be lower than bufferLength).
//
size_t loadFileToBuffer(const char *filePath,
void *buffer,
size_t bufferLength)
{
// Open the file in read mode.
unsigned char pathNumber, errorCode;
asm
{
lda #$01 ; read mode
ldx :filePath
os9 $84 ; I$Open
bcs @error
clrb
sta :pathNumber
@error
stb :errorCode
}
if (errorCode != 0)
{
printf("I$Open failed: error #%u\n", errorCode);
return 0;
}
// Load bytes from the file to the buffer.
size_t numBytesRead;
asm
{
lda :pathNumber
ldx :buffer ; address where to store the bytes
pshs y ; save global data ptr; cannot refer to C globals for now
ldy :bufferLength ; number of bytes to read
os9 $89 ; I$Read
bcs @error
clrb
sty :numBytesRead
@error
stb :errorCode
puls y ; restore global data ptr; can refer to C globals again
}
if (errorCode != 0)
{
printf("I$Read failed: error #%u\n", errorCode);
// Do not return because we need to close the file.
}
// Close the file.
unsigned char closeErrorCode;
asm
{
lda :pathNumber
os9 $8F ; I$Close
bcs @error
clrb
@error
stb :closeErrorCode
}
if (errorCode != 0) // if read error
return 0; // do not report close error if any; read error already reported
if (closeErrorCode != 0)
{
printf("I$Close failed: error #%u\n", errorCode);
return 0;
}
return numBytesRead; // success
}
int main()
{
char contents[10];
size_t numBytesRead = loadFileToBuffer("foo.txt\r", contents, sizeof(contents));
printf("First %u bytes: [", numBytesRead);
putstr(contents, numBytesRead);
printf("]\n");
return 0;
}
===================================================
It can be compiled with: cmoc --os9 os9load.c
Once the 'os9load' executable has been transferred to NitrOS-9, it can
be used by first creating a foo.txt file (e.g., with 'build foo.txt').
If for example this file contains "This is the foo.txt file.",
then when 'os9load' is run, it should print this:
First 10 bytes: [This is th]
I found the details on the systems calls in the "OS-9 Operating System -
System Programmer's Manual" PDF.
Technical details:
Whenever the Y register is used in an OS-9 system call, it must be
preserved with PSHS and PULS, as done above, because a CMOC program
uses it to point to the process's data segment.
While the Y register is used for something else, the CMOC program must
not refer to C global variables. (Local variables are accessed through
the U register.)
--
Pierre Sarrazin <sarrazip @ sarrazip . com>
More information about the Coco
mailing list