OSDN Git Service

[General][Qt] Merge upstream 2015-03-28.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr50 / timer.cpp
1 /*
2         FUJITSU FMR-50 Emulator 'eFMR-50'
3         FUJITSU FMR-60 Emulator 'eFMR-60'
4
5         Author : Takeda.Toshiya
6         Date   : 2008.04.30 -
7
8         [ timer ]
9 */
10
11 #include "timer.h"
12 #include "../i8259.h"
13 #include "../msm58321.h"
14 #include "../pcm1bit.h"
15
16 void TIMER::initialize()
17 {
18         free_run_counter = 0;
19         intr_reg = rtc_data = 0;
20         tmout0 = tmout1 = false;
21 }
22
23 void TIMER::write_io8(uint32 addr, uint32 data)
24 {
25         switch(addr) {
26         case 0x60:
27                 if(data & 0x80) {
28                         tmout0 = false;
29                 }
30                 intr_reg = data;
31                 update_intr();
32                 d_pcm->write_signal(SIG_PCM1BIT_ON, data, 4);
33                 break;
34         case 0x70:
35                 d_rtc->write_signal(SIG_MSM58321_DATA, data, 0x0f);
36                 break;
37         case 0x80:
38                 d_rtc->write_signal(SIG_MSM58321_CS, data, 0x80);
39                 d_rtc->write_signal(SIG_MSM58321_READ, data, 0x04);
40                 d_rtc->write_signal(SIG_MSM58321_WRITE, data, 0x02);
41                 d_rtc->write_signal(SIG_MSM58321_ADDR_WRITE, data, 0x01);
42                 break;
43         }
44 }
45
46 uint32 TIMER::read_io8(uint32 addr)
47 {
48         switch(addr) {
49         case 0x26:
50                 free_run_counter = (uint16)passed_usec(0);
51                 return free_run_counter & 0xff;
52         case 0x27:
53                 return free_run_counter >> 8;
54         case 0x60:
55                 return (tmout0 ? 1 : 0) | (tmout1 ? 2 : 0) | ((intr_reg & 7) << 2) | 0xe0;
56         case 0x70:
57                 return rtc_data;
58         }
59         return 0xff;
60 }
61
62 void TIMER::write_signal(int id, uint32 data, uint32 mask)
63 {
64         if(id == SIG_TIMER_CH0) {
65                 if(data & mask) {
66                         tmout0 = true;
67                 }
68                 update_intr();
69         } else if(id == SIG_TIMER_CH1) {
70                 tmout1 = ((data & mask) != 0);
71                 update_intr();
72         } else if(id == SIG_TIMER_RTC) {
73                 rtc_data = (data & mask) | (rtc_data & ~mask);
74         }
75 }
76
77 void TIMER::update_intr()
78 {
79         if((tmout0 && (intr_reg & 1)) || (tmout1 && (intr_reg & 2))) {
80                 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 1, 1);
81         } else {
82                 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 0, 1);
83         }
84 }
85
86 #define STATE_VERSION   1
87
88 void TIMER::save_state(FILEIO* state_fio)
89 {
90         state_fio->FputUint32(STATE_VERSION);
91         state_fio->FputInt32(this_device_id);
92         
93         state_fio->FputUint16(free_run_counter);
94         state_fio->FputUint8(intr_reg);
95         state_fio->FputUint8(rtc_data);
96         state_fio->FputBool(tmout0);
97         state_fio->FputBool(tmout1);
98 }
99
100 bool TIMER::load_state(FILEIO* state_fio)
101 {
102         if(state_fio->FgetUint32() != STATE_VERSION) {
103                 return false;
104         }
105         if(state_fio->FgetInt32() != this_device_id) {
106                 return false;
107         }
108         free_run_counter = state_fio->FgetUint16();
109         intr_reg = state_fio->FgetUint8();
110         rtc_data = state_fio->FgetUint8();
111         tmout0 = state_fio->FgetBool();
112         tmout1 = state_fio->FgetBool();
113         return true;
114 }
115