1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
|
/*
rmnimbus.c
Machine driver for the Research Machines Nimbus.
Phill Harvey-Smith
2009-11-29.
*/
#include "machine/z80sio.h"
#include "machine/wd17xx.h"
#include "machine/scsibus.h"
#include "machine/6522via.h"
#define MAINCPU_TAG "maincpu"
#define IOCPU_TAG "iocpu"
#define num_ioports 0x80
#define NIMBUS_KEYROWS 11
#define KEYBOARD_QUEUE_SIZE 32
#define SCREEN_WIDTH_PIXELS 640
#define SCREEN_HEIGHT_LINES 250
#define SCREEN_NO_COLOURS 16
#define NO_VIDREGS (0x30/2)
/* Nimbus sub-bios structures for debugging */
struct t_area_params
{
UINT16 ofs_brush;
UINT16 seg_brush;
UINT16 ofs_data;
UINT16 seg_data;
UINT16 count;
};
struct t_plot_string_params
{
UINT16 ofs_font;
UINT16 seg_font;
UINT16 ofs_data;
UINT16 seg_data;
UINT16 x;
UINT16 y;
UINT16 length;
};
struct t_nimbus_brush
{
UINT16 style;
UINT16 style_index;
UINT16 colour1;
UINT16 colour2;
UINT16 transparency;
UINT16 boundary_spec;
UINT16 boundary_colour;
UINT16 save_colour;
};
#define SCREEN_WIDTH_PIXELS 640
#define SCREEN_HEIGHT_LINES 250
#define SCREEN_NO_COLOURS 16
/* 80186 internal stuff */
struct mem_state
{
UINT16 lower;
UINT16 upper;
UINT16 middle;
UINT16 middle_size;
UINT16 peripheral;
};
struct timer_state
{
UINT16 control;
UINT16 maxA;
UINT16 maxB;
UINT16 count;
emu_timer *int_timer;
emu_timer *time_timer;
UINT8 time_timer_active;
attotime last_time;
};
struct dma_state
{
UINT32 source;
UINT32 dest;
UINT16 count;
UINT16 control;
UINT8 finished;
emu_timer *finish_timer;
};
struct intr_state
{
UINT8 pending;
UINT16 ack_mask;
UINT16 priority_mask;
UINT16 in_service;
UINT16 request;
UINT16 status;
UINT16 poll_status;
UINT16 timer;
UINT16 dma[2];
UINT16 ext[4];
UINT16 ext_vector[2]; // external vectors, when in cascade mode
};
struct i186_state
{
struct timer_state timer[3];
struct dma_state dma[2];
struct intr_state intr;
struct mem_state mem;
};
struct keyboard_t
{
UINT8 keyrows[NIMBUS_KEYROWS];
emu_timer *keyscan_timer;
UINT8 queue[KEYBOARD_QUEUE_SIZE];
UINT8 head;
UINT8 tail;
};
// Static data related to Floppy and SCSI hard disks
struct nimbus_drives_t
{
UINT8 reg400;
UINT8 reg410_in;
UINT8 reg410_out;
UINT8 reg418;
UINT8 drq_ff;
UINT8 int_ff;
};
/* 8031 Peripheral controler */
struct ipc_interface_t
{
UINT8 ipc_in;
UINT8 ipc_out;
UINT8 status_in;
UINT8 status_out;
UINT8 int_8c_pending;
UINT8 int_8e_pending;
UINT8 int_8f_pending;
};
/* Mouse/Joystick */
struct _mouse_joy_state
{
UINT8 m_mouse_px;
UINT8 m_mouse_py;
UINT8 m_mouse_x;
UINT8 m_mouse_y;
UINT8 m_mouse_pc;
UINT8 m_mouse_pcx;
UINT8 m_mouse_pcy;
UINT8 m_intstate_x;
UINT8 m_intstate_y;
UINT8 m_reg0a4;
emu_timer *m_mouse_timer;
};
class rmnimbus_state : public driver_device
{
public:
rmnimbus_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
UINT32 m_debug_machine;
i186_state m_i186;
keyboard_t m_keyboard;
nimbus_drives_t m_nimbus_drives;
ipc_interface_t m_ipc_interface;
UINT8 m_mcu_reg080;
UINT8 m_iou_reg092;
UINT8 m_last_playmode;
_mouse_joy_state m_nimbus_mouse;
UINT8 m_ay8910_a;
UINT16 m_IOPorts[num_ioports];
UINT8 m_sio_int_state;
UINT8 m_video_mem[SCREEN_WIDTH_PIXELS][SCREEN_HEIGHT_LINES];
UINT16 m_vidregs[NO_VIDREGS];
UINT8 m_bpp;
UINT16 m_pixel_mask;
UINT8 m_hs_count;
UINT32 m_debug_video;
DECLARE_READ16_MEMBER(nimbus_i186_internal_port_r);
DECLARE_WRITE16_MEMBER(nimbus_i186_internal_port_w);
DECLARE_READ8_MEMBER(nimbus_mcu_r);
DECLARE_WRITE8_MEMBER(nimbus_mcu_w);
DECLARE_READ16_MEMBER(nimbus_io_r);
DECLARE_WRITE16_MEMBER(nimbus_io_w);
DECLARE_READ8_MEMBER(nimbus_disk_r);
DECLARE_WRITE8_MEMBER(nimbus_disk_w);
DECLARE_READ8_MEMBER(nimbus_pc8031_r);
DECLARE_WRITE8_MEMBER(nimbus_pc8031_w);
DECLARE_READ8_MEMBER(nimbus_pc8031_iou_r);
DECLARE_WRITE8_MEMBER(nimbus_pc8031_iou_w);
DECLARE_READ8_MEMBER(nimbus_pc8031_port_r);
DECLARE_WRITE8_MEMBER(nimbus_pc8031_port_w);
DECLARE_READ8_MEMBER(nimbus_iou_r);
DECLARE_WRITE8_MEMBER(nimbus_iou_w);
DECLARE_READ8_MEMBER(nimbus_sound_ay8910_r);
DECLARE_WRITE8_MEMBER(nimbus_sound_ay8910_w);
DECLARE_WRITE8_MEMBER(nimbus_sound_ay8910_porta_w);
DECLARE_WRITE8_MEMBER(nimbus_sound_ay8910_portb_w);
DECLARE_READ8_MEMBER(nimbus_mouse_js_r);
DECLARE_WRITE8_MEMBER(nimbus_mouse_js_w);
DECLARE_READ16_MEMBER(nimbus_video_io_r);
DECLARE_WRITE16_MEMBER(nimbus_video_io_w);
DECLARE_DRIVER_INIT(nimbus);
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
virtual void video_reset();
virtual void palette_init();
};
/*----------- defined in drivers/rmnimbus.c -----------*/
extern const unsigned char nimbus_palette[SCREEN_NO_COLOURS][3];
/*----------- defined in machine/rmnimbus.c -----------*/
/* 80186 Internal */
/* external int priority masks */
#define EXTINT_CTRL_PRI_MASK 0x07
#define EXTINT_CTRL_MSK 0x08
#define EXTINT_CTRL_LTM 0x10
#define EXTINT_CTRL_CASCADE 0x20
#define EXTINT_CTRL_SFNM 0x40
/* DMA control register */
#define DEST_MIO 0x8000
#define DEST_DECREMENT 0x4000
#define DEST_INCREMENT 0x2000
#define DEST_NO_CHANGE (DEST_DECREMENT | DEST_INCREMENT)
#define DEST_INCDEC_MASK (DEST_DECREMENT | DEST_INCREMENT)
#define SRC_MIO 0X1000
#define SRC_DECREMENT 0x0800
#define SRC_INCREMENT 0x0400
#define SRC_NO_CHANGE (SRC_DECREMENT | SRC_INCREMENT)
#define SRC_INCDEC_MASK (SRC_DECREMENT | SRC_INCREMENT)
#define TERMINATE_ON_ZERO 0x0200
#define INTERRUPT_ON_ZERO 0x0100
#define SYNC_MASK 0x00C0
#define SYNC_SOURCE 0x0040
#define SYNC_DEST 0x0080
#define CHANNEL_PRIORITY 0x0020
#define TIMER_DRQ 0x0010
#define CHG_NOCHG 0x0004
#define ST_STOP 0x0002
#define BYTE_WORD 0x0001
/* Nimbus specific */
/* External int vectors for chained interupts */
#define EXTERNAL_INT_DISK 0x80
#define EXTERNAL_INT_MSM5205 0x84
#define EXTERNAL_INT_MOUSE_YU 0x88
#define EXTERNAL_INT_MOUSE_YD 0x89
#define EXTERNAL_INT_MOUSE_XL 0x8A
#define EXTERNAL_INT_MOUSE_XR 0x8B
#define EXTERNAL_INT_PC8031_8C 0x8c
#define EXTERNAL_INT_PC8031_8E 0x8E
#define EXTERNAL_INT_PC8031_8F 0x8F
#define EXTERNAL_INT_Z80SIO 0x9C
/* Memory controler */
#define RAM_BANK00_TAG "bank0"
#define RAM_BANK01_TAG "bank1"
#define RAM_BANK02_TAG "bank2"
#define RAM_BANK03_TAG "bank3"
#define RAM_BANK04_TAG "bank4"
#define RAM_BANK05_TAG "bank5"
#define RAM_BANK06_TAG "bank6"
#define RAM_BANK07_TAG "bank7"
#define HIBLOCK_BASE_MASK 0x08
#define HIBLOCK_SELECT_MASK 0x10
/* Z80 SIO for keyboard */
#define Z80SIO_TAG "z80sio"
extern const z80sio_interface nimbus_sio_intf;
/* Floppy/Fixed drive interface */
#define FDC_TAG "wd2793"
#define FDC_PAUSE 10000
extern const wd17xx_interface nimbus_wd17xx_interface;
#define NO_DRIVE_SELECTED 0xFF
/* SASI harddisk interface */
#define SCSIBUS_TAG "scsibus"
void nimbus_scsi_linechange(device_t *device, UINT8 line, UINT8 state);
/* Masks for writes to port 0x400 */
#define FDC_DRIVE0_MASK 0x01
#define FDC_DRIVE1_MASK 0x02
#define FDC_DRIVE2_MASK 0x04
#define FDC_DRIVE3_MASK 0x08
#define FDC_SIDE_MASK 0x10
#define FDC_MOTOR_MASKO 0x20
#define HDC_DRQ_MASK 0x40
#define FDC_DRQ_MASK 0x80
#define FDC_DRIVE_MASK (FDC_DRIVE0_MASK | FDC_DRIVE1_MASK | FDC_DRIVE2_MASK | FDC_DRIVE3_MASK)
#define FDC_SIDE() ((state->m_nimbus_drives.reg400 & FDC_SIDE_MASK) >> 4)
#define FDC_MOTOR() ((state->m_nimbus_drives.reg400 & FDC_MOTOR_MASKO) >> 5)
#define FDC_DRIVE() (fdc_driveno(state->m_nimbus_drives.reg400 & FDC_DRIVE_MASK))
#define HDC_DRQ_ENABLED() ((state->m_nimbus_drives.reg400 & HDC_DRQ_MASK) ? 1 : 0)
#define FDC_DRQ_ENABLED(state) ((state->m_nimbus_drives.reg400 & FDC_DRQ_MASK) ? 1 : 0)
/* Masks for port 0x410 read*/
#define FDC_READY_MASK 0x01
#define FDC_INDEX_MASK 0x02
#define FDC_MOTOR_MASKI 0x04
#define HDC_MSG_MASK 0x08
#define HDC_BSY_MASK 0x10
#define HDC_IO_MASK 0X20
#define HDC_CD_MASK 0x40
#define HDC_REQ_MASK 0x80
#define FDC_BITS_410 (FDC_READY_MASK | FDC_INDEX_MASK | FDC_MOTOR_MASKI)
#define HDC_BITS_410 (HDC_MSG_MASK | HDC_BSY_MASK | HDC_IO_MASK | HDC_CD_MASK | HDC_REQ_MASK)
#define INV_BITS_410 (HDC_BSY_MASK | HDC_IO_MASK | HDC_CD_MASK | HDC_REQ_MASK)
#define HDC_INT_TRIGGER (HDC_IO_MASK | HDC_CD_MASK | HDC_REQ_MASK)
/* Masks for port 0x410 write*/
#define HDC_RESET_MASK 0x01
#define HDC_SEL_MASK 0x02
#define HDC_IRQ_MASK 0x04
#define HDC_IRQ_ENABLED(state) ((state->m_nimbus_drives.reg410_out & HDC_IRQ_MASK) ? 1 : 0)
#define SCSI_ID_NONE 0x80
/* 8031/8051 Peripheral controler */
#define IPC_OUT_ADDR 0X01
#define IPC_OUT_READ_PEND 0X02
#define IPC_OUT_BYTE_AVAIL 0X04
#define IPC_IN_ADDR 0X01
#define IPC_IN_BYTE_AVAIL 0X02
#define IPC_IN_READ_PEND 0X04
#define ER59256_TAG "er59256"
/* IO unit */
#define DISK_INT_ENABLE 0x01
#define MSM5205_INT_ENABLE 0x04
#define MOUSE_INT_ENABLE 0x08
#define PC8031_INT_ENABLE 0x10
/* Sound hardware */
#define AY8910_TAG "ay8910"
#define MONO_TAG "mono"
#define MSM5205_TAG "msm5205"
void nimbus_msm5205_vck(device_t *device);
/* Mouse / Joystick */
#define JOYSTICK0_TAG "joystick0"
#define MOUSE_BUTTON_TAG "mousebtn"
#define MOUSEX_TAG "mousex"
#define MOUSEY_TAG "mousey"
enum
{
MOUSE_PHASE_STATIC = 0,
MOUSE_PHASE_POSITIVE,
MOUSE_PHASE_NEGATIVE
};
#define MOUSE_INT_ENABLED(state) (((state)->m_iou_reg092 & MOUSE_INT_ENABLE) ? 1 : 0)
/* Paralell / User port BBC compatible ! */
#define VIA_TAG "via6522"
#define CENTRONICS_TAG "centronics"
#define VIA_INT 0x03
extern const via6522_interface nimbus_via;
WRITE_LINE_DEVICE_HANDLER(nimbus_ack_w);
/*----------- defined in video/rmnimbus.c -----------*/
SCREEN_VBLANK( nimbus );
SCREEN_UPDATE_IND16( nimbus );
#define RED 0
#define GREEN 1
#define BLUE 2
#define LINEAR_ADDR(seg,ofs) ((seg<<4)+ofs)
#define OUTPUT_SEGOFS(mess,seg,ofs) logerror("%s=%04X:%04X [%08X]\n",mess,seg,ofs,((seg<<4)+ofs))
|