main blastcpm.c
  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <stddef.h>
  4#include <string.h>
  5#include <time.h>
  6#include <sys/select.h>
  7
  8#include "z80_to_x86.h"
  9#include "util.h"
 10
 11uint8_t ram[64 * 1024];
 12
 13#define START_OFF 0x100
 14#define OS_START 0xE400
 15#define OS_RESET 0xE403
 16int headless = 1;
 17
 18void z80_next_int_pulse(z80_context * context)
 19{
 20	context->int_pulse_start = context->int_pulse_end = CYCLE_NEVER;
 21}
 22
 23void render_errorbox(char *title, char *message)
 24{
 25}
 26
 27void render_infobox(char *title, char *message)
 28{
 29}
 30
 31void *console_write(uint32_t address, void *context, uint8_t value)
 32{
 33	putchar(value);
 34	return context;
 35}
 36
 37uint8_t console_read(uint32_t address, void *context)
 38{
 39	return getchar();
 40}
 41
 42void *console_flush_write(uint32_t address, void *context, uint8_t value)
 43{
 44	fflush(stdout);
 45	return context;
 46}
 47
 48uint8_t console_status_read(uint32_t address, void *context)
 49{
 50	fd_set read_fds;
 51	FD_ZERO(&read_fds);
 52	struct timeval timeout;
 53	timeout.tv_sec = 0;
 54	timeout.tv_usec = 0;
 55	FD_SET(fileno(stdin), &read_fds);
 56	return select(fileno(stdin)+1, &read_fds, NULL, NULL, &timeout) > 0; 
 57}
 58
 59time_t start;
 60uint64_t total_cycles;
 61void *exit_write(uint32_t address, void *context, uint8_t value)
 62{
 63	time_t duration = time(NULL) - start;
 64	z80_context *z80 = context;
 65	total_cycles += context->current_cycle;
 66	printf("Effective clock speed: %f MHz\n", ((double)total_cycles) / (1000000.0 * duration));
 67	exit(0);
 68	return context;
 69}
 70
 71const memmap_chunk z80_map[] = {
 72	{ 0x0000, 0x10000,  0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, NULL, NULL, NULL, NULL},
 73};
 74
 75memmap_chunk io_map[] = {
 76	{ 0x0, 0x1, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, console_read, console_write},
 77	{ 0x1, 0x2, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, console_status_read, console_flush_write},
 78	{ 0x2, 0x3, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, exit_write},
 79};
 80
 81int main(int argc, char **argv)
 82{
 83	FILE *f = fopen("fake_cpm.bin", "rb");
 84	long fsize = file_size(f);
 85	if (fsize > sizeof(ram) - OS_START) {
 86		fsize = sizeof(ram) - OS_START;
 87	}
 88	if (fread(ram + OS_START, 1, fsize, f) != fsize) {
 89		fprintf(stderr, "Error reading from fake_cpm.bin\n");
 90		exit(1);
 91	}
 92	f = fopen(argv[1], "rb");
 93	fsize = file_size(f);
 94	if (fsize > OS_START - START_OFF) {
 95		fsize = OS_START - START_OFF;
 96	}
 97	if (fread(ram + START_OFF, 1, fsize, f) != fsize) {
 98		fprintf(stderr, "Error reading from file %s\n", argv[1]);
 99		exit(1);
100	}
101	fclose(f);
102	ram[0] = 0xC3;
103	ram[1] = OS_RESET & 0xFF;
104	ram[2] = OS_RESET >> 8;
105	ram[5] = 0xC3;
106	ram[6] = OS_START & 0xFF;
107	ram[7] = OS_START >> 8;
108	
109	z80_options opts;
110	z80_context *context;
111	init_z80_opts(&opts, z80_map, 1, io_map, 3, 1, 0xFF);
112	context = init_z80_context(&opts);
113	start = time(NULL);
114	for(;;)
115	{
116		z80_run(context, 1000000);
117		total_cycles += context->current_cycle;
118		context->current_cycle = 0;
119		
120	}
121	return 0;
122}