Subversion Repositories Shiroi

Rev

Rev 21 | Rev 32 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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