2022-08-06 00:08:17 +03:00
|
|
|
/*
|
|
|
|
|
* Equi platform reference implementation
|
|
|
|
|
*
|
|
|
|
|
* Created in 2022 by Luxferre, released into public domain
|
|
|
|
|
*
|
|
|
|
|
* See equi.md file for the specification and manual
|
|
|
|
|
*
|
|
|
|
|
* @license Unlicense <https://unlicense.org>
|
|
|
|
|
* @author Luxferre
|
|
|
|
|
*/
|
|
|
|
|
|
2022-08-06 09:34:32 +03:00
|
|
|
/* Standard includes with size optimizations for TCC */
|
2022-08-06 00:08:17 +03:00
|
|
|
|
2022-08-06 09:34:32 +03:00
|
|
|
#ifdef __TINYC__
|
|
|
|
|
#include <tcclib.h>
|
|
|
|
|
#else
|
2022-08-06 00:08:17 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
2022-08-06 09:34:32 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Non-standard includes
|
|
|
|
|
* To save space, we emulate necessary conio functions on non-6502 systems, not vice versa
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef __CC65__
|
|
|
|
|
#include <conio.h>
|
|
|
|
|
#else
|
|
|
|
|
|
2022-08-06 12:14:23 +03:00
|
|
|
#define cgetc() (fgetc(stdin))
|
2022-08-06 21:09:10 +03:00
|
|
|
#define cputc(c) (fputc(c, stdout))
|
2022-08-06 12:14:23 +03:00
|
|
|
|
2022-08-06 09:34:32 +03:00
|
|
|
#endif
|
2022-08-06 00:08:17 +03:00
|
|
|
|
|
|
|
|
/* Definitions section */
|
|
|
|
|
|
2022-08-06 21:09:10 +03:00
|
|
|
#define EQUI_VER "0.0.1"
|
|
|
|
|
|
2022-08-06 00:08:17 +03:00
|
|
|
#define ushort unsigned short /* basic 16-bit integer */
|
|
|
|
|
#define uchar unsigned char /* basic 8-bit integer */
|
|
|
|
|
#define WS sizeof(ushort) /* Equi word size in bytes */
|
2022-08-06 13:35:10 +03:00
|
|
|
#define CLT_ENTRY_LEN 6u /* Amount of significant compiled word characters */
|
2022-08-06 00:08:17 +03:00
|
|
|
#define CLT_ENTRY_SIZE (CLT_ENTRY_LEN + WS) /* Full size in bytes taken by one CLT entry */
|
2022-08-06 21:09:10 +03:00
|
|
|
#define BS 8u /* Backspace character code */
|
2022-08-06 00:08:17 +03:00
|
|
|
|
|
|
|
|
/* Configuration section (constants overridable at compile-time) */
|
|
|
|
|
|
|
|
|
|
/* Main and return stack size in bytes */
|
|
|
|
|
#ifndef STACK_SIZE
|
2022-08-06 13:35:10 +03:00
|
|
|
#define STACK_SIZE 256u
|
2022-08-06 00:08:17 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Literal stack size in bytes */
|
|
|
|
|
#ifndef LIT_STACK_SIZE
|
2022-08-06 13:35:10 +03:00
|
|
|
#define LIT_STACK_SIZE 32u
|
2022-08-06 00:08:17 +03:00
|
|
|
#endif
|
|
|
|
|
|
2022-08-06 21:09:10 +03:00
|
|
|
/* Command buffer size in bytes */
|
|
|
|
|
#ifndef GPD_AREA_SIZE
|
|
|
|
|
#define GPD_AREA_SIZE 6400u
|
2022-08-06 00:08:17 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Command buffer size in bytes */
|
|
|
|
|
#ifndef CMD_BUF_SIZE
|
2022-08-06 13:35:10 +03:00
|
|
|
#define CMD_BUF_SIZE 15600u
|
2022-08-06 00:08:17 +03:00
|
|
|
#endif
|
|
|
|
|
|
2022-08-06 21:09:10 +03:00
|
|
|
/* Maximum amount of CLT entries */
|
|
|
|
|
#ifndef CLT_ENTRIES_MAX
|
|
|
|
|
#define CLT_ENTRIES_MAX 512u
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-08-06 00:08:17 +03:00
|
|
|
/* Some necessary constants and offsets derived from the above values */
|
|
|
|
|
#define STACK_SIZE_WORDS (STACK_SIZE / WS) /* Main and return stack size in words */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Structures that describe Equi machine RAM using the above configuration
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct CLTEntry {
|
2022-08-06 13:35:10 +03:00
|
|
|
uchar name[CLT_ENTRY_LEN]; /* compiled word name */
|
2022-08-06 00:08:17 +03:00
|
|
|
ushort loc; /* compiled word location */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct EquiRAM {
|
|
|
|
|
ushort main_stack[STACK_SIZE_WORDS];
|
|
|
|
|
ushort return_stack[STACK_SIZE_WORDS];
|
|
|
|
|
uchar literal_stack[LIT_STACK_SIZE];
|
|
|
|
|
ushort pc; /* program counter */
|
|
|
|
|
ushort msp; /* main stack pointer */
|
|
|
|
|
ushort rsp; /* return stack pointer */
|
2022-08-06 08:19:09 +03:00
|
|
|
uchar lsp; /* literal stack pointer */
|
2022-08-06 00:08:17 +03:00
|
|
|
ushort cbp; /* compilation buffer pointer */
|
|
|
|
|
ushort cltp; /* compilation lookup table pointer */
|
2022-08-06 21:09:10 +03:00
|
|
|
unsigned int II:1; /* instruction ignore mode */
|
|
|
|
|
unsigned int CM:1; /* compilation mode */
|
|
|
|
|
unsigned int IM:1; /* interpretation mode */
|
2022-08-06 00:08:17 +03:00
|
|
|
ushort gpd_start;
|
|
|
|
|
ushort cmd_start;
|
|
|
|
|
ushort cmd_size;
|
2022-08-06 21:09:10 +03:00
|
|
|
ushort ibp; /* input buffer pointer */
|
2022-08-06 00:08:17 +03:00
|
|
|
struct CLTEntry clt[CLT_ENTRIES_MAX]; /* compilation lookup table */
|
|
|
|
|
uchar gpd[GPD_AREA_SIZE];
|
|
|
|
|
uchar cmdbuf[CMD_BUF_SIZE];
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-06 09:34:32 +03:00
|
|
|
/* Before running the main code, instantiate the machine RAM */
|
|
|
|
|
static struct EquiRAM ram;
|
2022-08-06 00:08:17 +03:00
|
|
|
|
|
|
|
|
/* Also create an alternative view of the same RAM area for direct offset-based access */
|
|
|
|
|
static uchar* flatram = (uchar *)&ram;
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
2022-08-06 09:34:32 +03:00
|
|
|
/* initialize the RAM in the most standard way */
|
2022-08-06 21:09:10 +03:00
|
|
|
ram.gpd_start = (uchar *)&ram.gpd - (uchar *)&ram.main_stack;
|
|
|
|
|
ram.cmd_start = (uchar *)&ram.cmdbuf - (uchar *)&ram.main_stack;
|
2022-08-06 09:34:32 +03:00
|
|
|
ram.cmd_size = CMD_BUF_SIZE;
|
2022-08-06 21:09:10 +03:00
|
|
|
ram.pc = ram.cmd_start; /* Start execution from the start of command buffer */
|
|
|
|
|
ram.ibp = ram.cmd_start; /* Start input buffering from the start of command buffer */
|
2022-08-06 00:08:17 +03:00
|
|
|
|
2022-08-06 21:09:10 +03:00
|
|
|
printf("Welcome to Equi v" EQUI_VER " by Luxferre, 2022\n\nCLT: 0x%X (%d bytes)\nGPD: 0x%X (%d bytes)\nCommand buffer: 0x%X (%d bytes)\nEqui ready\n\n",
|
|
|
|
|
(uchar *)&ram.clt - (uchar *)&ram.main_stack,
|
|
|
|
|
(uchar *)&ram.gpd - (uchar *)&ram.clt,
|
|
|
|
|
ram.gpd_start,
|
|
|
|
|
ram.cmd_start - ram.gpd_start,
|
|
|
|
|
ram.cmd_start, ram.cmd_size);
|
|
|
|
|
|
|
|
|
|
cputc('>');
|
2022-08-06 12:14:23 +03:00
|
|
|
cgetc();
|
|
|
|
|
|
2022-08-06 00:08:17 +03:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|