OSDN Git Service

[VM][WIP] Use namespace to devices per VMs.
[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 namespace FMR50 {
17         
18 void TIMER::initialize()
19 {
20         free_run_counter = 0;
21         intr_reg = rtc_data = 0;
22         tmout0 = tmout1 = false;
23 }
24
25 void TIMER::write_io8(uint32_t addr, uint32_t data)
26 {
27         switch(addr) {
28         case 0x60:
29                 if(data & 0x80) {
30                         tmout0 = false;
31                 }
32                 intr_reg = data;
33                 update_intr();
34                 d_pcm->write_signal(SIG_PCM1BIT_ON, data, 4);
35                 break;
36         case 0x70:
37                 d_rtc->write_signal(SIG_MSM58321_DATA, data, 0x0f);
38                 break;
39         case 0x80:
40                 d_rtc->write_signal(SIG_MSM58321_CS, data, 0x80);
41                 d_rtc->write_signal(SIG_MSM58321_READ, data, 0x04);
42                 d_rtc->write_signal(SIG_MSM58321_WRITE, data, 0x02);
43                 d_rtc->write_signal(SIG_MSM58321_ADDR_WRITE, data, 0x01);
44                 break;
45         }
46 }
47
48 uint32_t TIMER::read_io8(uint32_t addr)
49 {
50         switch(addr) {
51         case 0x26:
52                 free_run_counter = (uint16_t)get_passed_usec(0);
53                 return free_run_counter & 0xff;
54         case 0x27:
55                 return free_run_counter >> 8;
56         case 0x60:
57                 return (tmout0 ? 1 : 0) | (tmout1 ? 2 : 0) | ((intr_reg & 7) << 2) | 0xe0;
58         case 0x70:
59                 return rtc_data;
60         }
61         return 0xff;
62 }
63
64 void TIMER::write_signal(int id, uint32_t data, uint32_t mask)
65 {
66         if(id == SIG_TIMER_CH0) {
67                 if(data & mask) {
68                         tmout0 = true;
69                 }
70                 update_intr();
71         } else if(id == SIG_TIMER_CH1) {
72                 tmout1 = ((data & mask) != 0);
73                 update_intr();
74         } else if(id == SIG_TIMER_RTC) {
75                 rtc_data = (data & mask) | (rtc_data & ~mask);
76         }
77 }
78
79 void TIMER::update_intr()
80 {
81         if((tmout0 && (intr_reg & 1)) || (tmout1 && (intr_reg & 2))) {
82                 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 1, 1);
83         } else {
84                 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 0, 1);
85         }
86 }
87
88 #define STATE_VERSION   1
89
90 bool TIMER::process_state(FILEIO* state_fio, bool loading)
91 {
92         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
93                 return false;
94         }
95         if(!state_fio->StateCheckInt32(this_device_id)) {
96                 return false;
97         }
98         state_fio->StateUint16(free_run_counter);
99         state_fio->StateUint8(intr_reg);
100         state_fio->StateUint8(rtc_data);
101         state_fio->StateBool(tmout0);
102         state_fio->StateBool(tmout1);
103         return true;
104 }
105
106 }