summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/includes/rmnimbus.h
blob: 37100f8646e979db62830cf2f6f276432f153c74 (plain) (tree)



























































































































































































































































































































                                                                                        
















                                                                                               
                                                                                         













































































































                                                                                                  
/*
    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 */

typedef struct
{
	UINT16  ofs_brush;
	UINT16  seg_brush;
	UINT16  ofs_data;
	UINT16  seg_data;
	UINT16  count;
} t_area_params;

typedef struct
{
	UINT16  ofs_font;
	UINT16  seg_font;
	UINT16  ofs_data;
	UINT16  seg_data;
	UINT16  x;
	UINT16  y;
	UINT16  length;
} t_plot_string_params;

typedef struct
{
	UINT16  style;
	UINT16  style_index;
	UINT16  colour1;
	UINT16  colour2;
	UINT16  transparency;
	UINT16  boundary_spec;
	UINT16  boundary_colour;
	UINT16  save_colour;
} t_nimbus_brush;

#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
};

typedef struct
{
	struct timer_state	timer[3];
	struct dma_state	dma[2];
	struct intr_state	intr;
	struct mem_state	mem;
} i186_state;

typedef struct
{
	UINT8       keyrows[NIMBUS_KEYROWS];
	emu_timer   *keyscan_timer;
	UINT8       queue[KEYBOARD_QUEUE_SIZE];
	UINT8       head;
	UINT8       tail;
}  keyboard_t;

// Static data related to Floppy and SCSI hard disks
typedef struct
{
	UINT8   reg400;
	UINT8   reg410_in;
	UINT8   reg410_out;
	UINT8   reg418;

	UINT8   drq_ff;
	UINT8   int_ff;
} nimbus_drives_t;

/* 8031 Peripheral controler */
typedef struct
{
	UINT8   ipc_in;
	UINT8   ipc_out;
	UINT8   status_in;
	UINT8   status_out;
	UINT8   int_8c_pending;
	UINT8   int_8e_pending;
	UINT8   int_8f_pending;
} ipc_interface_t;

/* Mouse/Joystick */
typedef struct
{
	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;
} _mouse_joy_state;


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);
};


/*----------- defined in drivers/rmnimbus.c -----------*/

extern const unsigned char nimbus_palette[SCREEN_NO_COLOURS][3];


/*----------- defined in machine/rmnimbus.c -----------*/

MACHINE_RESET(nimbus);
MACHINE_START(nimbus);

/* 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 -----------*/


VIDEO_START( nimbus );
SCREEN_VBLANK( nimbus );
SCREEN_UPDATE_IND16( nimbus );
VIDEO_RESET( 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))