Subversion Repositories Shiroi

Rev

Rev 32 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: shiroi.c 34 2024-09-01 10:13:47Z nishi $ */
2
 
3
#include "shiroi.h"
4
 
5
#include "card/shiroi_video_mk_i.h"
7 nishi 6
#include "card/shiroi_video_mk_ii.h"
1 nishi 7
#include "card/shiroi_sound_mk_i.h"
8
#include "card/shiroi_math_mk_i.h"
3 nishi 9
#include "card/shiroi_text_mk_i.h"
12 nishi 10
#include "card/shiroi_debug.h"
34 nishi 11
#include "card/shiroi_romcard_mk_i.h"
1 nishi 12
 
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <math.h>
12 nishi 16
#include <time.h>
1 nishi 17
 
18
float audio[480];
19
int16_t incre = 0;
20
 
21
void shiroi_play_audio(void* buffer, unsigned int frames) {
22
	int16_t* d = (int16_t*)buffer;
23
	int i;
24
	for(i = 0; i < frames; i++) {
25
		d[i] = audio[(i + incre >= 480) ? (i + incre - 480) : (i + incre)] * 32767;
26
	}
27
}
28
 
29
shiroi_card_t* shiroi_get_video_card(shiroi_t* shiroi) {
30
	int i;
31
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
32
		if(shiroi->cards[i].type == 0) continue;
33
		if((shiroi->cards[i].type & 0xf0) == SHIROI_VIDEO) return &shiroi->cards[i];
34
	}
35
	return NULL;
36
}
37
 
38
shiroi_card_t* shiroi_get_sound_card(shiroi_t* shiroi) {
39
	int i;
40
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
41
		if(shiroi->cards[i].type == 0) continue;
42
		if((shiroi->cards[i].type & 0xf0) == SHIROI_SOUND) return &shiroi->cards[i];
43
	}
44
	return NULL;
45
}
46
 
47
shiroi_card_t* shiroi_get_math_card(shiroi_t* shiroi) {
48
	int i;
49
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
50
		if(shiroi->cards[i].type == 0) continue;
3 nishi 51
		if(shiroi->cards[i].type == SHIROI_MATH_MARK_I) return &shiroi->cards[i];
1 nishi 52
	}
53
	return NULL;
54
}
55
 
3 nishi 56
shiroi_card_t* shiroi_get_text_card(shiroi_t* shiroi) {
57
	int i;
58
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
59
		if(shiroi->cards[i].type == 0) continue;
60
		if(shiroi->cards[i].type == SHIROI_TEXT_MARK_I) return &shiroi->cards[i];
61
	}
62
	return NULL;
63
}
64
 
12 nishi 65
shiroi_card_t* shiroi_get_debug_card(shiroi_t* shiroi) {
66
	int i;
67
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
68
		if(shiroi->cards[i].type == 0) continue;
69
		if(shiroi->cards[i].type == SHIROI_DEBUG) return &shiroi->cards[i];
70
	}
71
	return NULL;
72
}
73
 
34 nishi 74
shiroi_card_t* shiroi_get_romcard_card(shiroi_t* shiroi) {
75
	int i;
76
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
77
		if(shiroi->cards[i].type == 0) continue;
78
		if(shiroi->cards[i].type == SHIROI_ROMCARD_MARK_I) return &shiroi->cards[i];
79
	}
80
	return NULL;
81
}
82
 
1 nishi 83
void shiroi_init_cards(shiroi_t* shiroi) {
84
	int i;
85
	for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
86
		shiroi->cards[i].type = 0;
87
	}
88
}
89
 
90
void shiroi_install(shiroi_t* shiroi, int slot, int card) {
91
	if(card == SHIROI_VIDEO_MARK_I) {
92
		shiroi_video_mk_i_install(shiroi, slot);
7 nishi 93
	} else if(card == SHIROI_VIDEO_MARK_II) {
94
		shiroi_video_mk_ii_install(shiroi, slot);
1 nishi 95
	} else if(card == SHIROI_SOUND_MARK_I) {
96
		shiroi_sound_mk_i_install(shiroi, slot);
97
	} else if(card == SHIROI_MATH_MARK_I) {
98
		shiroi_math_mk_i_install(shiroi, slot);
3 nishi 99
	} else if(card == SHIROI_TEXT_MARK_I) {
100
		shiroi_text_mk_i_install(shiroi, slot);
12 nishi 101
	} else if(card == SHIROI_DEBUG) {
102
		shiroi_debug_install(shiroi, slot);
34 nishi 103
	} else if(card == SHIROI_ROMCARD_MARK_I) {
104
		shiroi_romcard_mk_i_install(shiroi, slot);
1 nishi 105
	}
106
}
107
 
