summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/includes/rmnimbus.h
blob: e59a469c762003a08417ace34aa47e0f4a12578a (plain) (blame)
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))