Files
zOS/apps/tbasic/main_nix.c

220 lines
4.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
#include <unistd.h>
#include <poll.h>
#include <time.h>
#include "../core/main.h"
#include "../core/utils.h"
#include "../core/textual.h"
#include "../core/tokens.h"
#include "../core/extern.h"
#define VARS_SPACE_SIZE 512
#define DATA_SPACE_SIZE 4096
#define LINE_SIZE 80
char extraCmdArgCnt[] = {2, 2, 0};
char extraFuncArgCnt[] = {1, 2};
static char* commonStrings = CONST_COMMON_STRINGS;
static char * parsingErrors = CONST_PARSING_ERRORS;
char dataSpace[DATA_SPACE_SIZE];
char lineSpace[LINE_SIZE * 3];
static FILE* fCurrent;
static short idCurrent = 0;
static struct termios oldTermSettings;
static void initSystem(void) {
struct termios termSettings;
tcgetattr(STDIN_FILENO, &oldTermSettings);
termSettings = oldTermSettings;
termSettings.c_lflag &= ~(ICANON | ECHO | ISIG);
tcsetattr(STDIN_FILENO, TCSANOW, &termSettings);
setvbuf(stdout, NULL, _IONBF, 0);
}
static void cleanup(void) {
tcsetattr(STDIN_FILENO, TCSANOW, &oldTermSettings);
}
short sysGetc(void) {
struct pollfd fd;
fd.fd = STDIN_FILENO;
fd.events = POLLIN;
if (!poll(&fd, 1, 0)) {
return -1;
}
return getchar();
}
void sysPutc(char c) {
putchar(c);
}
void sysEcho(char c) {
if (c == '\b') {
sysPutc(c);
sysPutc(' ');
}
sysPutc(c);
}
void sysQuit(void) {
cleanup();
exit(0);
}
void sysPoke(unsigned long addr, uchar value) {
dataSpace[addr] = value;
}
uchar sysPeek(unsigned long addr) {
return dataSpace[addr];
}
numeric sysMillis(numeric div) {
struct timespec tp;
long v;
clock_gettime(CLOCK_REALTIME, &tp);
v = (((numeric) tp.tv_sec) * 1000 + tp.tv_nsec / 1000000) & 0x7FFFFFFF;
return div <= 1 ? v : v / div;
}
char translateInput(short c) {
if (c == -1) {
c = 0;
}
return (char) (c & 0xFF);
}
void outputConstStr(char strId, char index, char* w) {
char* s;
switch (strId) {
case ID_COMMON_STRINGS:
s = commonStrings;
break;
case ID_PARSING_ERRORS:
s = parsingErrors;
break;
default:
return;
}
while (index > 0) {
while (*s++ != '\n') {
}
index -= 1;
}
while (*s != '\n') {
if (w) {
*(w++) = (*s++);
} else {
sysPutc(*s++);
}
}
if (w) {
*w = 0;
}
}
static numeric power(numeric base, numeric exp) {
return exp < 1 ? 1 : base * power(base, exp - 1);
}
short extraCommandByHash(numeric h) {
switch (h) {
case 0x036F: // POKE
return CMD_EXTRA + 0;
case 0x019C: // PIN - just prints argument values for test
return CMD_EXTRA + 1;
case 0x031A: // QUIT
return CMD_EXTRA + 2;
default:
return -1;
}
}
short extraFunctionByHash(numeric h) {
switch (h) {
case 0x0355: // PEEK
return 0;
case 0x06FC: // POWER - for test purpose
return 1;
default:
return -1;
}
}
void extraCommand(char cmd, numeric args[]) {
switch (cmd) {
case 0:
sysPoke(args[0], args[1]);
break;
case 1:
printf("PIN: %d,%d\n", args[0], args[1]);
break;
case 2:
sysQuit();
break;
}
}
numeric extraFunction(char cmd, numeric args[]) {
switch (cmd) {
case 0:
return sysPeek(args[0]);
case 1:
return power(args[1], args[0]);
}
return 0;
}
static char openStorage(char id, char op) {
char fname[] = "store0.dat";
char ops[] = "xb";
fname[5] += id;
ops[0] = op;
fCurrent = fopen(fname, ops);
return fCurrent != NULL ? 1 : 0;
}
char storageOperation(void* data, short size) {
if (data == NULL) {
if (idCurrent != 0) {
fclose(fCurrent);
}
idCurrent = 0;
if (size != 0) {
idCurrent = abs(size);
if (!openStorage(idCurrent, size > 0 ? 'w' : 'r')) {
idCurrent = 0;
return 0;
}
}
return 1;
}
if (size > 0) {
fwrite(data, size, 1, fCurrent);
} else {
fread(data, -size, 1, fCurrent);
}
return 1;
}
int main(void) {
initSystem();
init(VARS_SPACE_SIZE, 80, sizeof(dataSpace) - VARS_SPACE_SIZE);
while(1) {
lastInput = translateInput(sysGetc());
dispatch();
}
return 0;
}