Port I/O tested; strip unstable again, commented out
This commit is contained in:
@@ -7,7 +7,7 @@ DFLAGS=
|
||||
|
||||
desktopcc:
|
||||
cc -std=c89 -Os -o $(PROJNAME) $(CFILES) $(DFLAGS)
|
||||
strip $(PROJNAME)
|
||||
# strip $(PROJNAME)
|
||||
|
||||
tcc:
|
||||
tcc -std=c89 -o $(PROJNAME) $(CFILES) $(DFLAGS)
|
||||
|
||||
@@ -132,7 +132,7 @@ Please also note that Equi doesn't specify any graphical or sound output capabil
|
||||
|
||||
Being a purely PC-oriented low-level runtime/programming environment, Equi has the reference implementation emulator/VM written in C (ANSI C89 standard), `equi.c`, compilable and runnable on all the systems supporting standard I/O. Note that, for portability reasons, this emulator:
|
||||
|
||||
- doesn't fully implement `P` instruction but instead outputs its parameters to the standard error stream and puts three 0x0000 values back onto the stack,
|
||||
- only implements three ports for `P` instruction: 0 as an echo port (returns passed parameters as corresponding result values), 1 as a random port (returns two random values in the results in the range between the two parameter values) and 2 as a CRC16 calculation port for a given memory location and its length, for any other port value it outputs its parameters to the standard error stream and puts three 0x0000 values back onto the stack,
|
||||
- doesn't implement non-blocking key input (the ',' instruction is identical to blocking key input instruction `?`),
|
||||
- sandboxes the `{` and `}` operations using the file you supply in the command-line parameter. If you don't supply the file, these operations will effectively do nothing except putting 0x0000 (success status) onto the stack.
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -206,6 +207,14 @@ enum EquiInstructions {
|
||||
INS_QUIT='Q'
|
||||
};
|
||||
|
||||
/* Equi known ports enum */
|
||||
|
||||
enum EquiPorts {
|
||||
PORT_ECHO = 0x0, /* echo port, used for testing: R1=P1, R2=P2 */
|
||||
PORT_RANDOM, /* RNG port: P1 = valueFrom, P2 = valueTo => R1=rand(from, to), R2 = rand(from, to) */
|
||||
PORT_CHECKSUM /* checksum port: P1 = memAddr, P2 = length => R1=CRC16(memAddr, length), R2 = 0 */
|
||||
};
|
||||
|
||||
/* push a value onto the main stack */
|
||||
void pushMain(ushort val) {
|
||||
ram.main_stack[ram.msp++] = val;
|
||||
@@ -285,12 +294,36 @@ ushort crc16(const uchar* data_p, uchar length) {
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* persistent operation handler */
|
||||
/* Persistent operation handler */
|
||||
|
||||
ushort persistOp(maddr, dataLen, adl, adh, isWrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Port I/O handler */
|
||||
|
||||
void portIO(port, p2, p1) {
|
||||
ushort r1 = 0, r2 = 0, status = 0;
|
||||
switch(port) {
|
||||
case PORT_ECHO:
|
||||
r1 = p1;
|
||||
r2 = p2;
|
||||
break;
|
||||
case PORT_RANDOM:
|
||||
r1 = (ushort) (p1 + (rand()%p2));
|
||||
r2 = (ushort) (p1 + (rand()%p2));
|
||||
break;
|
||||
case PORT_CHECKSUM:
|
||||
r1 = crc16(&flatram[p1], p2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[PORTIO] Unimplemented call to port 0x%X with P1=%X and P2=%X, returning status=0, R1=0, R2=0\n", port, p1, p2);
|
||||
}
|
||||
pushMain(r1);
|
||||
pushMain(r2);
|
||||
pushMain(status);
|
||||
}
|
||||
|
||||
/* Main interpreter loop */
|
||||
|
||||
void equi_main_loop() {
|
||||
@@ -490,13 +523,10 @@ void equi_main_loop() {
|
||||
case INS_BKIN: /* blocking key input (again, no Unicode support yet, assuming a single byte incoming to the 16-bit value on the stack) */
|
||||
pushMain((ushort)cgetc());
|
||||
break;
|
||||
case INS_PORTIO: /* ( p1 p2 port -- r1 r2 status ) - simulate port I/O according to the spec */
|
||||
pbuf = popMain(); /* port */
|
||||
pbuf2 = popMain(); /* p2 */
|
||||
fprintf(stderr, "[PORTIO ] Call to port 0x%X with P1=%X and P2=%X, returning status=0, R1=0, R2=0\n", pbuf, pbuf2, popMain());
|
||||
pushMain(0u);
|
||||
pushMain(0u);
|
||||
pushMain(0u);
|
||||
case INS_PORTIO: /* ( p1 p2 port -- r1 r2 status ) - simulate/execute port I/O according to the spec */
|
||||
if(ram.msp < 3)
|
||||
trapout(STACK_UNDERFLOW);
|
||||
portIO(popMain(), popMain(), popMain());
|
||||
break;
|
||||
case INS_PERSIST_READ: /* ( adh adl len maddr -- status) */
|
||||
pushMain(persistOp(popMain(), popMain(), popMain(), popMain(), 0));
|
||||
@@ -534,6 +564,8 @@ int main(int argc, char* argv[]) {
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
#endif
|
||||
/* initialize the PRNG */
|
||||
srand((unsigned)time(NULL));
|
||||
/* initialize the RAM in the most standard way */
|
||||
ram.gpd_start = (uchar *)&ram.gpd - (uchar *)&ram.main_stack;
|
||||
ram.cmd_start = (uchar *)&ram.cmdbuf - (uchar *)&ram.main_stack;
|
||||
|
||||
Reference in New Issue
Block a user