Basic cli handling

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-02-29 13:01:58 +01:00
parent d53f1cbfe0
commit 262a211da9
14 changed files with 514 additions and 292 deletions

View file

@ -1,4 +1,7 @@
AC_INIT([65oo2], [1.0])
AC_INIT([65∞2], [1.0],
[https://git.cute.engineering/d0p1/65oo2/issues],
[65oo2],
[https://git.cute.engineering/d0p1/65oo2])
AC_CANONICAL_HOST
@ -25,6 +28,9 @@ AM_PROG_CC_C_O
PKG_PROG_PKG_CONFIG
AC_CHECK_TOOLS(WINDRES, [windres], :)
PKG_CHECK_MODULES([SDL2], [sdl2])
SDL2_LIBS=${SDL2_LIBS/-mwindows/}
AC_ARG_ENABLE([ata-vga],
[AS_HELP_STRING([--enable-ata-vga], [enable VGA (default=yes)])],
[WANT_ATA_VGA=$enableval], [WANT_ATA_VGA=yes])
@ -40,13 +46,12 @@ AC_ARG_ENABLE(jit,
[WANT_JIT=$enableval], [WANT_JIT=no])
AC_CHECK_INCLUDES_DEFAULT
AC_CHECK_HEADERS([libgen.h])
AC_C_CONST
AM_CONDITIONAL([USE_ATA_VGA], test "$WANT_ATA_VGA" = "yes")
if test "$WANT_ATA_VGA" = "yes"; then
AC_DEFINE([ATA_VGA], [1], [Enable VGA device])
PKG_CHECK_MODULES([SDL2], [sdl2])
fi
AM_CONDITIONAL([USE_ATA_ETHERNET], test "$WANT_ATA_ETHERNET" = "yes")

View file

@ -1,11 +1,15 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#include "lib/op.h"
#define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \
| OP_ADDR_IMM | OP_ADDR_ABS)
| OP_ADDR_IMM | OP_ADDR_ABS)
char *prg_name;
FILE *input;
@ -14,261 +18,318 @@ FILE *output;
uint8_t
readu8(void)
{
uint8_t val;
uint8_t val;
if (fread(&val, 1, 1, input) != 1)
{
return (-1); /* XXX: TODO */
}
if (fread(&val, 1, 1, input) != 1)
{
return (-1); /* XXX: TODO */
}
return (val);
return (val);
}
uint16_t
readu16(void)
{
uint16_t val;
uint16_t val;
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
return (val);
return (val);
}
uint32_t
readu32(void)
{
uint32_t val;
uint32_t val;
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
return (val);
return (val);
}
int16_t
read16(void)
{
int16_t val;
int16_t val;
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
return (val);
return (val);
}
int32_t
read32(void)
{
int32_t val;
int32_t val;
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
return (val);
return (val);
}
void
fatal(const char *str, ...)
{
va_list ap;
va_list ap;
fprintf(stderr, "%s: ", prg_name);
va_start(ap, str);
vfprintf(stderr, str, ap);
va_end(ap);
fprintf(stderr, "\n");
fprintf(stderr, "%s: ", prg_name);
va_start(ap, str);
vfprintf(stderr, str, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
void
decode_target_suffix(uint8_t attr)
{
fprintf(output, ".");
if (IS_TARGET_ZEXT(attr))
{
fprintf(output, "U");
}
fprintf(output, ".");
if (IS_TARGET_ZEXT(attr))
{
fprintf(output, "U");
}
switch (GET_TARGET_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, "B");
break;
case SIZE_WORD:
fprintf(output, "W");
break;
case SIZE_LONG:
fprintf(output, "L");
break;
}
switch (GET_TARGET_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, "B");
break;
case SIZE_WORD:
fprintf(output, "W");
break;
case SIZE_LONG:
fprintf(output, "L");
break;
}
}
void
decode_address(uint8_t attr)
{
switch (GET_ADDRESS_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, " %%%X", readu8());
break;
case SIZE_WORD:
fprintf(output, " %%%hX", readu16());
break;
case SIZE_LONG:
fprintf(output, " %%%X", readu32());
break;
default:
break;
}
switch (GET_ADDRESS_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, " %%%X", readu8());
break;
case SIZE_WORD:
fprintf(output, " %%%hX", readu16());
break;
case SIZE_LONG:
fprintf(output, " %%%X", readu32());
break;
default:
break;
}
}
void
decode_imm(uint8_t opcode)
{
uint8_t attr;
uint8_t attr;
attr = readu8();
attr = readu8();
fprintf(output, "%s", opcode_str[opcode]);
decode_target_suffix(attr);
switch (GET_TARGET_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, " #$%X\n", readu8());
break;
case SIZE_WORD:
fprintf(output, " #$%hX\n", readu16());
break;
case SIZE_LONG:
fprintf(output, " #$%X\n", readu32());
break;
default:
break;
}
fprintf(output, "%s", opcode_str[opcode]);
decode_target_suffix(attr);
switch (GET_TARGET_SIZE(attr))
{
case SIZE_BYTE:
fprintf(output, " #$%X\n", readu8());
break;
case SIZE_WORD:
fprintf(output, " #$%hX\n", readu16());
break;
case SIZE_LONG:
fprintf(output, " #$%X\n", readu32());
break;
default:
break;
}
}
void
decode_ind(uint8_t opcode)
{
uint8_t attr;
uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8();
if (opcode != OP_JMP_ind)
{
decode_target_suffix(attr);
}
if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y))
{
fprintf(output, " (");
}
else
{
fprintf(output, " ");
}
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8();
if (opcode != OP_JMP_ind)
{
decode_target_suffix(attr);
}
if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y))
{
fprintf(output, " (");
}
else
{
fprintf(output, " ");
}
decode_address(attr);
decode_address(attr);
if (opcode_addr[opcode] & OP_ADDR_X)
{
fprintf(output, ", X)");
}
else if (opcode_addr[opcode] & OP_ADDR_Y)
{
fprintf(output, "), Y");
}
fprintf(output, "\n");
if (opcode_addr[opcode] & OP_ADDR_X)
{
fprintf(output, ", X)");
}
else if (opcode_addr[opcode] & OP_ADDR_Y)
{
fprintf(output, "), Y");
}
fprintf(output, "\n");
}
void
decode_abs(uint8_t opcode)
{
uint8_t attr;
uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8();
if (opcode != OP_JSR_abs
|| opcode != OP_JMP_abs)
{
decode_target_suffix(attr);
}
decode_address(attr);
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8();
if (opcode != OP_JSR_abs
|| opcode != OP_JMP_abs)
{
decode_target_suffix(attr);
}
decode_address(attr);
if (opcode_addr[opcode] & OP_ADDR_X)
{
fprintf(output, ", X");
}
else if (opcode_addr[opcode] & OP_ADDR_Y)
{
fprintf(output, ", Y");
}
fprintf(output, "\n");
if (opcode_addr[opcode] & OP_ADDR_X)
{
fprintf(output, ", X");
}
else if (opcode_addr[opcode] & OP_ADDR_Y)
{
fprintf(output, ", Y");
}
fprintf(output, "\n");
}
void
decode(void)
{
uint8_t opcode;
int16_t relative;
uint8_t opcode;
int16_t relative;
do {
opcode = readu8();
if (feof(input)) return;
switch (opcode_addr[opcode] & OP_ADDR_MODE)
{
case OP_ADDR_IMPL:
fprintf(output, "%s\n", opcode_str[opcode]);
break;
case OP_ADDR_REL:
relative = read16();
fprintf(output, "%s $%hX\n", opcode_str[opcode], relative);
break;
case OP_ADDR_IMM:
decode_imm(opcode);
break;
case OP_ADDR_IND:
decode_ind(opcode);
break;
case OP_ADDR_ABS:
decode_abs(opcode);
break;
default:
fprintf(output, "???\n", opcode);
break;
}
} while (!feof(input));
do {
opcode = readu8();
if (feof(input)) return;
switch (opcode_addr[opcode] & OP_ADDR_MODE)
{
case OP_ADDR_IMPL:
if (opcode_addr[opcode] & OP_ADDR_A)
{
fprintf(output, "%s A\n", opcode_str[opcode]);
}
else
{
fprintf(output, "%s\n", opcode_str[opcode]);
}
break;
case OP_ADDR_REL:
relative = read16();
fprintf(output, "%s $%hX\n", opcode_str[opcode], relative);
break;
case OP_ADDR_IMM:
decode_imm(opcode);
break;
case OP_ADDR_IND:
decode_ind(opcode);
break;
case OP_ADDR_ABS:
decode_abs(opcode);
break;
default:
fprintf(output, "???\n", opcode);
break;
}
} while (!feof(input));
}
void
usage(int retcode)
{
if (retcode == EXIT_FAILURE)
{
fprintf(stderr,
"Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s [-hV] [INPUT] [OUTPUT]\n", prg_name);
printf("Disassemble INPUT to OUTPUT\n\n");
printf("With no INPUT read standard input.\n");
printf("With no OUTPUT write standard output.\n\n");
printf("\t-h\tdisplay this help and exit\n");
printf("\t-V\toutput version information\n");
printf("\nReport bugs to <%s>\n", PACKAGE_BUGREPORT);
}
exit(retcode);
}
void
version(void)
{
printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
prg_name = argv[0];
input = stdin;
output = stdout;
#ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]);
#else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
input = stdin;
output = stdout;
if (argc > 2)
{
output = fopen(argv[2], "w");
if (output == NULL) fatal("can't open %s.", argv[2]);
}
while ((argc > 1) && (argv[1][0] == '-'))
{
switch (argv[1][1])
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
default:
usage(EXIT_FAILURE);
break;
}
if (argc > 1)
{
input = fopen(argv[1], "rb");
if (input == NULL) fatal("can't open %s.", argv[1]);
}
argv++;
argc--;
}
decode();
if (argc > 2)
{
output = fopen(argv[2], "w");
if (output == NULL) fatal("can't open %s.", argv[2]);
}
if (argc > 1)
{
input = fopen(argv[1], "rb");
if (input == NULL) fatal("can't open %s.", argv[1]);
}
return (EXIT_SUCCESS);
decode();
return (EXIT_SUCCESS);
}

