2 Yuasa Kyouiku System YALKY Emulator 'eYALKY'
4 Author : Takeda.Toshiya
11 #include "../datarec.h"
15 #define EVENT_COUNTER 0
20 SID <- DATA RECORDER SIGNAL (NEGATIVE, L H L H L L H H ...)
21 RST5 <- DATA RECORDER SIGNAL (POSITIVE, H L H L H H L L ...)
22 RST7 <- I8156 TIMER OUT (3MHz ???, OSC = 6MHz)
29 PA5 <- DATA RECORDER SIGNAL (0 = NO SIGNAL)
30 PA6 <- COUNTER (4520) QB2
31 PA7 <- MODEL TYPE ??? (H = PM-1001)
34 PB1 -> FONT ROM (2364) A12, FONT BANK SWITCH
37 PB4 -> COUNTER (4520) RESET B
38 PB5 -> DATA RECORDER H = FAST FORWARD or REC ???
39 PB6 -> DATA RECORDER H = PLAY, L = STOP
40 PB7 -> DATA RECORDER H = FAST REWIND
42 PC0 -> KEYBOARD COLUMN
43 PC1 -> KEYBOARD COLUMN
44 PC2 -> KEYBOARD COLUMN
51 PC2 POINT CLEAR MARK BACK SET
56 // load font rom image
57 FILEIO* fio = new FILEIO();
58 if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
59 fio->Fread(font, sizeof(font), 1);
64 key_stat = emu->get_key_buffer();
68 register_frame_event(this);
70 adjust_event_timing();
75 div_counter = counter = 0;
76 posi_counter = nega_counter = 0;
77 drec_in = drec_toggle = false;
80 void IO::adjust_event_timing()
82 if(register_id != -1) {
83 cancel_event(this, register_id);
85 double freq = d_drec->get_ave_hi_freq() * 1.4;
86 register_event(this, EVENT_COUNTER, 1000000.0 / freq, true, ®ister_id);
89 void IO::write_io8(uint32_t addr, uint32_t data)
100 d_pio->write_io8(addr, data);
105 uint32_t IO::read_io8(uint32_t addr)
107 switch(addr & 0xff) {
116 return d_pio->read_io8(addr);
121 void IO::write_signal(int id, uint32_t data, uint32_t mask)
130 if((prev & 0x10) && !(pb & 0x10)) {
131 adjust_event_timing();
135 if(!(prev & 0x80) && (pb & 0x80)) {
136 d_drec->set_ff_rew(-1);
137 } else if((prev & 0x80) && !(pb & 0x80)) {
138 d_drec->set_ff_rew(0);
140 if(!(prev & 0x40) && (pb & 0x40)) {
141 d_drec->set_remote(true);
142 } else if((prev & 0x40) && !(pb & 0x40)) {
143 d_drec->set_remote(false);
157 case SIG_IO_DREC_EAR:
159 bool prev_in = drec_in;
160 bool prev_toggle = drec_toggle;
162 drec_in = ((data & mask) != 0);
169 if(!prev_in && drec_in) {
170 if(prev_clock == 0 || get_passed_usec(prev_clock) > 1000000.0 / d_drec->get_ave_hi_freq() * 6) {
174 prev_clock = get_current_clock();
176 if(++div_counter & 1) {
177 drec_toggle = !drec_toggle;
180 if(!prev_toggle && drec_toggle) {
182 adjust_event_timing();
187 d_cpu->write_signal(SIG_I8085_SID, !drec_toggle ? 0xffffffff : 0, 1); // negative
188 d_cpu->write_signal(SIG_I8085_RST5, drec_toggle ? 0xffffffff : 0, 1); // positive
194 void IO::event_callback(int event_id, int err)
200 void IO::update_counter()
202 d_pio->write_signal(SIG_I8155_PORT_A, (counter >= 4) ? 0xffffffff : 0, 0x40);
205 void IO::event_frame()
207 if((posi_counter + nega_counter) > ((pb & 0x80) ? DATAREC_FAST_REW_SPEED : 1) * 10) {
208 int ratio = (100 * posi_counter) / (posi_counter + nega_counter);
209 posi_counter = nega_counter = 0;
210 d_pio->write_signal(SIG_I8155_PORT_A, (ratio > 40 && ratio < 60) ? 0xffffffff : 0, 0x20);
212 d_pio->write_signal(SIG_I8155_PORT_A, 0, 0x20);
217 void IO::update_key()
219 uint8_t value = 0xff;
222 if(key_stat[0x30] || key_stat[0x60]) value &= ~0x01; // 0
223 if(key_stat[0x31] || key_stat[0x61]) value &= ~0x02; // 1
224 if(key_stat[0x32] || key_stat[0x62]) value &= ~0x04; // 2
225 if(key_stat[0x33] || key_stat[0x63]) value &= ~0x08; // 3
226 if(key_stat[0x34] || key_stat[0x64]) value &= ~0x10; // 4
229 if(key_stat[0x35] || key_stat[0x65]) value &= ~0x01; // 5
230 if(key_stat[0x36] || key_stat[0x66]) value &= ~0x02; // 6
231 if(key_stat[0x37] || key_stat[0x67]) value &= ~0x04; // 7
232 if(key_stat[0x38] || key_stat[0x68]) value &= ~0x08; // 8
233 if(key_stat[0x39] || key_stat[0x69]) value &= ~0x10; // 9
236 if(key_stat[0xbe] || key_stat[0x6e]) value &= ~0x01; // DECIMAL POINT
237 if(key_stat[0x43] || key_stat[0x08]) value &= ~0x02; // CLEAR -> C or BACK SPACE
238 if(key_stat[0x4d] || key_stat[0x20]) value &= ~0x04; // MARK -> M or SPACE
239 if(key_stat[0x42] || key_stat[0x1b]) value &= ~0x08; // BACK -> B or ESC
240 if(key_stat[0x53] || key_stat[0x0d]) value &= ~0x10; // SET -> S or ENTER
242 d_pio->write_signal(SIG_I8155_PORT_A, value, 0x1f);
245 void IO::draw_screen()
247 scrntype_t cd = RGB_COLOR(0, 255, 0);
248 scrntype_t cb = RGB_COLOR(0, 0, 0);
250 for(int y = 0; y < 16; y++) {
251 for(int x = 0; x < 32; x++) {
252 uint8_t code = vram[x + y * 32];
253 // uint8_t attr = vram[x + y * 32 + 512];
255 for(int l = 0; l < 16; l++) {
256 scrntype_t* dst = emu->get_screen_buffer(y * 16 + l) + x * 8;
257 uint8_t pattern = font[(code * 16 + l) | ((pb & 2) ? 0x1000 : 0)];
259 dst[0] = (pattern & 0x80) ? cd : cb;
260 dst[1] = (pattern & 0x40) ? cd : cb;
261 dst[2] = (pattern & 0x20) ? cd : cb;
262 dst[3] = (pattern & 0x10) ? cd : cb;
263 dst[4] = (pattern & 0x08) ? cd : cb;
264 dst[5] = (pattern & 0x04) ? cd : cb;
265 dst[6] = (pattern & 0x02) ? cd : cb;
266 dst[7] = (pattern & 0x01) ? cd : cb;
272 #define STATE_VERSION 2
274 bool IO::process_state(FILEIO* state_fio, bool loading)
276 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
279 if(!state_fio->StateCheckInt32(this_device_id)) {
282 state_fio->StateValue(pb);
283 state_fio->StateValue(pc);
284 state_fio->StateValue(div_counter);
285 state_fio->StateValue(counter);
286 state_fio->StateValue(posi_counter);
287 state_fio->StateValue(nega_counter);
288 state_fio->StateValue(drec_in);
289 state_fio->StateValue(drec_toggle);
290 state_fio->StateValue(prev_clock);
291 state_fio->StateValue(register_id);