Persistent operations implemented

This commit is contained in:
Luxferre
2022-08-12 11:26:34 +03:00
parent d48e6df014
commit 1a95042757
3 changed files with 45 additions and 9 deletions
+29 -5
View File
@@ -72,6 +72,11 @@
#define CLT_ENTRIES_MAX 512u
#endif
/* Persistent storage sandbox file name */
#ifndef PERSIST_FILE
#define PERSIST_FILE "PERS.DAT"
#endif
/* Some necessary constants and offsets derived from the above values */
#define STACK_SIZE_WORDS (STACK_SIZE / WS) /* Main and return stack size in words */
@@ -122,7 +127,8 @@ enum EquiErrors {
CMD_OVERFLOW,
INVALID_INSTRUCTION,
INVALID_WORD,
PORT_IO_ERROR
PORT_IO_ERROR,
PERSIST_IO_ERROR
};
/* Error reporting method */
@@ -154,6 +160,9 @@ void trapout(errcode) {
case PORT_IO_ERROR:
cerr("Port I/O error\n");
break;
case PERSIST_IO_ERROR:
cerr("Persistent storage I/O error\n");
break;
}
exit(errcode);
}
@@ -296,13 +305,24 @@ ushort crc16(const uchar* data_p, uchar length) {
/* Persistent operation handler */
ushort persistOp(maddr, dataLen, adl, adh, isWrite) {
ushort persistOp(FILE *pfd, ushort maddr, ushort dataLen, ushort adl, ushort adh, uchar isWrite) {
ushort status = 0, proc;
if(pfd) {
fseek(pfd, (adh << 16) | adl, SEEK_SET);
if(isWrite) /* writing to the persistent area from the memory */
proc = (ushort) fwrite(&flatram[maddr], 1, dataLen, pfd);
else /* reading from the persistent area into the memory */
proc = (ushort) fread(&flatram[maddr], 1, dataLen, pfd);
if(proc != dataLen)
status = PERSIST_IO_ERROR;
}
pushMain(status);
return 0;
}
/* Port I/O handler */
void portIO(port, p2, p1) {
void portIO(ushort port, ushort p2, ushort p1) {
ushort r1 = 0, r2 = 0, status = 0;
switch(port) {
case PORT_ECHO:
@@ -329,6 +349,8 @@ void portIO(port, p2, p1) {
void equi_main_loop() {
uchar instr;
ushort lhash, pbuf, pbuf2;
/* try to open the persistent sandbox file */
FILE *pfd = fopen(PERSIST_FILE, "r+b");
/* reset all stacks before running and reinit CLT */
ram.msp = ram.rsp = ram.lsp = ram.cltp = 0;
/* reset pc */
@@ -529,10 +551,10 @@ void equi_main_loop() {
portIO(popMain(), popMain(), popMain());
break;
case INS_PERSIST_READ: /* ( adh adl len maddr -- status) */
pushMain(persistOp(popMain(), popMain(), popMain(), popMain(), 0));
pushMain(persistOp(pfd, popMain(), popMain(), popMain(), popMain(), 0));
break;
case INS_PERSIST_WRITE: /* ( adh adl len maddr -- status) */
pushMain(persistOp(popMain(), popMain(), popMain(), popMain(), 1));
pushMain(persistOp(pfd, popMain(), popMain(), popMain(), popMain(), 1));
break;
default: /* all characters not processed before are invalid instructions */
trapout(INVALID_INSTRUCTION);
@@ -543,6 +565,8 @@ void equi_main_loop() {
continue;
brx: break;
}
/* close the persistent sandbox file if open */
if(pfd) fclose(pfd);
/* unset interpretation mode flag and exit */
ram.IM = 0;
ram.pc = ram.ibp = 65535U;