View file

@ -12,7 +12,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF,
/* PHP */ OP_ADDR_IMPL,
/* ORA */ OP_ADDR_IMM,
/* ASL */ OP_ADDR_IMPL,
/* ASL */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF,
/* */ 0xFF,
/* ORA */ OP_ADDR_ABS,
@ -48,7 +48,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF,
/* PLP */ OP_ADDR_IMPL,
/* AND */ OP_ADDR_IMM,
/* ROL */ OP_ADDR_IMPL,
/* ROL */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF,
/* BIT */ OP_ADDR_ABS,
/* AND */ OP_ADDR_ABS,
@ -84,7 +84,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF,
/* PHA */ OP_ADDR_IMPL,
/* EOR */ OP_ADDR_IMM,
/* LSR */ OP_ADDR_IMPL,
/* LSR */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF,
/* JMP */ OP_ADDR_ABS,
/* EOR */ OP_ADDR_ABS,
@ -112,7 +112,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* 6- */
/* RTS */ OP_ADDR_IMPL,
/* ADC */ OP_ADDR_IND | OP_ADDR_X,
/* */ 0xFF,
/* PER */ OP_ADDR_IMPL,
/* */ 0xFF,
/* */ 0xFF,
/* ADC */ 0xFF,
@ -120,7 +120,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF,
/* PLA */ OP_ADDR_IMPL,
/* ADC */ OP_ADDR_IMM,
/* ROR */ OP_ADDR_IMPL,
/* ROR */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF,
/* JMP */ OP_ADDR_IND,
/* ADC */ OP_ADDR_ABS,
@ -291,20 +291,20 @@ const uint8_t opcode_addr[OP_MAX] = {
};
const char *opcode_str[OP_MAX] = {
"BRK", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "PHP", "ORA", "ASLA", NULL, NULL, "ORA", "ASL", NULL,
"BPL", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "CLC", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL,
"JSR", "AND", NULL, NULL, "BIT", "AND", "ROL", NULL, "PLP", "AND", "ROLA", NULL, "BIT", "AND", "ROL", NULL,
"BMI", "AND", NULL, NULL, NULL, "AND", "ROL", NULL, "SEC", "AND", NULL, NULL, NULL, "AND", "ROL", NULL,
"RTI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "PHA", "EOR", "LSRA", NULL, "JMP", "EOR", "LSR", NULL,
"BVC", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "CLI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL,
"RTS", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, "PLA", "ADC", "RORA", NULL, "JMP", "ADC", "ROR", NULL,
"BVS", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, "SEI", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL,
NULL, "STA", NULL, NULL, "STY", "STA", "STX", NULL, "DEY", NULL, "TXA", NULL, "STY", "STA", "STX", NULL,
"BCC", "STA", NULL, NULL, "STY", "STA", "STX", NULL, "TYA", "STA", "TXS", NULL, NULL, "STA", NULL, NULL,
"LDY", "LDA", "LDX", NULL, "LDY", "LDA", "LDX", NULL, "TAY", "LDA", "TAX", NULL, "LDY", "LDA", "LDX", NULL,
"BCS", "LDA", NULL, NULL, "LDY", "LDA", "LDX", NULL, "CLV", "LDA", "TSX", NULL, "LDY", "LDA", "LDX", NULL,
"CPY", "CMP", NULL, NULL, "CPY", "CMP", "DEC", NULL, "INY", "CMP", "DEX", NULL, "CPY", "CMP", "DEC", NULL,
"BNE", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL, "CLD", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL,
"CPX", "SBC", NULL, NULL, "CPX", "SBC", "INC", NULL, "INX", "SBC", "NOP", NULL, "CPX", "SBC", "INC", NULL,
"BEQ", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL, "SED", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL
"BRK", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "PHP", "ORA", "ASL", NULL, NULL, "ORA", "ASL", NULL,
"BPL", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "CLC", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL,
"JSR", "AND", NULL, NULL, "BIT", "AND", "ROL", NULL, "PLP", "AND", "ROL", NULL, "BIT", "AND", "ROL", NULL,
"BMI", "AND", NULL, NULL, NULL, "AND", "ROL", NULL, "SEC", "AND", NULL, NULL, NULL, "AND", "ROL", NULL,
"RTI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "PHA", "EOR", "LSR", NULL, "JMP", "EOR", "LSR", NULL,
"BVC", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "CLI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL,
"RTS", "ADC", "PER", NULL, NULL, "ADC", "ROR", NULL, "PLA", "ADC", "ROR", NULL, "JMP", "ADC", "ROR", NULL,
"BVS", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, "SEI", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL,
NULL, "STA", NULL, NULL, "STY", "STA", "STX", NULL, "DEY", NULL, "TXA", NULL, "STY", "STA", "STX", NULL,
"BCC", "STA", NULL, NULL, "STY", "STA", "STX", NULL, "TYA", "STA", "TXS", NULL, NULL, "STA", NULL, NULL,
"LDY", "LDA", "LDX", NULL, "LDY", "LDA", "LDX", NULL, "TAY", "LDA", "TAX", NULL, "LDY", "LDA", "LDX", NULL,
"BCS", "LDA", NULL, NULL, "LDY", "LDA", "LDX", NULL, "CLV", "LDA", "TSX", NULL, "LDY", "LDA", "LDX", NULL,
"CPY", "CMP", NULL, NULL, "CPY", "CMP", "DEC", NULL, "INY", "CMP", "DEX", NULL, "CPY", "CMP", "DEC", NULL,
"BNE", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL, "CLD", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL,
"CPX", "SBC", NULL, NULL, "CPX", "SBC", "INC", NULL, "INX", "SBC", "NOP", NULL, "CPX", "SBC", "INC", NULL,
"BEQ", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL, "SED", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL
};

