276 lines
8.7 KiB
C
276 lines
8.7 KiB
C
/*
|
|
* ntsys.h
|
|
*
|
|
* Copyright 2026
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*
|
|
*
|
|
*/
|
|
|
|
#if (!defined(__LIB_ntsys_H_))
|
|
#define __LIB_ntsys_H_
|
|
|
|
#define NTSYS_ASSEMBLE_STANDARD_MEMORY_SIZE 4096
|
|
|
|
#define NTSYS_VERSION "1.0"
|
|
|
|
#define NAME_OF_32_BITS_TYPE unsigned int
|
|
#define NAME_OF_64_BITS_TYPE unsigned long int
|
|
#define NAME_OF_16_BITS_TYPE unsigned short int
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef unsigned char __e_byte_t;
|
|
|
|
typedef struct {
|
|
__e_byte_t e_magic[3];
|
|
__e_byte_t e_filesize[4];
|
|
__e_byte_t e_memorysize[2];
|
|
} __e_image_header_t;
|
|
|
|
#if (!defined(EXIT_SUCCESS))
|
|
#define EXIT_SUCCESS 0
|
|
#endif
|
|
|
|
#if (!defined(EXIT_FAILURE))
|
|
#define EXIT_FAILURE 1
|
|
#endif
|
|
|
|
__e_byte_t* __ntsys_stack = NULL;
|
|
unsigned int __ntsys_stack_pointer = 0;
|
|
__e_byte_t* __ntsys_buffer = NULL;
|
|
size_t __ntsys_buffer_size = 0;
|
|
unsigned int __ntsys_buffer_ptr = 0;
|
|
int fGH6VSEzu7qNiGVE_stat = EXIT_SUCCESS;
|
|
|
|
void ntsys_error(char* _err) {
|
|
printf("\033[1mntsys: \033[91m%s\033[0m\n", _err);
|
|
}
|
|
|
|
#include "ntfiles.h"
|
|
|
|
word_t fGH6VSEzu7qNiGVE_mem_size = NTSYS_ASSEMBLE_STANDARD_MEMORY_SIZE;
|
|
|
|
#include "ntsys-assembler.h"
|
|
|
|
static void __help(void) {
|
|
puts (
|
|
"BINARY Emulator - LICENSE GPL V3" "\n"
|
|
" " "VM for micron files" "\n"
|
|
"Using:" "\n"
|
|
" " "ntsys [OPTIONS...] [FILENAME]" "\n"
|
|
"Examples:" "\n"
|
|
" " "ntsys --asm FILE.asm" "\n"
|
|
" " "ntsys [--asm] FILE.asm --out FILE.exe" "\n"
|
|
" " "ntsys FILE.exe" "\n"
|
|
"Options:" "\n"
|
|
" " "--help / -h - show this help" "\n"
|
|
" " "--version / -v - show version" "\n"
|
|
" " "--asm / -a - compile assembler program" "\n"
|
|
" " "--out / -o - set output file name" "\n"
|
|
" " "--debug / -d - display debugging info" "\n"
|
|
" " "--mem / -m - asm output memory size" "\n"
|
|
" " "--nfull / -n - no print all debug info" "\0"
|
|
);
|
|
}
|
|
static int __exe_run(__e_byte_t* memory, __e_byte_t fulldebug, unsigned int memorysize, unsigned long filesize, FILE* fp, __e_byte_t debug) {
|
|
__ntsys_stack_pointer = memorysize;
|
|
__ntsys_stack = memory;
|
|
__e_byte_t* buff = malloc(filesize - 8);
|
|
__ntsys_buffer = buff;
|
|
__ntsys_buffer_size = fread(buff, 1, filesize - 8, fp);
|
|
__ntsys_buffer_ptr = 0;
|
|
if (!debug) {
|
|
while (__ntsys_buffer_ptr < __ntsys_buffer_size) {
|
|
__e_byte_t cmd = buff[__ntsys_buffer_ptr];
|
|
__ntsys_buffer_ptr ++;
|
|
fn_fGH6VSEzu7qNiGVE[cmd]();
|
|
}
|
|
} else {
|
|
putchar('\n');
|
|
while (__ntsys_buffer_ptr < __ntsys_buffer_size) {
|
|
__e_byte_t cmd = buff[__ntsys_buffer_ptr];
|
|
if (fulldebug) {
|
|
fprintf(stdout, "Command %d 0x%X\n"
|
|
"Position %d 0x%X\n"
|
|
"Stack point %d 0x%X\n\n"
|
|
, cmd, cmd,
|
|
__ntsys_buffer_ptr, __ntsys_buffer_ptr,
|
|
__ntsys_stack_pointer, __ntsys_stack_pointer);
|
|
}
|
|
__ntsys_buffer_ptr ++;
|
|
fn_fGH6VSEzu7qNiGVE[cmd]();
|
|
FILE* df = fopen("dump.bin", "wb");
|
|
if (df == NULL) {
|
|
ntsys_error("Cannot open dump file!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
fwrite(__ntsys_stack, 1, memorysize, df);
|
|
fclose(df);
|
|
if (fulldebug) {
|
|
puts("Press any key to continue...");
|
|
getchar();
|
|
}
|
|
}
|
|
}
|
|
if (debug) {
|
|
printf("\nStack point %d 0x%X\n", __ntsys_stack_pointer, __ntsys_stack_pointer);
|
|
}
|
|
free(buff);
|
|
if (fGH6VSEzu7qNiGVE_stat != EXIT_SUCCESS) return fGH6VSEzu7qNiGVE_stat;
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int ntsys_api_call(char* filename, unsigned char debug, unsigned char isFullDebug) {
|
|
|
|
/* File data */
|
|
|
|
__e_image_header_t head;
|
|
__e_byte_t head_bin[8];
|
|
|
|
/* Parser */
|
|
|
|
FILE* fp = fopen(filename, "rb");
|
|
if (fp == NULL) {
|
|
ntsys_error("Cannot open file!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
short int res1 = ((fread(&head_bin, 1, sizeof(head_bin), fp)));
|
|
head.e_magic[0] = head_bin[0];
|
|
head.e_magic[1] = head_bin[1];
|
|
head.e_magic[2] = (__e_byte_t)0;
|
|
int __i = 1;
|
|
size_t i = 0;
|
|
if (!(*((char *)&__i) == 1)) {
|
|
/* BIG ENDIAN */
|
|
head.e_memorysize[0] = head_bin[7];
|
|
head.e_memorysize[1] = head_bin[6];
|
|
i = 3;
|
|
while (1) {
|
|
head.e_filesize[i] = head_bin[5 - i];
|
|
if (i == 0) break;
|
|
i --;
|
|
}
|
|
} else {
|
|
/* LITTLE ENDIAN */
|
|
head.e_memorysize[0] = head_bin[6];
|
|
head.e_memorysize[1] = head_bin[7];
|
|
while (i != 4) {
|
|
head.e_filesize[i] = head_bin[2 + i];
|
|
i ++;
|
|
}
|
|
}
|
|
short int res2 = (strcmp(((char*)head.e_magic), "MZ"));
|
|
if (res1 != sizeof(head_bin) || res2 != 0) {
|
|
ntsys_error("Header read error or digital signature is invalid!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
unsigned long int filesize = 0;
|
|
if (sizeof(dword_t) != 4 || sizeof(qword_t) != 8 || sizeof(word_t) != 2) goto __exit_datatype_error;
|
|
switch (4) {
|
|
case sizeof(NAME_OF_64_BITS_TYPE): filesize = *((NAME_OF_64_BITS_TYPE*)head.e_filesize); break;
|
|
case sizeof(NAME_OF_32_BITS_TYPE): filesize = *((NAME_OF_32_BITS_TYPE*)head.e_filesize); break;
|
|
default:
|
|
__exit_datatype_error:
|
|
ntsys_error("Unknown data type! You must recompile the program and specify a different type.");
|
|
return EXIT_FAILURE;
|
|
}
|
|
unsigned int mem_size = (unsigned int)*((NAME_OF_16_BITS_TYPE*)head.e_memorysize);
|
|
__e_byte_t* memory = malloc(*((NAME_OF_16_BITS_TYPE*)head.e_memorysize));
|
|
if (memory == NULL) {
|
|
ntsys_error("Out of memory!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
if (debug) {
|
|
printf("File size %lu 0x%lX\n", filesize, filesize);
|
|
printf("Memory size %u 0x%X\n", mem_size, mem_size);
|
|
}
|
|
int stat = __exe_run(memory, isFullDebug, mem_size, filesize, fp, debug);
|
|
fclose(fp);
|
|
free(memory);
|
|
return stat;
|
|
}
|
|
|
|
int _lib_ntsys_main(int argc, char** argv) {
|
|
unsigned int t = 1;
|
|
char* filename = NULL;
|
|
char* asm_out = "out.exe";
|
|
char mode = 'R';
|
|
unsigned char out = 0;
|
|
unsigned char debug = 0;
|
|
unsigned char is_full_deb = 1;
|
|
unsigned char mem = 0;
|
|
while (t < argc) {
|
|
char* str = argv[t];
|
|
if (str[0] == '-') {
|
|
unsigned char f = 0;
|
|
if (str[1] == '-') f = 1;
|
|
switch (str[1 + f]) {
|
|
case 'd':
|
|
debug = 1;
|
|
break;
|
|
case 'n':
|
|
debug = 1;
|
|
is_full_deb = 0;
|
|
break;
|
|
case 'h':
|
|
__help();
|
|
return EXIT_SUCCESS;
|
|
case 'v':
|
|
puts(NTSYS_VERSION);
|
|
return EXIT_SUCCESS;
|
|
case 'a':
|
|
mode = 'A';
|
|
break;
|
|
case 'o':
|
|
out = 1;
|
|
mode = 'A';
|
|
break;
|
|
case 'm':
|
|
mem = 1;
|
|
mode = 'A';
|
|
break;
|
|
default:
|
|
ntsys_error("Unknown option!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
} else {
|
|
if (out) {
|
|
asm_out = str;
|
|
out = 0;
|
|
} else if (mem) {
|
|
fGH6VSEzu7qNiGVE_mem_size = strtol(str, NULL, 10);
|
|
mem = 0;
|
|
} else {
|
|
filename = str;
|
|
}
|
|
}
|
|
t ++;
|
|
}
|
|
if (filename == NULL || out) {
|
|
ntsys_error("Please specify the file name!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
if (mode == 'R') return ntsys_api_call(filename, debug, is_full_deb);
|
|
return ntsys_compile_asm(filename, asm_out);
|
|
}
|
|
|
|
#endif /* __LIB_ntsys_H_ */
|
|
|