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 AC_CANONICAL_HOST
@ -25,6 +28,9 @@ AM_PROG_CC_C_O
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
AC_CHECK_TOOLS(WINDRES, [windres], :) AC_CHECK_TOOLS(WINDRES, [windres], :)
PKG_CHECK_MODULES([SDL2], [sdl2])
SDL2_LIBS=${SDL2_LIBS/-mwindows/}
AC_ARG_ENABLE([ata-vga], AC_ARG_ENABLE([ata-vga],
[AS_HELP_STRING([--enable-ata-vga], [enable VGA (default=yes)])], [AS_HELP_STRING([--enable-ata-vga], [enable VGA (default=yes)])],
[WANT_ATA_VGA=$enableval], [WANT_ATA_VGA=yes]) [WANT_ATA_VGA=$enableval], [WANT_ATA_VGA=yes])
@ -40,13 +46,12 @@ AC_ARG_ENABLE(jit,
[WANT_JIT=$enableval], [WANT_JIT=no]) [WANT_JIT=$enableval], [WANT_JIT=no])
AC_CHECK_INCLUDES_DEFAULT AC_CHECK_INCLUDES_DEFAULT
AC_CHECK_HEADERS([libgen.h])
AC_C_CONST AC_C_CONST
AM_CONDITIONAL([USE_ATA_VGA], test "$WANT_ATA_VGA" = "yes") AM_CONDITIONAL([USE_ATA_VGA], test "$WANT_ATA_VGA" = "yes")
if test "$WANT_ATA_VGA" = "yes"; then if test "$WANT_ATA_VGA" = "yes"; then
AC_DEFINE([ATA_VGA], [1], [Enable VGA device]) AC_DEFINE([ATA_VGA], [1], [Enable VGA device])
PKG_CHECK_MODULES([SDL2], [sdl2])
fi fi
AM_CONDITIONAL([USE_ATA_ETHERNET], test "$WANT_ATA_ETHERNET" = "yes") AM_CONDITIONAL([USE_ATA_ETHERNET], test "$WANT_ATA_ETHERNET" = "yes")

View file