View file

@ -12,6 +12,7 @@
# define OP_ADDR_ABS 1 << 3
# define OP_ADDR_X 1 << 4
# define OP_ADDR_Y 1 << 5
# define OP_ADDR_A 1 << 6
# define OP_BRK_impl 0x00
# define OP_ORA_x_ind 0x01

View file

@ -1,11 +1,11 @@
include jit/Makefrag.am
include ata/Makefrag.am
include res/Makefrag.am
noinst_LIBRARIES = $(LIBJIT) $(LIB_ATA)
bin_PROGRAMS = vm
vm_SOURCES = main.c
vm_CFLAGS =-I$(top_srcdir)
vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES)
include jit/Makefrag.am
include ata/Makefrag.am
include res/Makefrag.am
noinst_LIBRARIES = $(LIBJIT) $(LIB_ATA)
bin_PROGRAMS = vm
vm_SOURCES = main.c
vm_CFLAGS =-I$(top_srcdir) $(SDL2_CFLAGS)
vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES) $(SDL2_LIBS)

View file

@ -1,7 +1,11 @@
LIB_ATA = libata.a
libata_a_SOURCES = ata/ata.c ata/rtc.c
if USE_ATA_VGA
libata_a_SOURCES += ata/vga.c
endif
LIB_ATA = libata.a
libata_a_SOURCES = ata/ata.c ata/rtc.c
if USE_ATA_VGA
libata_a_SOURCES += ata/vga.c
endif
if USE_ATA_ETHERNET
libata_a_SOURCES += ata/ethernet.c
endif

