Wip VM
This commit is contained in:
parent
4ad7bb1bf1
commit
62305e44c3
21
doc/memory.org
Normal file
21
doc/memory.org
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
|
||||||
|
#+begin_src
|
||||||
|
0xFFFFFFFF +-----------------------+
|
||||||
|
| isa mmio |
|
||||||
|
0xFFFFF000 +-----------------------+
|
||||||
|
. .
|
||||||
|
. .
|
||||||
|
. .
|
||||||
|
0xFFFBFFFF +-----------------------+
|
||||||
|
| video ram |
|
||||||
|
0xFFFB0000 +-----------------------+
|
||||||
|
. .
|
||||||
|
. .
|
||||||
|
. .
|
||||||
|
0xFFF00000 +-----------------------+
|
||||||
|
| ROM |
|
||||||
|
+-----------------------+
|
||||||
|
| RAM |
|
||||||
|
0x00000000 +-----------------------+
|
||||||
|
#+end_src
|
|
@ -6,6 +6,6 @@ noinst_LIBRARIES = $(LIBJIT) $(LIB_ATA)
|
||||||
|
|
||||||
bin_PROGRAMS = vm
|
bin_PROGRAMS = vm
|
||||||
|
|
||||||
vm_SOURCES = main.c
|
vm_SOURCES = main.c video/monitor.c
|
||||||
vm_CFLAGS =-I$(top_srcdir) $(SDL2_CFLAGS)
|
vm_CFLAGS =-I$(top_srcdir) $(SDL2_CFLAGS)
|
||||||
vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES) $(SDL2_LIBS)
|
vm_LDADD = ../lib/lib65oo2.a ../libutils/libutils.a $(LIBJIT) $(LIB_ATA) $(RES) $(SDL2_LIBS)
|
||||||
|
|
38
vm/ata/ata.c
38
vm/ata/ata.c
|
@ -1,27 +1,21 @@
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "../bus.h"
|
||||||
|
|
||||||
extern AtaDevice rtc_dev;
|
static struct bus *devices = {
|
||||||
#ifdef ATA_ETHERNET
|
&rtc_device,
|
||||||
extern AtaDevice ethernet_dev;
|
ðernet_device,
|
||||||
#endif /* ATA_ETHERNET */
|
&serial3_device,
|
||||||
#ifdef ATA_VGA
|
&serial2_device,
|
||||||
extern AtaDevice vga_dev;
|
&serial1_device,
|
||||||
#endif /* ATA_VGA */
|
NULL,
|
||||||
|
|
||||||
|
|
||||||
AtaDevice *devices[] = {
|
|
||||||
&rtc_dev,
|
|
||||||
#ifdef ATA_ETHERNET
|
|
||||||
ðernet_dev,
|
|
||||||
#endif /* ATA_ETHERNET */
|
|
||||||
#ifdef ATA_VGA
|
|
||||||
&vga_dev,
|
|
||||||
#endif /* ATA_VGA */
|
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
ata_bus_initialize(void)
|
struct bus isa_bus = {
|
||||||
{
|
"isa-mmio",
|
||||||
}
|
{0xFFFFF000, UINT32_MAX},
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
devices
|
||||||
|
};
|
18
vm/ata/ata.h
18
vm/ata/ata.h
|
@ -2,18 +2,12 @@
|
||||||
# define VM_ATA_ATA_H 1
|
# define VM_ATA_ATA_H 1
|
||||||
|
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
# include "../bus.h"
|
||||||
|
|
||||||
typedef void (*IoWrite)(uint8_t offset, uint8_t data);
|
extern struct bus rtc_device;
|
||||||
typedef uint8_t (*IoRead)(uint8_t offset);
|
extern struct bus ethernet_device;
|
||||||
|
extern struct bus serial3_device;
|
||||||
typedef struct
|
extern struct bus serial2_device;
|
||||||
{
|
extern struct bus serial1_device;
|
||||||
char const *name;
|
|
||||||
uint16_t start;
|
|
||||||
uint16_t end;
|
|
||||||
void *state;
|
|
||||||
IoWrite io_write;
|
|
||||||
IoRead io_read;
|
|
||||||
} AtaDevice;
|
|
||||||
|
|
||||||
#endif /* VM_ATA_ATA_H */
|
#endif /* VM_ATA_ATA_H */
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#include "ata.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
|
||||||
};
|
};
|
||||||
|
|
||||||
AtaDevice ethernet_dev = {
|
struct bus ethernet_device = {
|
||||||
"TinyEthernet",
|
"ethernet-dev",
|
||||||
0x360,
|
{0x360, 0x36F},
|
||||||
0x36F,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
32
vm/ata/rtc.c
32
vm/ata/rtc.c
|
@ -16,30 +16,30 @@ static uint8_t current_reg = 0x00;
|
||||||
void
|
void
|
||||||
rtc_write(uint8_t addr, uint8_t value)
|
rtc_write(uint8_t addr, uint8_t value)
|
||||||
{
|
{
|
||||||
if (addr == 0)
|
if (addr == 0)
|
||||||
{
|
{
|
||||||
current_reg = value;
|
current_reg = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
rtc_read(uint8_t addr)
|
rtc_read(uint8_t addr)
|
||||||
{
|
{
|
||||||
time_t time;
|
time_t time;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
localtime(&time);
|
localtime(&time);
|
||||||
|
|
||||||
(void)time;
|
(void)time;
|
||||||
(void)tm;
|
(void)tm;
|
||||||
|
|
||||||
return (0x00);
|
return (0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
AtaDevice rtc_dev = {
|
struct bus rtc_device = {
|
||||||
"RTC",
|
"rtc-dev",
|
||||||
0x070,
|
{0x070, 0x071},
|
||||||
0x071,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
|
|
||||||
AtaDevice com3_dev = {
|
struct bus serial3_device = {
|
||||||
"COM3",
|
"serial3-dev",
|
||||||
0x3E0,
|
{0x3E0, 0x3EF},
|
||||||
0x3EF,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
AtaDevice com2_dev = {
|
struct bus serial2_device = {
|
||||||
"COM2",
|
"serial2-dev",
|
||||||
0x2F8,
|
{0x02F8, 0x2FF},
|
||||||
0x2FF,
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
AtaDevice com1_dev = {
|
struct bus serial1_device = {
|
||||||
"COM1",
|
"serial1-dev",
|
||||||
0x3F8,
|
{0x3F8, 0x3FF},
|
||||||
0x3FF,
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
22
vm/ata/vga.c
22
vm/ata/vga.c
|
@ -1,22 +0,0 @@
|
||||||
#include "ata.h"
|
|
||||||
|
|
||||||
enum VGA_REG {
|
|
||||||
REG_CRTC_ADDR,
|
|
||||||
REG_CRTC_DATA,
|
|
||||||
REG_INPUT_STATUS1,
|
|
||||||
REG_FEAT_CTRL,
|
|
||||||
REG_ATTR_ADDR,
|
|
||||||
REG_ATTR_DATA,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum VGA_CRTC {
|
|
||||||
XXX
|
|
||||||
};
|
|
||||||
|
|
||||||
AtaDevice vga_dev = {
|
|
||||||
"TinyVGA",
|
|
||||||
0x3C0,
|
|
||||||
0x3CF,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
};
|
|
12
vm/bus.c
12
vm/bus.c
|
@ -1,7 +1,6 @@
|
||||||
void
|
|
||||||
bus_initialize(void)
|
#include <stdint.h>
|
||||||
{
|
#include "bus.h"
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bus_read(void)
|
bus_read(void)
|
||||||
|
@ -17,3 +16,8 @@ void
|
||||||
bus_reset(void)
|
bus_reset(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct bus mainbus = {
|
||||||
|
"mainbus",
|
||||||
|
{0x0, UINT32_MAX},
|
||||||
|
};
|
17
vm/bus.h
17
vm/bus.h
|
@ -7,10 +7,19 @@
|
||||||
typedef int (*BusRead)(uint32_t addr, void *data, size_t sz);
|
typedef int (*BusRead)(uint32_t addr, void *data, size_t sz);
|
||||||
typedef int (*BusWrite)(uint32_t addr, const void *data, size_t sz);
|
typedef int (*BusWrite)(uint32_t addr, const void *data, size_t sz);
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
uint32_t start;
|
||||||
BusRead read;
|
uint32_t end;
|
||||||
BusWrite write;
|
} Range;
|
||||||
|
|
||||||
|
typedef struct bus {
|
||||||
|
const char *name;
|
||||||
|
Range range;
|
||||||
|
|
||||||
|
BusRead read;
|
||||||
|
BusWrite write;
|
||||||
|
|
||||||
|
struct bus *sub[];
|
||||||
} Bus;
|
} Bus;
|
||||||
|
|
||||||
#endif /* !VM_BUS_H */
|
#endif /* !VM_BUS_H */
|
6
vm/cpu.c
6
vm/cpu.c
|
@ -1,6 +1,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_reset(Cpu *cpu)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
invalid_opcode(Cpu *cpu)
|
invalid_opcode(Cpu *cpu)
|
||||||
{
|
{
|
||||||
|
|
5
vm/cpu.h
5
vm/cpu.h
|
@ -11,6 +11,11 @@ typedef struct
|
||||||
uint32_t Y;
|
uint32_t Y;
|
||||||
uint8_t SR;
|
uint8_t SR;
|
||||||
uint32_t SP;
|
uint32_t SP;
|
||||||
|
uint32_t CR0;
|
||||||
|
uint32_t CR1;
|
||||||
|
uint32_t CR2;
|
||||||
} Cpu;
|
} Cpu;
|
||||||
|
|
||||||
|
void cpu_reset(Cpu *cpu);
|
||||||
|
|
||||||
#endif /* !VM_CPU_H */
|
#endif /* !VM_CPU_H */
|
54
vm/main.c
54
vm/main.c
|
@ -1,12 +1,38 @@
|
||||||
#include "config.h"
|
#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>
|
#include <SDL.h>
|
||||||
|
#include "libutils/utils.h"
|
||||||
|
#include "video.h"
|
||||||
|
|
||||||
static const char *prg_name;
|
static int
|
||||||
|
vm_maim(void)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
int run;
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO) != 0)
|
||||||
|
{
|
||||||
|
fatal("SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_setup();
|
||||||
|
run = 1;
|
||||||
|
while (run)
|
||||||
|
{
|
||||||
|
while(SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
if(event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
run = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monitor_draw();
|
||||||
|
}
|
||||||
|
monitor_cleanup();
|
||||||
|
SDL_Quit();
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int retcode)
|
usage(int retcode)
|
||||||
|
@ -14,11 +40,11 @@ usage(int retcode)
|
||||||
if (retcode == EXIT_FAILURE)
|
if (retcode == EXIT_FAILURE)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Try '%s -h' for more information.\n", prg_name);
|
"Try '%s -h' for more information.\n", get_exec_name());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Usage: %s [-hV] [-b bios]\n", prg_name);
|
printf("Usage: %s [-hV] [-b bios]\n", get_exec_name());
|
||||||
printf("\t-h\tdisplay this help and exit\n");
|
printf("\t-h\tdisplay this help and exit\n");
|
||||||
printf("\t-V\toutput version information\n");
|
printf("\t-V\toutput version information\n");
|
||||||
printf("\nReport bugs to <%s>\n", PACKAGE_BUGREPORT);
|
printf("\nReport bugs to <%s>\n", PACKAGE_BUGREPORT);
|
||||||
|
@ -27,21 +53,10 @@ usage(int retcode)
|
||||||
exit(retcode);
|
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)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGEN_H
|
set_exec_name(argv[0]);
|
||||||
prg_name = basename(argv[0]);
|
|
||||||
#else
|
|
||||||
prg_name = argv[0];
|
|
||||||
#endif /* HAVE_LIBGEN_H */
|
|
||||||
|
|
||||||
while ((argc > 1) && (argv[1][0] == '-'))
|
while ((argc > 1) && (argv[1][0] == '-'))
|
||||||
{
|
{
|
||||||
|
@ -61,5 +76,6 @@ main(int argc, char **argv)
|
||||||
argv++;
|
argv++;
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
return (EXIT_SUCCESS);
|
|
||||||
|
return (vm_maim());
|
||||||
}
|
}
|
||||||
|
|
1149
vm/res/fonts.c
Normal file
1149
vm/res/fonts.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
vm/res/fonts.png
Normal file
BIN
vm/res/fonts.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
8
vm/video.h
Normal file
8
vm/video.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef VM_VIDEO_H
|
||||||
|
# define VM_VIDEO_H 1
|
||||||
|
|
||||||
|
int monitor_setup(void);
|
||||||
|
void monitor_cleanup(void);
|
||||||
|
void monitor_draw(void);
|
||||||
|
|
||||||
|
#endif /* !VM_VIDEO_H */
|
35
vm/video/memory.c
Normal file
35
vm/video/memory.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <cstring>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../bus.h"
|
||||||
|
|
||||||
|
#define VIDEO_BASE_ADDR 0xFFFB8000
|
||||||
|
|
||||||
|
static uint16_t memory[320*200];
|
||||||
|
|
||||||
|
static int
|
||||||
|
read(uint32_t addr, void *data, size_t sz)
|
||||||
|
{
|
||||||
|
addr = addr - VIDEO_BASE_ADDR;
|
||||||
|
|
||||||
|
memcpy(data, ((uint8_t *)memory) + addr, sz);
|
||||||
|
|
||||||
|
return (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write(uint32_t addr, const void *data, size_t sz)
|
||||||
|
{
|
||||||
|
addr = addr - VIDEO_BASE_ADDR;
|
||||||
|
|
||||||
|
memcpy(((uint8_t *)memory) + addr, data, sz);
|
||||||
|
|
||||||
|
return (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bus video_memory = {
|
||||||
|
"video-memory",
|
||||||
|
{VIDEO_BASE_ADDR, VIDEO_BASE_ADDR + (320 * 200 * sizeof(uint16_t))},
|
||||||
|
&read,
|
||||||
|
&write,
|
||||||
|
};
|
53
vm/video/monitor.c
Normal file
53
vm/video/monitor.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include <SDL.h>
|
||||||
|
#include "libutils/utils.h"
|
||||||
|
|
||||||
|
static SDL_Window *window = NULL;
|
||||||
|
static SDL_Renderer *renderer = NULL;
|
||||||
|
static SDL_Texture *fonts = NULL;
|
||||||
|
|
||||||
|
int
|
||||||
|
monitor_setup(void)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface;
|
||||||
|
|
||||||
|
window = SDL_CreateWindow("65∞2",
|
||||||
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
320, 200, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
fatal("SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
if (renderer == NULL)
|
||||||
|
{
|
||||||
|
fatal("SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RenderSetLogicalSize(renderer, 320, 200);
|
||||||
|
|
||||||
|
surface = SDL_LoadBMP("res/fonts.bmp");
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
fatal("SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
fonts = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
if (fonts == NULL)
|
||||||
|
{
|
||||||
|
fatal("SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
monitor_draw(void)
|
||||||
|
{
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
monitor_cleanup(void)
|
||||||
|
{
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
Loading…
Reference in a new issue