10 nishi 108
void shiroi_reset_card(shiroi_t* shiroi, int slot) {
109
	int card = shiroi->cards[slot].type;
110
	if(card == 0) {
111
	} else if(card == SHIROI_VIDEO_MARK_I) {
112
		shiroi_video_mk_i_reset(shiroi, slot);
113
	} else if(card == SHIROI_VIDEO_MARK_II) {
114
		shiroi_video_mk_ii_reset(shiroi, slot);
115
	} else if(card == SHIROI_SOUND_MARK_I) {
116
		shiroi_sound_mk_i_reset(shiroi, slot);
117
	} else if(card == SHIROI_MATH_MARK_I) {
118
		shiroi_math_mk_i_reset(shiroi, slot);
119
	} else if(card == SHIROI_TEXT_MARK_I) {
120
		shiroi_text_mk_i_reset(shiroi, slot);
12 nishi 121
	} else if(card == SHIROI_DEBUG) {
122
		shiroi_debug_reset(shiroi, slot);
34 nishi 123
	} else if(card == SHIROI_ROMCARD_MARK_I) {
124
		shiroi_romcard_mk_i_reset(shiroi, slot);
10 nishi 125
	}
126
}
127
 
1 nishi 128
void shiroi_init(shiroi_t* shiroi) {
129
	shiroi->z80_pins = z80_init(&shiroi->z80);
130
	shiroi->stop = false;
10 nishi 131
	shiroi->reset = false;
1 nishi 132
	shiroi->play_audio = shiroi_play_audio;
133
 
134
	int i;
135
 
136
	for(i = 0; i < 480; i++) {
137
		audio[i] = 0;
138
	}
139
}
140
 
141
void shiroi_loop(shiroi_t* shiroi) {
142
	int x = 0;
143
	int y = 0;
12 nishi 144
#ifdef ACCURATE_CLOCK
19 nishi 145
	double hz = 1000000000.0 / (20 * 1024 * 1024);
12 nishi 146
	struct timespec deadline;
147
#endif
11 nishi 148
	while(!shiroi->stop || shiroi->reset) {
10 nishi 149
		if(shiroi->reset) {
150
			z80_reset(&shiroi->z80);
151
			int i;
152
			for(i = 0; i < 256 / SHIROI_IO_PORTS; i++) {
153
				shiroi_reset_card(shiroi, i);
154
			}
155
			shiroi->reset = false;
11 nishi 156
			incre = 0;
157
			for(i = 0; i < 480; i++) audio[i] = 0;
158
			continue;
10 nishi 159
		}
12 nishi 160
#ifdef ACCURATE_CLOCK
161
		clock_gettime(CLOCK_MONOTONIC, &deadline);
162
		deadline.tv_nsec += hz;
163
		if(deadline.tv_nsec >= 1000000000) {
164
			deadline.tv_nsec -= 1000000000;
165
			deadline.tv_sec++;
166
		}
167
#endif
1 nishi 168
		shiroi->z80_pins = z80_tick(&shiroi->z80, shiroi->z80_pins);
169
		if(shiroi->z80_pins & Z80_MREQ) {
170
			uint16_t addr = Z80_GET_ADDR(shiroi->z80_pins);
171
			if(shiroi->z80_pins & Z80_RD) {
172
				uint8_t data = shiroi->ram[addr];
173
				Z80_SET_DATA(shiroi->z80_pins, data);
174
			} else if(shiroi->z80_pins & Z80_WR) {
3 nishi 175
				if(addr >= 0x8000) {
176
					uint8_t data = Z80_GET_DATA(shiroi->z80_pins);
177
					shiroi->ram[addr] = data;
32 nishi 178
				} else {
22 nishi 179
					fprintf(stderr, "Illegal write at 0x%X\n", addr);
3 nishi 180
				}
1 nishi 181
			}
182
		} else if(shiroi->z80_pins & Z80_IORQ) {
183
			uint16_t io = Z80_GET_ADDR(shiroi->z80_pins);
184
			uint16_t addr = io & 0xff;
185
			uint16_t data = (io >> 8) & 0xff;
186
 
187
			if(shiroi->z80_pins & Z80_M1) {
188
			} else {
22 nishi 189
				Z80_SET_DATA(shiroi->z80_pins, 0);
1 nishi 190
				shiroi_video_mk_i(shiroi);
7 nishi 191
				shiroi_video_mk_ii(shiroi);
1 nishi 192
				shiroi_sound_mk_i(shiroi);
193
				shiroi_math_mk_i(shiroi);
3 nishi 194
				shiroi_text_mk_i(shiroi);
12 nishi 195
				shiroi_debug(shiroi);
34 nishi 196
				shiroi_romcard_mk_i(shiroi);
1 nishi 197
			}
198
		}
199
 
200
		shiroi_video_mk_i_tick(shiroi);
7 nishi 201
		shiroi_video_mk_ii_tick(shiroi);
1 nishi 202
		shiroi_sound_mk_i_tick(shiroi);
203
		shiroi_math_mk_i_tick(shiroi);
3 nishi 204
		shiroi_text_mk_i_tick(shiroi);
12 nishi 205
		shiroi_debug_tick(shiroi);
34 nishi 206
		shiroi_romcard_mk_i_tick(shiroi);
12 nishi 207
#ifdef ACCURATE_CLOCK
208
		clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
209
#endif
1 nishi 210
	}
211
}