View file

@ -1,14 +1,14 @@
#include "isa.h"
static const uint8_t mac_addr[6] = {
0x53, 0x54, 0x41, 0x4C, 0x49, 0x4E
};
AtaDevice ethernet_dev = {
"TinyEthernet",
0x360,
0x36F,
NULL,
NULL,
NULL
};
#include "ata.h"
static const uint8_t mac_addr[6] = {
0x53, 0x54, 0x41, 0x4C, 0x49, 0x4E
};
AtaDevice ethernet_dev = {
"TinyEthernet",
0x360,
0x36F,
NULL,
NULL,
NULL
};

View file

@ -1,45 +1,45 @@
#include <time.h>
#include "ata.h"
#define REG_SECS 0x00
#define REG_MINS 0x00
#define REG_HOURS 0x00
#define REG_WKDAY 0x06
#define REG_DAY 0x07
#define REG_YEAR 0x09
#define REG_CENTURY 0x032
#define REG_STATUSA 0x0A
#define REG_STATUSB 0x0B
static uint8_t current_reg = 0x00;
void
rtc_write(uint8_t addr, uint8_t value)
{
if (addr == 0)
{
current_reg = value;
}
}
uint8_t
rtc_read(uint8_t addr)
{
time_t time;
struct tm tm;
localtime(&time);
(void)time;
(void)tm;
return (0x00);
}
AtaDevice rtc_dev = {
"RTC",
0x070,
0x071,
NULL,
NULL
};
#include <time.h>
#include "ata.h"
#define REG_SECS 0x00
#define REG_MINS 0x00
#define REG_HOURS 0x00
#define REG_WKDAY 0x06
#define REG_DAY 0x07
#define REG_YEAR 0x09
#define REG_CENTURY 0x32
#define REG_STATUSA 0x0A
#define REG_STATUSB 0x0B
static uint8_t current_reg = 0x00;
void
rtc_write(uint8_t addr, uint8_t value)
{
if (addr == 0)
{
current_reg = value;
}
}
uint8_t
rtc_read(uint8_t addr)
{
time_t time;
struct tm tm;
localtime(&time);
(void)time;
(void)tm;
return (0x00);
}
AtaDevice rtc_dev = {
"RTC",
0x070,
0x071,
NULL,
NULL
};

