Mercurial > repos > simple16
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 } |