comparison src/main.c @ 8:5176efdda5ae

Initial work on VDP emulation
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Mar 2016 00:24:31 -0700
parents 7e44f7d5810b
children 04d8efe7a1f0
comparison
equal deleted inserted replaced
7:8f9a05e2e425 8:5176efdda5ae
1 #include <stdint.h> 1 #include <stdint.h>
2 #include <stdio.h> 2 #include <stdio.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <string.h> 4 #include <string.h>
5 #include "cpu.h" 5 #include "cpu.h"
6 #include "vdp.h"
6 7
7 #define CYCLES_PER_FRAME ((48000*25)/60) 8 #define CYCLES_PER_FRAME (832*262)
8 9
9 uint8_t rom[48 * 1024]; 10 uint8_t rom[48 * 1024];
10 uint8_t ram[16 * 1024]; 11 uint8_t ram[16 * 1024];
11 12
12 enum { 13 enum {
20 PORT_FREQUENCY_D, 21 PORT_FREQUENCY_D,
21 PORT_VOLUME_AB, 22 PORT_VOLUME_AB,
22 PORT_VOLUME_CD, 23 PORT_VOLUME_CD,
23 PORT_TIMER, 24 PORT_TIMER,
24 PORT_SERIAL, 25 PORT_SERIAL,
26 PORT_VERTICAL,
27 PORT_HORIZONTAL,
28 PORT_VRAM_ADDRESS,
29 PORT_VRAM_DATA
25 }; 30 };
31
32 typedef struct {
33 cpu *proc;
34 vdp video;
35 } console;
26 36
27 void debug_port_write(cpu *context, uint8_t port, uint16_t value) 37 void debug_port_write(cpu *context, uint8_t port, uint16_t value)
28 { 38 {
29 putchar(value); 39 putchar(value);
30 } 40 }
32 uint16_t debug_port_read(cpu *context, uint8_t port) 42 uint16_t debug_port_read(cpu *context, uint8_t port)
33 { 43 {
34 return getchar(); 44 return getchar();
35 } 45 }
36 46
47 void vertical_port_write(cpu *context, uint8_t port, uint16_t value)
48 {
49 console *system = context->system;
50 vdp_run(&system->video, context->cycles);
51 system->video.vscroll = value;
52 }
53
54 uint16_t vertical_port_read(cpu *context, uint8_t port)
55 {
56 console *system = context->system;
57 vdp_run(&system->video, context->cycles);
58 return system->video.vcounter;
59 }
60
61 void horizontal_port_write(cpu *context, uint8_t port, uint16_t value)
62 {
63 console *system = context->system;
64 vdp_run(&system->video, context->cycles);
65 system->video.hscroll = value;
66 }
67
68 uint16_t horizontal_port_read(cpu *context, uint8_t port)
69 {
70 console *system = context->system;
71 vdp_run(&system->video, context->cycles);
72 return system->video.hcounter;
73 }
74
75 void address_port_write(cpu *context, uint8_t port, uint16_t value)
76 {
77 console *system = context->system;
78 vdp_run(&system->video, context->cycles);
79 vdp_write_address(&system->video, value);
80 }
81
82 uint16_t address_port_read(cpu *context, uint8_t port)
83 {
84 console *system = context->system;
85 vdp_run(&system->video, context->cycles);
86 return system->video.status;
87 }
88
89 void data_port_write(cpu *context, uint8_t port, uint16_t value)
90 {
91 console *system = context->system;
92 vdp_run(&system->video, context->cycles);
93 vdp_write_data(&system->video, value);
94 }
95
37 memory_region regions[] = { 96 memory_region regions[] = {
38 {rom, 0, sizeof(rom)-1, MEM_READ}, 97 {rom, 0, sizeof(rom)-1, MEM_READ},
39 {ram, sizeof(rom), sizeof(rom)-1+sizeof(ram), MEM_READ}, 98 {ram, sizeof(rom), sizeof(rom)-1+sizeof(ram), MEM_READ},
40 }; 99 };
41 100
42 void run_console(cpu *context) 101 void run_console(console *context)
43 { 102 {
44 for(;;) 103 for(;;)
45 { 104 {
46 run_cpu(context, CYCLES_PER_FRAME); 105 run_cpu(context->proc, CYCLES_PER_FRAME);
47 context->cycles -= CYCLES_PER_FRAME; 106 vdp_run(&context->video, CYCLES_PER_FRAME);
107 context->proc->cycles -= CYCLES_PER_FRAME;
108 context->video.cycles -= CYCLES_PER_FRAME;
48 } 109 }
49 } 110 }
50 111
51 112
52 113
64 125
65 size_t read; 126 size_t read;
66 if ((read = fread(rom, 1, sizeof(rom), f)) < sizeof(rom)) { 127 if ((read = fread(rom, 1, sizeof(rom), f)) < sizeof(rom)) {
67 memset(rom + read, 0xFF, sizeof(rom)-read); 128 memset(rom + read, 0xFF, sizeof(rom)-read);
68 } 129 }
69 cpu *context = alloc_cpu(1, sizeof(regions)/sizeof(memory_region), regions); 130 console context;
70 context->port_handlers[PORT_SERIAL].write = debug_port_write; 131 context.proc = alloc_cpu(10, sizeof(regions)/sizeof(memory_region), regions);
71 context->port_handlers[PORT_SERIAL].read = debug_port_read; 132 context.proc->system = &context;
72 run_console(context); 133 vdp_init(&context.video, 2);
134 context.proc->port_handlers[PORT_SERIAL].write = debug_port_write;
135 context.proc->port_handlers[PORT_SERIAL].read = debug_port_read;
136 context.proc->port_handlers[PORT_VERTICAL].write = vertical_port_write;
137 context.proc->port_handlers[PORT_VERTICAL].read = vertical_port_read;
138 context.proc->port_handlers[PORT_HORIZONTAL].write = horizontal_port_write;
139 context.proc->port_handlers[PORT_HORIZONTAL].read = horizontal_port_read;
140 context.proc->port_handlers[PORT_VRAM_ADDRESS].write = address_port_write;
141 context.proc->port_handlers[PORT_VRAM_ADDRESS].read = address_port_read;
142 context.proc->port_handlers[PORT_VRAM_DATA].write = data_port_write;
143 run_console(&context);
73 return 0; 144 return 0;
74 } 145 }