16
vm/bus.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef VM_BUS_H
# define VM_BUS_H 1
# include <stddef.h>
# include <stdint.h>
typedef int (*BusRead)(uint32_t addr, void *data, size_t sz);
typedef int (*BusWrite)(uint32_t addr, const void *data, size_t sz);
typedef struct
{
BusRead read;
BusWrite write;
} Bus;
#endif /* !VM_BUS_H */

23
vm/cpu.c Normal file
View file

@ -0,0 +1,23 @@
#include <stdlib.h>
#include "cpu.h"
void
invalid_opcode(Cpu *cpu)
{
exit(EXIT_FAILURE);
}
void
cpu_execute(Cpu *cpu)
{
uint8_t opcode;
switch (opcode)
{
default:
invalid_opcode();
break;
}
cpu->PC += 1;
}

16
vm/cpu.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef VM_CPU_H
# define VM_CPU_H 1
# include <stdint.h>
typedef struct
{
uint32_t PC;
uint32_t A;
uint32_t X;
uint32_t Y;
uint8_t SR;
uint32_t SP;
} Cpu;
#endif /* !VM_CPU_H */

View file

@ -1,18 +1,65 @@
#include <stdlib.h>
#include <stdio.h>
static const char *prg_name;
void
usage(void)
{
printf("Usage: %s [-hV] [-b bios]\n");
}
int
main(int argc, char **argv)
{
prg_name = argv[0];
return (EXIT_SUCCESS);
}
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#include <SDL.h>
static const char *prg_name;
static void
usage(int retcode)
{
if (retcode == EXIT_FAILURE)
{
fprintf(stderr,
"Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s [-hV] [-b bios]\n", prg_name);
printf("\t-h\tdisplay this help and exit\n");
printf("\t-V\toutput version information\n");
printf("\nReport bugs to <%s>\n", PACKAGE_BUGREPORT);
}
exit(retcode);
}
static void
version(void)
{
printf("%S version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
#ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]);
#else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
while ((argc > 1) && (argv[1][0] == '-'))
{
switch (argv[1][1])
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
default:
usage(EXIT_FAILURE);
break;
}
argv++;
argc--;
}
return (EXIT_SUCCESS);
}

32
vm/net/tap-linux.c Normal file
View file

@ -0,0 +1,32 @@
#include <linux/if_tun.h>
/*
* man 7 netdevice
* man 4 tap
*/
void
tap_new(void)
{
int fd;
struct ifreq req;
fd = open("/dev/net/tun", O_RDWR);
if (fd < 0)
{
return;
}
memset(&req, 0, sizeof(struct ifreq));
req.ifr_flags = IFF_TAP | IFF_NO_PI;
/*
* malloc(IFNAMSIZ);
* tun_alloc(xxxx, IFF_TAP);
*/
strncpy(req.ifr_name, "todo", 5);
if (ioctl(fd, TUNSETIFF, &req) < 0)
{
return;
}
}

17
vm/vm.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef VM_VM_H
# define VM_VM_H 1
# include "cpu.h"
# include "bus.h"
# define VM_MAX_CPU 8
typedef struct
{
int cpu_count;
Cpu cpus[VM_MAX_CPU];
Bus bus;
} Vm;
#endif /* !VM_VM_H */