~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mame/machine/pcshare.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    machine/pcshare.c
4
 
 
5
 
    Functions to emulate general aspects of the machine
6
 
    (RAM, ROM, interrupts, I/O ports)
7
 
 
8
 
    The information herein is heavily based on
9
 
    'Ralph Browns Interrupt List'
10
 
    Release 52, Last Change 20oct96
11
 
 
12
 
    TODO:
13
 
    clean up (maybe split) the different pieces of hardware
14
 
    PIC, PIT, DMA... add support for LPT, COM (almost done)
15
 
    emulation of a serial mouse on a COM port (almost done)
16
 
    support for Game Controller port at 0x0201
17
 
    support for XT harddisk (under the way, see machine/pc_hdc.c)
18
 
    whatever 'hardware' comes to mind,
19
 
    maybe SoundBlaster? EGA? VGA?
20
 
 
21
 
***************************************************************************/
22
 
 
23
 
#include "emu.h"
24
 
#include "machine/pcshare.h"
25
 
#include "machine/pckeybrd.h"
26
 
#include "machine/8237dma.h"
27
 
#include "machine/pic8259.h"
28
 
#include "machine/pit8253.h"
29
 
#include "machine/8042kbdc.h"
30
 
#include "machine/mc146818.h"
31
 
 
32
 
#define VERBOSE_DBG 0       /* general debug messages */
33
 
#define DBG_LOG(N,M,A) \
34
 
        if(VERBOSE_DBG>=N){ if( M )logerror("%11.6f: %-24s",pc_keyb.machine().time().as_double(),(char*)M ); logerror A; }
35
 
 
36
 
#define VERBOSE_JOY 0           /* JOY (joystick port) */
37
 
#define JOY_LOG(N,M,A) \
38
 
        if(VERBOSE_JOY>=N){ if( M )logerror("%11.6f: %-24s",pc_keyb.machine().time().as_double(),(char*)M ); logerror A; }
39
 
 
40
 
 
41
 
static TIMER_CALLBACK( pc_keyb_timer );
42
 
 
43
 
/*
44
 
   keyboard seams to permanently sent data clocked by the mainboard
45
 
   clock line low for longer means "resync", keyboard sends 0xaa as answer
46
 
   will become automatically 0x00 after a while
47
 
*/
48
 
 
49
 
static struct {
50
 
        running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
51
 
 
52
 
        running_machine *m_machine;
53
 
        void (*int_cb)(running_machine &, int);
54
 
        emu_timer *timer;
55
 
        UINT8 data;
56
 
        int on;
57
 
        int self_test;
58
 
} pc_keyb;
59
 
 
60
 
 
61
 
 
62
 
void init_pc_common(running_machine &machine, UINT32 flags, void (*set_keyb_int_func)(running_machine &, int))
63
 
{
64
 
        /* PC-XT keyboard */
65
 
        if (flags & PCCOMMON_KEYBOARD_AT)
66
 
                at_keyboard_init(machine, AT_KEYBOARD_TYPE_AT);
67
 
        else
68
 
                at_keyboard_init(machine, AT_KEYBOARD_TYPE_PC);
69
 
        at_keyboard_set_scan_code_set(1);
70
 
 
71
 
        memset(&pc_keyb, 0, sizeof(pc_keyb));
72
 
        pc_keyb.m_machine = &machine;
73
 
        pc_keyb.int_cb = set_keyb_int_func;
74
 
        pc_keyb.timer = machine.scheduler().timer_alloc(FUNC(pc_keyb_timer));
75
 
}
76
 
 
77
 
UINT8 pc_keyb_read(void)
78
 
{
79
 
        return pc_keyb.data;
80
 
}
81
 
 
82
 
 
83
 
 
84
 
static TIMER_CALLBACK( pc_keyb_timer )
85
 
{
86
 
        if ( pc_keyb.on ) {
87
 
                pc_keyboard();
88
 
        } else {
89
 
                /* Clock has been low for more than 5 msec, start diagnostic test */
90
 
                at_keyboard_reset(machine);
91
 
                pc_keyb.self_test = 1;
92
 
        }
93
 
}
94
 
 
95
 
 
96
 
 
97
 
void pc_keyb_set_clock(int on)
98
 
{
99
 
        on = on ? 1 : 0;
100
 
 
101
 
        if (pc_keyb.on != on)
102
 
        {
103
 
                if (!on)
104
 
                        pc_keyb.timer->adjust(attotime::from_msec(5));
105
 
                else {
106
 
                        if ( pc_keyb.self_test ) {
107
 
                                /* The self test of the keyboard takes some time. 2 msec seems to work. */
108
 
                                /* This still needs to verified against a real keyboard. */
109
 
                                pc_keyb.timer->adjust(attotime::from_msec( 2 ));
110
 
                        } else {
111
 
                                pc_keyb.timer->reset();
112
 
                                pc_keyb.self_test = 0;
113
 
                        }
114
 
                }
115
 
 
116
 
                pc_keyb.on = on;
117
 
        }
118
 
}
119
 
 
120
 
