comparison blastcpm.c @ 820:cf6149b7c6e5

Implement a tiny bit of CPM BDOS and add a corresponding Z80 core driver so that simple CPM programs like ZEXDOC/ZEXALL can be run against my Z80 core
author Michael Pavone <pavone@retrodev.com>
date Wed, 29 Jul 2015 00:05:21 -0700
parents
children fe8c79f82c22
comparison
equal deleted inserted replaced
819:ab017fb09e77 820:cf6149b7c6e5
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include <sys/select.h>
6
7 #include "z80_to_x86.h"
8 #include "util.h"
9
10 uint8_t ram[64 * 1024];
11
12 #define START_OFF 0x100
13 #define OS_START 0xE400
14 #define OS_RESET 0xE403
15 int headless = 1;
16
17 void z80_next_int_pulse(z80_context * context)
18 {
19 context->int_pulse_start = context->int_pulse_end = CYCLE_NEVER;
20 }
21
22 void render_errorbox(char *title, char *message)
23 {
24 }
25
26 void render_infobox(char *title, char *message)
27 {
28 }
29
30 void *console_write(uint32_t address, void *context, uint8_t value)
31 {
32 putchar(value);
33 return context;
34 }
35
36 uint8_t console_read(uint32_t address, void *context)
37 {
38 return getchar();
39 }
40
41 void *console_flush_write(uint32_t address, void *context, uint8_t value)
42 {
43 fflush(stdout);
44 return context;
45 }
46
47 uint8_t console_status_read(uint32_t address, void *context)
48 {
49 fd_set read_fds;
50 FD_ZERO(&read_fds);
51 struct timeval timeout;
52 timeout.tv_sec = 0;
53 timeout.tv_usec = 0;
54 FD_SET(fileno(stdin), &read_fds);
55 return select(fileno(stdin)+1, &read_fds, NULL, NULL, &timeout) > 0;
56 }
57
58 void *exit_write(uint32_t address, void *context, uint8_t value)
59 {
60 exit(0);
61 return context;
62 }
63
64 const memmap_chunk z80_map[] = {
65 { 0x0000, 0x10000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, NULL, NULL, NULL, NULL},
66 };
67
68 const memmap_chunk io_map[] = {
69 { 0x0, 0x1, 0xFFFF, 0, 0, NULL, NULL, NULL, console_read, console_write},
70 { 0x1, 0x2, 0xFFFF, 0, 0, NULL, NULL, NULL, console_status_read, console_flush_write},
71 { 0x2, 0x3, 0xFFFF, 0, 0, NULL, NULL, NULL, NULL, exit_write},
72 };
73
74 int main(int argc, char **argv)
75 {
76 FILE *f = fopen("fake_cpm.bin", "rb");
77 long fsize = file_size(f);
78 if (fsize > sizeof(ram) - OS_START) {
79 fsize = sizeof(ram) - OS_START;
80 }
81 if (fread(ram + OS_START, 1, fsize, f) != fsize) {
82 fprintf(stderr, "Error reading from fake_cpm.bin\n");
83 exit(1);
84 }
85 f = fopen(argv[1], "rb");
86 fsize = file_size(f);
87 if (fsize > OS_START - START_OFF) {
88 fsize = OS_START - START_OFF;
89 }
90 if (fread(ram + START_OFF, 1, fsize, f) != fsize) {
91 fprintf(stderr, "Error reading from file %s\n", argv[1]);
92 exit(1);
93 }
94 fclose(f);
95 ram[0] = 0xC3;
96 ram[1] = OS_RESET & 0xFF;
97 ram[2] = OS_RESET >> 8;
98 ram[5] = 0xC3;
99 ram[6] = OS_START & 0xFF;
100 ram[7] = OS_START >> 8;
101
102 z80_options opts;
103 z80_context context;
104 init_z80_opts(&opts, z80_map, 1, io_map, 3, 1);
105 init_z80_context(&context, &opts);
106 for(;;)
107 {
108 z80_run(&context, 1000000);
109 context.current_cycle = 0;
110 }
111 return 0;
112 }