123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- /*
- * Stdio replacement library
- * Contains a subset of functions to use as drop-in replacement
- * Originally made for porting the BCC compiler
- * BDOS_PrintConsole could be replaced with uprint instead
- */
- // maximum number of files to open at the same time (+1 because we skip index 0)
- #define FOPEN_MAX_FILES 16
- #define FOPEN_FILENAME_LIMIT 32
- #define EOF -1
- char fopenList[FOPEN_MAX_FILES][FOPEN_FILENAME_LIMIT]; // filenames for each opened file
- word fopenCurrentlyOpen[FOPEN_MAX_FILES]; // which indexes are currently opened
- word fopenCursors[FOPEN_MAX_FILES]; // cursors of currently opened files
- word CH376CurrentlyOpened = 0; // index in fopenList which is currently opened on CH376
- // fopen replacement
- // requires full paths
- // returns 0 on error
- // otherwise returns the index to the fopenList buffer
- // creates new file if write is 1
- // append is not an option for now
- word fopen(const char* fname, const word write)
- {
- if (strlen(fname) >= FOPEN_FILENAME_LIMIT)
- {
- BDOS_PrintConsole("E: Path too large\n");
- return 0;
- }
- if (fname[0] != '/')
- {
- BDOS_PrintConsole("E: Filename should be a full path\n");
- return 0;
- }
- // conver to uppercase
- strToUpper(fname);
- // if write, create the file
- if (write)
- {
- FS_close(); // to be sure
- CH376CurrentlyOpened = 0;
- // if current path is correct (can be file or directory)
- if (FS_sendFullPath(fname) == FS_ANSW_USB_INT_SUCCESS)
- {
- // create the file
-
- if (FS_createFile() == FS_ANSW_USB_INT_SUCCESS)
- {
- //BDOS_PrintConsole("File created\n");
- }
- else
- {
- BDOS_PrintConsole("E: Could not create file\n");
- return 0;
- }
- }
- else
- {
- BDOS_PrintConsole("E: Invalid path\n");
- return 0;
- }
- }
- word i = 1; // skip index 0
- while (i < FOPEN_MAX_FILES)
- {
- if (fopenCurrentlyOpen[i] == 0)
- {
- // found a free spot
- fopenCurrentlyOpen[i] = 1;
- fopenCursors[i] = 0;
- // write filename
- strcpy(fopenList[i], fname);
- return i; // return index
- }
- i++;
- }
- BDOS_PrintConsole("E: The maximum number of files are already opened. Forgot to close some files?\n");
- return 0;
- }
- // closes file at index
- // also closes the file on CH376 if it is currently open there as well
- void fclose(word i)
- {
- if (CH376CurrentlyOpened == i)
- {
- FS_close(); // to be sure
- CH376CurrentlyOpened = 0;
- }
- fopenCurrentlyOpen[i] = 0;
- fopenList[i][0] = 0; // to be sure
- }
- // returns the current char at cursor (EOF is end of file)
- // increments the cursor
- word fgetc(word i)
- {
- // check if file is open
- if (fopenCurrentlyOpen[i] == 0)
- {
- BDOS_PrintConsole("fgetc: File is not open\n");
- return EOF;
- }
- // open on CH376 if not open already
- if (CH376CurrentlyOpened != i)
- {
- // close last one first, unless there is no last
- if (CH376CurrentlyOpened != 0)
- {
- //BDOS_PrintConsole("fgetc: Closed previous file\n");
- FS_close();
- }
- // if the resulting path is correct (can be file or directory)
- if (FS_sendFullPath(fopenList[i]) == FS_ANSW_USB_INT_SUCCESS)
- {
- // if we can successfully open the file (not directory)
- if (FS_open() == FS_ANSW_USB_INT_SUCCESS)
- {
- CH376CurrentlyOpened = i;
- // set cursor to last position
- FS_setCursor(fopenCursors[i]);
- //BDOS_PrintConsole("fgetc: File opened on CH376\n");
- }
- else
- {
- BDOS_PrintConsole("E: Could not open file\n");
- return EOF;
- }
- }
- else
- {
- BDOS_PrintConsole("E: Invalid path\n");
- return EOF;
- }
- }
- // read char and increment cursor locally
- char gotchar = 0;
- word retval = FS_readFile(&gotchar, 1, 0);
- if (retval != FS_ANSW_USB_INT_SUCCESS)
- {
- // assume EOF
- return EOF;
- }
- fopenCursors[i]++;
- return gotchar;
- }
- // writes string s at cursor
- // increments the cursor
- // returns EOF on failure
- // otherwise returns 1
- word fputs(word i, char* s)
- {
- // check if file is open
- if (fopenCurrentlyOpen[i] == 0)
- {
- BDOS_PrintConsole("fputs: File is not open\n");
- return EOF;
- }
- // open on CH376 if not open already
- if (CH376CurrentlyOpened != i)
- {
- // close last one first, unless there is no last
- if (CH376CurrentlyOpened != 0)
- {
- //BDOS_PrintConsole("fputs: Closed previous file\n");
- FS_close();
- }
- // if the resulting path is correct (can be file or directory)
- if (FS_sendFullPath(fopenList[i]) == FS_ANSW_USB_INT_SUCCESS)
- {
- // if we can successfully open the file (not directory)
- if (FS_open() == FS_ANSW_USB_INT_SUCCESS)
- {
- CH376CurrentlyOpened = i;
- // set cursor to last position
- FS_setCursor(fopenCursors[i]);
- //BDOS_PrintConsole("fputs: File opened on CH376\n");
- }
- else
- {
- BDOS_PrintConsole("E: Could not open file\n");
- return EOF;
- }
- }
- else
- {
- BDOS_PrintConsole("E: Invalid path\n");
- return EOF;
- }
- }
- // write string and increment cursor locally
- word slen = strlen(s);
- word retval = FS_writeFile(s, slen);
- if (retval != FS_ANSW_USB_INT_SUCCESS)
- {
- // assume EOF
- return EOF;
- }
- fopenCursors[i] += slen;
- return 1;
- }
- // fputs, but a single char
- word fputc(word i, char c)
- {
- char* s = "0";
- s[0] = c;
- return fputs(i, s);
- }
- word printf(char* s)
- {
- //TODO: do escape character handling
- BDOS_PrintConsole(s);
- }
- word printd(word d)
- {
- if (d < 0)
- {
- BDOS_PrintcConsole('-');
- BDOS_PrintDecConsole(-d);
- }
- else
- {
- BDOS_PrintDecConsole(d);
- }
-
- }
- void exit(word i)
- {
- asm("jump Return_BDOS\n");
- }
|