void pc_keyb_clear(void)
121
 
{
122
 
        pc_keyb.data = 0;
123
 
        if ( pc_keyb.int_cb ) {
124
 
                pc_keyb.int_cb(pc_keyb.machine(), 0);
125
 
        }
126
 
}
127
 
 
128
 
void pc_keyboard(void)
129
 
{
130
 
        int data;
131
 
 
132
 
        at_keyboard_polling();
133
 
 
134
 
        if (pc_keyb.on)
135
 
        {
136
 
                if ( (data=at_keyboard_read())!=-1) {
137
 
                        pc_keyb.data = data;
138
 
                        DBG_LOG(1,"KB_scancode",("$%02x\n", pc_keyb.data));
139
 
                        if ( pc_keyb.int_cb ) {
140
 
                                pc_keyb.int_cb(pc_keyb.machine(), 1);
141
 
                        }
142
 
                        pc_keyb.self_test = 0;
143
 
                }
144
 
        }
145
 
}
146
 
 
147
 
/******************
148
 
DMA8237 Controller
149
 
******************/
150
 
 
151
 
static int dma_channel;
152
 
static UINT8 dma_offset[2][4];
153
 
static UINT8 at_pages[0x10];
154
 
 
155
 
static WRITE_LINE_DEVICE_HANDLER( pc_dma_hrq_changed )
156
 
{
157
 
        cputag_set_input_line(device->machine(), "maincpu", INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
158
 
 
159
 
        /* Assert HLDA */
160
 
        i8237_hlda_w( device, state );
161
 
}
162
 
 
163
 
 
164
 
static READ8_HANDLER( pc_dma_read_byte )
165
 
{
166
 
        offs_t page_offset = (((offs_t) dma_offset[0][dma_channel]) << 16)
167
 
                & 0xFF0000;
168
 
 
169
 
        return space->read_byte(page_offset + offset);
170
 
}
171
 
 
172
 
 
173
 
static WRITE8_HANDLER( pc_dma_write_byte )
174
 
{
175
 
        offs_t page_offset = (((offs_t) dma_offset[0][dma_channel]) << 16)
176
 
                & 0xFF0000;
177
 
 
178
 
        space->write_byte(page_offset + offset, data);
179
 
}
180
 
 
181
 
static READ8_HANDLER(dma_page_select_r)
182
 
{
183
 
        UINT8 data = at_pages[offset % 0x10];
184
 
 
185
 
        switch(offset % 8)
186
 
        {
187
 
        case 1:
188
 
                data = dma_offset[(offset / 8) & 1][2];
189
 
                break;
190
 
        case 2:
191
 
                data = dma_offset[(offset / 8) & 1][3];
192
 
                break;
193
 
        case 3:
194
 
                data = dma_offset[(offset / 8) & 1][1];
195
 
                break;
196
 
        case 7:
197
 
                data = dma_offset[(offset / 8) & 1][0];
198
 
                break;
199
 
        }
200
 
        return data;
201
 
}
202
 
 
203
 
 
204
 
static WRITE8_HANDLER(dma_page_select_w)
205
 
{
206
 
        at_pages[offset % 0x10] = data;
207
 
 
208
 
        switch(offset % 8)
209
 
        {
210
 
        case 1:
211
 
                dma_offset[(offset / 8) & 1][2] = data;
212
 
                break;
213
 
        case 2:
214
 
                dma_offset[(offset / 8) & 1][3] = data;
215
 
                break;
216
 
        case 3:
217
 
                dma_offset[(offset / 8) & 1][1] = data;
218
 
                break;
219
 
        case 7:
220
 
                dma_offset[(offset / 8) & 1][0] = data;
221
 
                break;
222
 
        }
223
 
}
224
 
 
225
 
static void set_dma_channel(device_t *device, int channel, int state)
226
 
{
227
 
        if (!state) dma_channel = channel;
228
 
}
229
 
 
230
 
static WRITE_LINE_DEVICE_HANDLER( pc_dack0_w ) { set_dma_channel(device, 0, state); }
231
 
static WRITE_LINE_DEVICE_HANDLER( pc_dack1_w ) { set_dma_channel(device, 1, state); }
232
 
static WRITE_LINE_DEVICE_HANDLER( pc_dack2_w ) { set_dma_channel(device, 2, state); }
233
 
static WRITE_LINE_DEVICE_HANDLER( pc_dack3_w ) { set_dma_channel(device, 3, state); }
234
 
 
235
 
static I8237_INTERFACE( dma8237_1_config )
236
 
{
237
 
        DEVCB_LINE(pc_dma_hrq_changed),
238
 
        DEVCB_NULL,
239
 
        DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, pc_dma_read_byte),
240
 
        DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, pc_dma_write_byte),
241
 
        { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL },
242
 
        { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL },
243
 
        { DEVCB_LINE(pc_dack0_w), DEVCB_LINE(pc_dack1_w), DEVCB_LINE(pc_dack2_w), DEVCB_LINE(pc_dack3_w) }
244
 
};
245
 
 
246
 
static I8237_INTERFACE( dma8237_2_config )
247
 
