summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/nick.h
blob: acc3a795c4d7eba8c99acee8e4e2122ff40e8905 (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
/**********************************************************************

    Intelligent Designs NICK emulation

    Copyright MESS Team.
    Visit http://mamedev.org for licensing and usage restrictions.

**********************************************************************/

#pragma once

#ifndef __NICK__
#define __NICK__

#include "emu.h"
#include "machine/rescap.h"
#include "video/resnet.h"



///*************************************************************************
//  INTERFACE CONFIGURATION MACROS
///*************************************************************************

#define MCFG_NICK_ADD(_tag, _screen_tag, _clock, _virq) \
	MCFG_SCREEN_ADD(_screen_tag, RASTER) \
	MCFG_SCREEN_REFRESH_RATE(50) \
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) \
	MCFG_SCREEN_SIZE(ENTERPRISE_SCREEN_WIDTH, ENTERPRISE_SCREEN_HEIGHT) \
	MCFG_SCREEN_VISIBLE_AREA(0, ENTERPRISE_SCREEN_WIDTH-1, 0, ENTERPRISE_SCREEN_HEIGHT-1) \
	MCFG_SCREEN_UPDATE_DEVICE(_tag, nick_device, screen_update) \
	MCFG_DEVICE_ADD(_tag, NICK, _clock) \
	downcast<nick_device *>(device)->set_screen_tag(_screen_tag); \
	downcast<nick_device *>(device)->set_virq_callback(DEVCB2_##_virq);


/* there are 64us per line, although in reality
 about 50 are visible. */
#define ENTERPRISE_SCREEN_WIDTH (50*16)

/* there are 312 lines per screen, although in reality
 about 35*8 are visible */
#define ENTERPRISE_SCREEN_HEIGHT    (35*8)


///*************************************************************************
//  TYPE DEFINITIONS
///*************************************************************************

/* Nick executes a Display list, in the form of a list of Line Parameter
 Tables, this is the form of the data */
struct LPT_ENTRY
{
	UINT8 SC;       /* scanlines in this modeline (two's complement) */
	UINT8 MB;       /* the MODEBYTE (defines video display mode) */
	UINT8 LM;       /* left margin etc */
	UINT8 RM;       /* right margin etc */
	UINT8 LD1L;     /* (a7..a0) of line data pointer LD1 */
	UINT8 LD1H;     /* (a8..a15) of line data pointer LD1 */
	UINT8 LD2L;     /* (a7..a0) of line data pointer LD2 */
	UINT8 LD2H;     /* (a8..a15) of line data pointer LD2 */
	UINT8 COL[8];   /* COL0..COL7 */
};


// ======================> nick_device

class nick_device :  public device_t,
					 public device_memory_interface
{
public:
	// construction/destruction
	nick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	void set_screen_tag(const char *screen_tag) { m_screen_tag = screen_tag; }
	template<class _virq> void set_virq_callback(_virq virq) { m_write_virq.set_callback(virq); }

	virtual DECLARE_ADDRESS_MAP(vram_map, 8);
	virtual DECLARE_ADDRESS_MAP(vio_map, 8);

	UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);

protected:
	// device-level overrides
	virtual void device_start();
	virtual void device_reset();
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);

	// device_memory_interface overrides
	virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;

	DECLARE_READ8_MEMBER( vram_r );
	DECLARE_WRITE8_MEMBER( vram_w );

	DECLARE_WRITE8_MEMBER( fixbias_w );
	DECLARE_WRITE8_MEMBER( border_w );
	DECLARE_WRITE8_MEMBER( lpl_w );
	DECLARE_WRITE8_MEMBER( lph_w );

	address_space_config m_space_config;

private:
	devcb2_write_line m_write_virq;

	void initialize_palette();

	void write_pixel(int ci);
	void calc_visible_clocks(int width);
	void init();
	void write_border(int clocks);
	void do_left_margin();
	void do_right_margin();

	int get_color_index(int pen_index);
	void write_pixels2color(UINT8 pen0, UINT8 pen1, UINT8 data_byte);
	void write_pixels2color_lpixel(UINT8 pen0, UINT8 pen1, UINT8 data_byte);
	void write_pixels(UINT8 data_byte, UINT8 char_idx);
	void write_pixels_lpixel(UINT8 data_byte, UINT8 char_idx);

	void do_pixel(int clocks_visible);
	void do_lpixel(int clocks_visible);
	void do_attr(int clocks_visible);
	void do_ch256(int clocks_visible);
	void do_ch128(int clocks_visible);
	void do_ch64(int clocks_visible);
	void do_display();
	void update_lpt();
	void reload_lpt();
	void do_line();

	/* horizontal position */
	UINT8 horizontal_clock;
	/* current scanline within LPT */
	UINT8 m_scanline_count;
	
	UINT8 m_FIXBIAS;
	UINT8 m_BORDER;
	UINT8 m_LPL;
	UINT8 m_LPH;
	
	UINT16 m_LD1;
	UINT16 m_LD2;
	
	LPT_ENTRY   m_LPT;
	
	UINT32 *m_dest;
	int m_dest_pos;
	int m_dest_max_pos;
	
	UINT8 m_reg[4];
	
	/* first clock visible on left hand side */
	int m_first_visible_clock;
	/* first clock visible on right hand side */
	int m_last_visible_clock;
	
	/* given a bit pattern, this will get the pen index */
	UINT8 m_pen_idx_4col[256];
	/* given a bit pattern, this will get the pen index */
	UINT8 m_pen_idx_16col[256];

	int m_virq;

	const char *m_screen_tag;
	screen_device *m_screen;
	bitmap_rgb32 m_bitmap;
	rgb_t m_palette[256];

	emu_timer *m_timer_scanline;
};


// device type definition
extern const device_type NICK;



#endif