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}