{
248
 
        DEVCB_NULL,
249
 
        DEVCB_NULL,
250
 
        DEVCB_NULL,
251
 
        DEVCB_NULL,
252
 
        { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL },
253
 
        { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL },
254
 
        { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL }
255
 
};
256
 
 
257
 
 
258
 
/******************
259
 
8259 IRQ controller
260
 
******************/
261
 
 
262
 
static WRITE_LINE_DEVICE_HANDLER( pic8259_1_set_int_line )
263
 
{
264
 
        cputag_set_input_line(device->machine(), "maincpu", 0, state ? HOLD_LINE : CLEAR_LINE);
265
 
}
266
 
 
267
 
static READ8_DEVICE_HANDLER( get_slave_ack )
268
 
{
269
 
        if (offset==2) { // IRQ = 2
270
 
                return pic8259_acknowledge(device->machine().device("pic8259_2"));
271
 
        }
272
 
        return 0x00;
273
 
}
274
 
 
275
 
static const struct pic8259_interface pic8259_1_config =
276
 
{
277
 
        DEVCB_LINE(pic8259_1_set_int_line),
278
 
        DEVCB_LINE_VCC,
279
 
        DEVCB_HANDLER(get_slave_ack)
280
 
};
281
 
 
282
 
static const struct pic8259_interface pic8259_2_config =
283
 
{
284
 
        DEVCB_DEVICE_LINE("pic8259_1", pic8259_ir2_w),
285
 
        DEVCB_LINE_GND,
286
 
        DEVCB_NULL
287
 
};
288
 
 
289
 
IRQ_CALLBACK(pcat_irq_callback)
290
 
{
291
 
        return pic8259_acknowledge(device->machine().device("pic8259_1"));
292
 
}
293
 
 
294
 
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out0_changed )
295
 
{
296
 
        if ( device->machine().device("pic8259_1") )
297
 
        {
298
 
                pic8259_ir0_w(device->machine().device("pic8259_1"), state);
299
 
        }
300
 
}
301
 
 
302
 
 
303
 
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out2_changed )
304
 
{
305
 
        //at_speaker_set_input( state ? 1 : 0 );
306
 
}
307
 
 
308
 
 
309
 
static const struct pit8253_config at_pit8254_config =
310
 
{
311
 
        {
312
 
                {
313
 
                        4772720/4,                              /* heartbeat IRQ */
314
 
                        DEVCB_NULL,
315
 
                        DEVCB_LINE(at_pit8254_out0_changed)
316
 
                }, {
317
 
                        4772720/4,                              /* dram refresh */
318
 
                        DEVCB_NULL,
319
 
                        DEVCB_NULL
320
 
                }, {
321
 
                        4772720/4,                              /* pio port c pin 4, and speaker polling enough */
322
 
                        DEVCB_NULL,
323
 
                        DEVCB_LINE(at_pit8254_out2_changed)
324
 
                }
325
 
        }
326
 
};
327
 
 
328
 
ADDRESS_MAP_START( pcat32_io_common, AS_IO, 32 )
329
 
        AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE8("dma8237_1", i8237_r, i8237_w, 0xffffffff)
330
 
        AM_RANGE(0x0020, 0x003f) AM_DEVREADWRITE8("pic8259_1", pic8259_r, pic8259_w, 0xffffffff)
331
 
        AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE8("pit8254", pit8253_r, pit8253_w, 0xffffffff)
332
 
        AM_RANGE(0x0060, 0x006f) AM_READWRITE8(kbdc8042_8_r, kbdc8042_8_w, 0xffffffff)
333
 
        AM_RANGE(0x0070, 0x007f) AM_RAM //AM_DEVREADWRITE8_MODERN("rtc", mc146818_device, read, write, 0xffffffff)
334
 
        AM_RANGE(0x0080, 0x009f) AM_READWRITE8(dma_page_select_r,dma_page_select_w, 0xffffffff)//TODO
335
 
        AM_RANGE(0x00a0, 0x00bf) AM_DEVREADWRITE8("pic8259_2", pic8259_r, pic8259_w, 0xffffffff)
336
 
        AM_RANGE(0x00c0, 0x00df) AM_DEVREADWRITE8("dma8237_2", i8237_r, i8237_w, 0xffff)
337
 
ADDRESS_MAP_END
338
 
 
339
 
MACHINE_CONFIG_FRAGMENT(pcat_common)
340
 
        MCFG_PIC8259_ADD( "pic8259_1", pic8259_1_config )
341
 
        MCFG_PIC8259_ADD( "pic8259_2", pic8259_2_config )
342
 
        MCFG_I8237_ADD( "dma8237_1", XTAL_14_31818MHz/3, dma8237_1_config )
343
 
        MCFG_I8237_ADD( "dma8237_2", XTAL_14_31818MHz/3, dma8237_2_config )
344
 
        MCFG_PIT8254_ADD( "pit8254", at_pit8254_config )
345
 
//  MCFG_MC146818_ADD( "rtc", MC146818_STANDARD )
346
 
MACHINE_CONFIG_END