OSDN Git Service

[UI][Qt] Add YALKY, PC-2000, SMC-70.
[csp-qt/common_source_project-fm7.git] / source / src / vm / yalky / io.cpp
1 /*
2         Yuasa Kyouiku System YALKY Emulator 'eYALKY'
3
4         Author : Takeda.Toshiya
5         Date   : 2016.03.28-
6
7         [ i/o ]
8 */
9
10 #include "io.h"
11 #include "../i8155.h"
12
13 void IO::initialize()
14 {
15         // load font rom image
16         FILEIO* fio = new FILEIO();
17         if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
18                 fio->Fread(font, sizeof(font), 1);
19                 fio->Fclose();
20         }
21         delete fio;
22         
23         key_stat = emu->get_key_buffer();
24         pb = pc = 0xff;
25         counter = 0;
26         register_frame_event(this);
27 }
28
29 /*
30 PA0 <- KEYBOARD DATA
31 PA1 <- KEYBOARD DATA
32 PA2 <- KEYBOARD DATA
33 PA3 <- KEYBOARD DATA
34 PA4 <- KEYBOARD DATA
35 PA5 <- DATA RECORDER
36 PA6 <- 4520 QB2
37 PA7 <- +5V
38
39 PB0 -> 7948 Pin #6
40 PB1 -> FONT ROM (2364) A12
41 PB2 -> 7945 Pin #1
42 PB3 -> LED
43 PB4 -> 4520 ENABLE B
44 PB5 -> DATA RECORDER
45 PB6 -> DATA RECORDER
46 PB7 -> DATA RECORDER
47
48 PC0 -> KEYBOARD COLUMN
49 PC1 -> KEYBOARD COLUMN
50 PC2 -> KEYBOARD COLUMN
51 PC3
52 PC4
53
54         PA0     PA1     PA2     PA3     PA4
55 PC0     0       1       2       3       4
56 PC1     5       6       7       8       9
57 PC2     POINT   CLEAR   MARK    BACK    SET
58 */
59
60 void IO::write_io8(uint32_t addr, uint32_t data)
61 {
62         switch(addr & 0xff) {
63         case 0x00:
64         case 0x01:
65         case 0x02:
66         case 0x03:
67         case 0x04:
68         case 0x05:
69         case 0x06:
70         case 0x07:
71                 d_pio->write_io8(addr, data);
72                 break;
73         }
74 }
75
76 uint32_t IO::read_io8(uint32_t addr)
77 {
78         switch(addr & 0xff) {
79         case 0x00:
80         case 0x01:
81         case 0x02:
82         case 0x03:
83         case 0x04:
84         case 0x05:
85         case 0x06:
86         case 0x07:
87                 return d_pio->read_io8(addr);
88         }
89         return 0xff;
90 }
91
92 void IO::write_signal(int id, uint32_t data, uint32_t mask)
93 {
94         switch(id) {
95         case SIG_IO_PORT_B:
96                 pb &= ~mask;
97                 pb |= data & mask;
98                 break;
99                 
100         case SIG_IO_PORT_C:
101                 pc &= ~mask;
102                 pc |= data & mask;
103                 update_key();
104                 break;
105                 
106         case SIG_IO_DREC_ROT:
107                 d_pio->write_signal(SIG_I8155_PORT_A, !(data & mask) ? 0xffffffff : 0, 0x20);
108                 break;
109         }
110 }
111
112 void IO::event_frame()
113 {
114 //      if(!(pb & 0x10)) {
115                 counter++;
116 //      }
117         d_pio->write_signal(SIG_I8155_PORT_A, (counter & 4) ? 0xffffffff : 0, 0x40);
118         update_key();
119 }
120
121 void IO::update_key()
122 {
123         uint8_t value = 0xff;
124         
125         if(!(pc & 0x01)) {
126                 if(key_stat[0x30] || key_stat[0x60]) value &= ~0x01;    // 0
127                 if(key_stat[0x31] || key_stat[0x61]) value &= ~0x02;    // 1
128                 if(key_stat[0x32] || key_stat[0x62]) value &= ~0x04;    // 2
129                 if(key_stat[0x33] || key_stat[0x63]) value &= ~0x08;    // 3
130                 if(key_stat[0x34] || key_stat[0x64]) value &= ~0x10;    // 4
131         }
132         if(!(pc & 0x02)) {
133                 if(key_stat[0x35] || key_stat[0x65]) value &= ~0x01;    // 5
134                 if(key_stat[0x36] || key_stat[0x66]) value &= ~0x02;    // 6
135                 if(key_stat[0x37] || key_stat[0x67]) value &= ~0x04;    // 7
136                 if(key_stat[0x38] || key_stat[0x68]) value &= ~0x08;    // 8
137                 if(key_stat[0x39] || key_stat[0x69]) value &= ~0x10;    // 9
138         }
139         if(!(pc & 0x04)) {
140                 if(key_stat[0xbe] || key_stat[0x6e]) value &= ~0x01;    // DECIMAL POINT
141                 if(key_stat[0x43] || key_stat[0x1b]) value &= ~0x02;    // CLEAR -> C or ESC
142                 if(key_stat[0x4d] || key_stat[0x20]) value &= ~0x04;    // MARK  -> M or SPACE
143                 if(key_stat[0x42] || key_stat[0x08]) value &= ~0x08;    // BACK  -> B or BACK SPACE
144                 if(key_stat[0x53] || key_stat[0x0d]) value &= ~0x10;    // SET   -> S or ENTER
145         }
146         d_pio->write_signal(SIG_I8155_PORT_A, value, 0x1f);
147 }
148
149 void IO::draw_screen()
150 {
151         scrntype_t cd = RGB_COLOR(0, 255, 0);
152         scrntype_t cb = RGB_COLOR(0, 0, 0);
153         
154         for(int y = 0; y < 16; y++) {
155                 for(int x = 0; x < 32; x++) {
156                         uint8_t code = vram[x + y * 32];
157                         uint8_t attr = vram[x + y * 32 + 512];
158                         
159                         for(int l = 0; l < 16; l++) {
160                                 scrntype_t* dst = emu->get_screen_buffer(y * 16 + l) + x * 8;
161                                 uint8_t pattern = font[code * 16 + l];
162                                 
163                                 dst[0] = (pattern & 0x80) ? cd : cb;
164                                 dst[1] = (pattern & 0x40) ? cd : cb;
165                                 dst[2] = (pattern & 0x20) ? cd : cb;
166                                 dst[3] = (pattern & 0x10) ? cd : cb;
167                                 dst[4] = (pattern & 0x08) ? cd : cb;
168                                 dst[5] = (pattern & 0x04) ? cd : cb;
169                                 dst[6] = (pattern & 0x02) ? cd : cb;
170                                 dst[7] = (pattern & 0x01) ? cd : cb;
171                         }
172                 }
173         }
174 }
175
176 #define STATE_VERSION   1
177
178 void IO::save_state(FILEIO* state_fio)
179 {
180         state_fio->FputUint32(STATE_VERSION);
181         state_fio->FputInt32(this_device_id);
182         
183         state_fio->FputUint8(pb);
184         state_fio->FputUint8(pc);
185         state_fio->FputUint8(counter);
186 }
187
188 bool IO::load_state(FILEIO* state_fio)
189 {
190         if(state_fio->FgetUint32() != STATE_VERSION) {
191                 return false;
192         }
193         if(state_fio->FgetInt32() != this_device_id) {
194                 return false;
195         }
196         pb = state_fio->FgetUint8();
197         pc = state_fio->FgetUint8();
198         counter = state_fio->FgetUint8();
199         return true;
200 }
201