@ -1,11 +1,15 @@
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#include "lib/op.h" #include "lib/op.h"
#define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \ #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; char *prg_name;
FILE *input; FILE *input;
@ -14,261 +18,318 @@ FILE *output;
uint8_t uint8_t
readu8(void) readu8(void)
{ {
uint8_t val; uint8_t val;
if (fread(&val, 1, 1, input) != 1) if (fread(&val, 1, 1, input) != 1)
{ {
return (-1); /* XXX: TODO */ return (-1); /* XXX: TODO */
} }
return (val); return (val);
} }
uint16_t uint16_t
readu16(void) readu16(void)
{ {
uint16_t val; uint16_t val;
if (fread(&val, 1, 2, input) != 2) if (fread(&val, 1, 2, input) != 2)
{ {
return (-1); /* XXX: TODO */ return (-1); /* XXX: TODO */
} }
return (val); return (val);
} }
uint32_t uint32_t
readu32(void) readu32(void)
{ {
uint32_t val; uint32_t val;
if (fread(&val, 1, 4, input) != 4) if (fread(&val, 1, 4, input) != 4)
{ {
return (-1); /* XXX: TODO */ return (-1); /* XXX: TODO */
} }
return (val); return (val);
} }
int16_t int16_t
read16(void) read16(void)
{ {
int16_t val; int16_t val;
if (fread(&val, 1, 2, input) != 2) if (fread(&val, 1, 2, input) != 2)
{ {
return (-1); /* XXX: TODO */ return (-1); /* XXX: TODO */
} }
return (val); return (val);
} }
int32_t int32_t
read32(void) read32(void)
{ {
int32_t val; int32_t val;
if (fread(&val, 1, 4, input) != 4) if (fread(&val, 1, 4, input) != 4)
{ {
return (-1); /* XXX: TODO */ return (-1); /* XXX: TODO */
} }
return (val); return (val);
} }
void void
fatal(const char *str, ...) fatal(const char *str, ...)
{ {
va_list ap; va_list ap;
fprintf(stderr, "%s: ", prg_name); fprintf(stderr, "%s: ", prg_name);
va_start(ap, str); va_start(ap, str);
vfprintf(stderr, str, ap); vfprintf(stderr, str, ap);
va_end(ap); va_end(ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
void void
decode_target_suffix(uint8_t attr) decode_target_suffix(uint8_t attr)
{ {
fprintf(output, "."); fprintf(output, ".");
if (IS_TARGET_ZEXT(attr)) if (IS_TARGET_ZEXT(attr))
{ {
fprintf(output, "U"); fprintf(output, "U");
} }
switch (GET_TARGET_SIZE(attr)) switch (GET_TARGET_SIZE(attr))
{ {
case SIZE_BYTE: case SIZE_BYTE:
fprintf(output, "B"); fprintf(output, "B");
break; break;
case SIZE_WORD: case SIZE_WORD:
fprintf(output, "W"); fprintf(output, "W");
break; break;
case SIZE_LONG: case SIZE_LONG:
fprintf(output, "L"); fprintf(output, "L");
break; break;
} }
} }
void void
decode_address(uint8_t attr) decode_address(uint8_t attr)
{ {
switch (GET_ADDRESS_SIZE(attr)) switch (GET_ADDRESS_SIZE(attr))
{ {
case SIZE_BYTE: case SIZE_BYTE:
fprintf(output, " %%%X", readu8()); fprintf(output, " %%%X", readu8());
break; break;
case SIZE_WORD: case SIZE_WORD:
fprintf(output, " %%%hX", readu16()); fprintf(output, " %%%hX", readu16());
break; break;
case SIZE_LONG: case SIZE_LONG:
fprintf(output, " %%%X", readu32()); fprintf(output, " %%%X", readu32());
break; break;
default: default:
break; break;
} }
} }
void void
decode_imm(uint8_t opcode) decode_imm(uint8_t opcode)
{ {
uint8_t attr; uint8_t attr;
attr = readu8(); attr = readu8();
fprintf(output, "%s", opcode_str[opcode]); fprintf(output, "%s", opcode_str[opcode]);
decode_target_suffix(attr); decode_target_suffix(attr);
switch (GET_TARGET_SIZE(attr)) switch (GET_TARGET_SIZE(attr))
{ {
case SIZE_BYTE: case SIZE_BYTE:
fprintf(output, " #$%X\n", readu8()); fprintf(output, " #$%X\n", readu8());
break; break;
case SIZE_WORD: case SIZE_WORD:
fprintf(output, " #$%hX\n", readu16()); fprintf(output, " #$%hX\n", readu16());
break; break;
case SIZE_LONG: case SIZE_LONG:
fprintf(output, " #$%X\n", readu32()); fprintf(output, " #$%X\n", readu32());
break; break;
default: default:
break; break;
} }
} }
void void
decode_ind(uint8_t opcode) decode_ind(uint8_t opcode)
{ {
uint8_t attr; uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]); fprintf(output, "%s", opcode_str[opcode]);
attr = readu8(); attr = readu8();
if (opcode != OP_JMP_ind) if (opcode != OP_JMP_ind)
{ {
decode_target_suffix(attr); decode_target_suffix(attr);
} }
if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y)) if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y))
{ {
fprintf(output, " ("); fprintf(output, " (");
} }
else else
{ {
fprintf(output, " "); fprintf(output, " ");
} }
decode_address(attr); decode_address(attr);
if (opcode_addr[opcode] & OP_ADDR_X) if (opcode_addr[opcode] & OP_ADDR_X)
{ {
fprintf(output, ", X)"); fprintf(output, ", X)");
} }
else if (opcode_addr[opcode] & OP_ADDR_Y) else if (opcode_addr[opcode] & OP_ADDR_Y)
{ {
fprintf(output, "), Y"); fprintf(output, "), Y");
} }
fprintf(output, "\n"); fprintf(output, "\n");
} }
void void
decode_abs(uint8_t opcode) decode_abs(uint8_t opcode)
{ {
uint8_t attr; uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]); fprintf(output, "%s", opcode_str[opcode]);
attr = readu8(); attr = readu8();
if (opcode != OP_JSR_abs if (opcode != OP_JSR_abs
|| opcode != OP_JMP_abs) || opcode != OP_JMP_abs)
{ {
decode_target_suffix(attr); decode_target_suffix(attr);
} }
decode_address(attr); decode_address(attr);
if (opcode_addr[opcode] & OP_ADDR_X) if (opcode_addr[opcode] & OP_ADDR_X)
{ {
fprintf(output, ", X"); fprintf(output, ", X");
} }
else if (opcode_addr[opcode] & OP_ADDR_Y) else if (opcode_addr[opcode] & OP_ADDR_Y)
{ {
fprintf(output, ", Y"); fprintf(output, ", Y");
} }
fprintf(output, "\n"); fprintf(output, "\n");
} }
void void
decode(void) decode(void)
{ {
uint8_t opcode; uint8_t opcode;
int16_t relative; int16_t relative;
do { do {
opcode = readu8(); opcode = readu8();
if (feof(input)) return; if (feof(input)) return;
switch (opcode_addr[opcode] & OP_ADDR_MODE) switch (opcode_addr[opcode] & OP_ADDR_MODE)
{ {
case OP_ADDR_IMPL: case OP_ADDR_IMPL:
fprintf(output, "%s\n", opcode_str[opcode]); if (opcode_addr[opcode] & OP_ADDR_A)
break; {
case OP_ADDR_REL: fprintf(output, "%s A\n", opcode_str[opcode]);
relative = read16(); }
fprintf(output, "%s $%hX\n", opcode_str[opcode], relative); else
break; {
case OP_ADDR_IMM: fprintf(output, "%s\n", opcode_str[opcode]);
decode_imm(opcode); }
break; break;
case OP_ADDR_IND: case OP_ADDR_REL:
decode_ind(opcode); relative = read16();
break; fprintf(output, "%s $%hX\n", opcode_str[opcode], relative);
case OP_ADDR_ABS: break;
decode_abs(opcode); case OP_ADDR_IMM:
break; decode_imm(opcode);
default: break;
fprintf(output, "???\n", opcode); case OP_ADDR_IND:
break; decode_ind(opcode);
} break;
} while (!feof(input)); 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
prg_name = argv[0]; #ifdef HAVE_LIBGEN_H
input = stdin; prg_name = basename(argv[0]);
output = stdout; #else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
input = stdin;
output = stdout;
if (argc > 2) while ((argc > 1) && (argv[1][0] == '-'))
{ {
output = fopen(argv[2], "w"); switch (argv[1][1])
if (output == NULL) fatal("can't open %s.", argv[2]); {
} case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
default:
usage(EXIT_FAILURE);
break;
}
if (argc > 1) argv++;
{ argc--;
input = fopen(argv[1], "rb"); }
if (input == NULL) fatal("can't open %s.", argv[1]);
}
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, /* */ 0xFF,
/* PHP */ OP_ADDR_IMPL, /* PHP */ OP_ADDR_IMPL,
/* ORA */ OP_ADDR_IMM, /* ORA */ OP_ADDR_IMM,
/* ASL */ OP_ADDR_IMPL, /* ASL */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF, /* */ 0xFF,
/* */ 0xFF, /* */ 0xFF,
/* ORA */ OP_ADDR_ABS, /* ORA */ OP_ADDR_ABS,
@ -48,7 +48,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF, /* */ 0xFF,
/* PLP */ OP_ADDR_IMPL, /* PLP */ OP_ADDR_IMPL,
/* AND */ OP_ADDR_IMM, /* AND */ OP_ADDR_IMM,
/* ROL */ OP_ADDR_IMPL, /* ROL */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF, /* */ 0xFF,
/* BIT */ OP_ADDR_ABS, /* BIT */ OP_ADDR_ABS,
/* AND */ OP_ADDR_ABS, /* AND */ OP_ADDR_ABS,
@ -84,7 +84,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF, /* */ 0xFF,
/* PHA */ OP_ADDR_IMPL, /* PHA */ OP_ADDR_IMPL,
/* EOR */ OP_ADDR_IMM, /* EOR */ OP_ADDR_IMM,
/* LSR */ OP_ADDR_IMPL, /* LSR */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF, /* */ 0xFF,
/* JMP */ OP_ADDR_ABS, /* JMP */ OP_ADDR_ABS,
/* EOR */ OP_ADDR_ABS, /* EOR */ OP_ADDR_ABS,
@ -112,7 +112,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* 6- */ /* 6- */
/* RTS */ OP_ADDR_IMPL, /* RTS */ OP_ADDR_IMPL,
/* ADC */ OP_ADDR_IND | OP_ADDR_X, /* ADC */ OP_ADDR_IND | OP_ADDR_X,
/* */ 0xFF, /* PER */ OP_ADDR_IMPL,
/* */ 0xFF, /* */ 0xFF,
/* */ 0xFF, /* */ 0xFF,
/* ADC */ 0xFF, /* ADC */ 0xFF,
@ -120,7 +120,7 @@ const uint8_t opcode_addr[OP_MAX] = {
/* */ 0xFF, /* */ 0xFF,
/* PLA */ OP_ADDR_IMPL, /* PLA */ OP_ADDR_IMPL,
/* ADC */ OP_ADDR_IMM, /* ADC */ OP_ADDR_IMM,
/* ROR */ OP_ADDR_IMPL, /* ROR */ OP_ADDR_IMPL | OP_ADDR_A,
/* */ 0xFF, /* */ 0xFF,
/* JMP */ OP_ADDR_IND, /* JMP */ OP_ADDR_IND,
/* ADC */ OP_ADDR_ABS, /* ADC */ OP_ADDR_ABS,
@ -291,20 +291,20 @@ const uint8_t opcode_addr[OP_MAX] = {
}; };
const char *opcode_str[OP_MAX] = { const char *opcode_str[OP_MAX] = {
"BRK", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "PHP", "ORA", "ASLA", NULL, NULL, "ORA", "ASL", 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, "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, "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, "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, "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, "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, "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, "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, 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, "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, "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, "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, "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, "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, "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 "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_ABS 1 << 3
# define OP_ADDR_X 1 << 4 # define OP_ADDR_X 1 << 4
# define OP_ADDR_Y 1 << 5 # define OP_ADDR_Y 1 << 5
# define OP_ADDR_A 1 << 6
# define OP_BRK_impl 0x00 # define OP_BRK_impl 0x00
# define OP_ORA_x_ind 0x01 # define OP_ORA_x_ind 0x01

View file

@ -7,5 +7,5 @@ noinst_LIBRARIES = $(LIBJIT) $(LIB_ATA)
bin_PROGRAMS = vm bin_PROGRAMS = vm
vm_SOURCES = main.c vm_SOURCES = main.c
vm_CFLAGS =-I$(top_srcdir) vm_CFLAGS =-I$(top_srcdir) $(SDL2_CFLAGS)
vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES) vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES) $(SDL2_LIBS)

View file

@ -5,3 +5,7 @@ libata_a_SOURCES = ata/ata.c ata/rtc.c
if USE_ATA_VGA if USE_ATA_VGA
libata_a_SOURCES += ata/vga.c libata_a_SOURCES += ata/vga.c
endif endif
if USE_ATA_ETHERNET
libata_a_SOURCES += ata/ethernet.c
endif

View file

@ -1,4 +1,4 @@
#include "isa.h" #include "ata.h"
static const uint8_t mac_addr[6] = { static const uint8_t mac_addr[6] = {
0x53, 0x54, 0x41, 0x4C, 0x49, 0x4E 0x53, 0x54, 0x41, 0x4C, 0x49, 0x4E

View file

@ -7,7 +7,7 @@
#define REG_WKDAY 0x06 #define REG_WKDAY 0x06
#define REG_DAY 0x07 #define REG_DAY 0x07
#define REG_YEAR 0x09 #define REG_YEAR 0x09
#define REG_CENTURY 0x032 #define REG_CENTURY 0x32
#define REG_STATUSA 0x0A #define REG_STATUSA 0x0A
#define REG_STATUSB 0x0B #define REG_STATUSB 0x0B

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 "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#include <SDL.h>
static const char *prg_name; static const char *prg_name;
void static void
usage(void) usage(int retcode)
{ {
printf("Usage: %s [-hV] [-b bios]\n"); 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
prg_name = argv[0]; #ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]);
#else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
return (EXIT_SUCCESS); 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 */