OSDN Git Service

3a16cb7b2cf91c258743b72ae9fc27329d1200ce
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm16pi / sub.cpp
1 /*
2         FUJITSU FM16pi Emulator 'eFM16pi'
3
4         Author : Takeda.Toshiya
5         Date   : 2010.12.25-
6
7         [ sub system ]
8 */
9
10 #include "sub.h"
11 #include "../../fifo.h"
12 #include "../i8255.h"
13 #include "../i8259.h"
14 #include "../mb8877.h"
15 #include "../msm58321.h"
16 #include "../pcm1bit.h"
17
18 #define EVENT_KEYSCAN   0
19
20 static const int key_table[256] = {
21         // EXT -> END, GRAPH -> ALT
22           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,0x0E,0x0F,  -1,  -1,  -1,0x1C,  -1,  -1,
23         0x37,0x36,0x3C,0x3E,0x39,0x3D,  -1,  -1,  -1,  -1,  -1,0x01,0x3B,0x3A,  -1,  -1,
24         0x34,  -1,  -1,0x44,0x47,0x48,0x49,0x4B,0x4A,  -1,  -1,  -1,  -1,0x45,0x46,  -1,
25         0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,  -1,  -1,  -1,  -1,  -1,  -1,
26           -1,0x1D,0x2D,0x2B,0x1F,0x12,0x20,0x21,0x22,0x17,0x23,0x24,0x25,0x2F,0x2E,0x18,
27         0x19,0x10,0x13,0x1E,0x14,0x16,0x2C,0x11,0x2A,0x15,0x29,  -1,  -1,  -1,  -1,  -1,
28         0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,  -1,  -1,  -1,  -1,0x31,  -1,
29         0x3F,0x40,0x41,0x42,0x43,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
30           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
31           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
32           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
33           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,0x27,0x26,0x30,0x0C,0x31,0x32,
34         0x1A,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
35           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,0x1B,0x35,0x28,0x0D,  -1,
36           -1,  -1,0x33,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
37           -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
38 };
39
40 void SUB::initialize()
41 {
42         key_buffer = new FIFO(16);
43         
44         // key scan (15ms)
45         register_event(this, EVENT_KEYSCAN, 15000, true, NULL);
46 }
47
48 void SUB::release()
49 {
50         key_buffer->release();
51         delete key_buffer;
52 }
53
54 void SUB::reset()
55 {
56         key_buffer->clear();
57         key_buffer->write(0xf0);        // self check result
58         key_data = 0xf0;
59         key_irq = false;
60         fdc_drive = fdc_side = 0;       // 0xff ???
61         rtc_data = 0;
62 }
63
64 void SUB::write_io8(uint32 addr, uint32 data)
65 {
66         switch(addr) {
67         case 0x40:
68                 d_rtc->write_signal(SIG_MSM58321_CS, data, 0x10);
69                 d_rtc->write_signal(SIG_MSM58321_ADDR_WRITE, data, 0x20);       // prev data is written
70                 d_rtc->write_signal(SIG_MSM58321_DATA, data, 0x0f);
71                 d_rtc->write_signal(SIG_MSM58321_READ, data, 0x40);
72                 d_rtc->write_signal(SIG_MSM58321_WRITE, data, 0x80);            // current data is written
73                 break;
74         case 0xa0:
75                 if(!(data & 8)) {
76                         d_pic->write_signal(SIG_I8259_IR6, 0, 0);       // printer ack
77                 }
78                 if(!(data & 0x10)) {
79                         d_pic->write_signal(SIG_I8259_IR0, 0, 0);       // interval timer
80                         d_pio->write_signal(SIG_I8255_PORT_B, 0x20, 0x20);
81                 }
82                 if(data & 0x20) {
83                         // power off
84                         emu->power_off();
85                 }
86                 d_pcm->write_signal(SIG_PCM1BIT_ON, data, 0x40);
87                 rtc_data |= data & 0x80;
88                 break;
89         case 0xc8:
90                 d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 1);
91                 fdc_side = data;
92                 break;
93         case 0xca:
94                 d_fdc->write_signal(SIG_MB8877_DRIVEREG, data, 3);
95                 // bit6: drive disable (1=disable)
96                 d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x80);
97                 fdc_drive = data;
98                 break;
99         }
100 }
101
102 uint32 SUB::read_io8(uint32 addr)
103 {
104         switch(addr) {
105         case 0x40:
106                 return rtc_data;
107         case 0x60:
108                 if(key_irq) {
109                         d_pic->write_signal(SIG_I8259_IR4, 0, 0);
110                         d_pio->write_signal(SIG_I8255_PORT_C, 8, 8);
111                         key_irq = false;
112                 }
113                 return key_data;
114         case 0xc8:
115                 return fdc_side;
116         case 0xca:
117                 return fdc_drive;
118         }
119         return 0xff;
120 }
121
122 void SUB::write_signal(int id, uint32 data, uint32 mask)
123 {
124         if(id == SIG_SUB_RTC) {
125                 // bit0-3: rtc data
126                 // bit4:   rtc busy
127                 rtc_data = (rtc_data & ~mask) | (data & mask);
128         }
129 }
130
131 void SUB::event_callback(int event_id, int err)
132 {
133         if(!key_buffer->empty() && !key_irq) {
134                 d_pic->write_signal(SIG_I8259_IR4, 1, 1);
135                 d_pio->write_signal(SIG_I8255_PORT_C, 0, 8);
136                 key_irq = true;
137                 key_data = key_buffer->read();
138         }
139 }
140
141 void SUB::key_down(int code)
142 {
143         if((code = key_table[code]) != -1) {
144                 key_buffer->write(code);
145         }
146 }
147
148 void SUB::key_up(int code)
149 {
150         if((code = key_table[code]) != -1) {
151                 key_buffer->write(code | 0x80);
152         }
153 }
154
155 void SUB::notify_power_off()
156 {
157         if(rtc_data & 0x80) {
158                 d_cpu->write_signal(SIG_CPU_NMI, 1, 1);
159         }
160 }
161
162 void SUB::draw_screen()
163 {
164         // 640x200, msb->lsb
165         scrntype cd = RGB_COLOR(48, 56, 16);
166         scrntype cb = RGB_COLOR(160, 168, 160);
167         
168         for(int y = 0, ptr = 0; y < 200; y++) {
169                 scrntype *dest = emu->screen_buffer(y);
170                 for(int x = 0; x < 640; x += 8) {
171                         uint8 pat = vram[ptr++];
172                         dest[0] = (pat & 0x80) ? cd : cb;
173                         dest[1] = (pat & 0x40) ? cd : cb;
174                         dest[2] = (pat & 0x20) ? cd : cb;
175                         dest[3] = (pat & 0x10) ? cd : cb;
176                         dest[4] = (pat & 0x08) ? cd : cb;
177                         dest[5] = (pat & 0x04) ? cd : cb;
178                         dest[6] = (pat & 0x02) ? cd : cb;
179                         dest[7] = (pat & 0x01) ? cd : cb;
180                         dest += 8;
181                 }
182         }
183 }
184