1 // license:BSD-3-Clause
2 // copyright-holders:Nathan Woods,Frank Palazzolo
3 /*****************************************************************************
4  *
5  * includes/stic.h
6  *
7  ****************************************************************************/
8 
9 #ifndef MAME_VIDEO_STIC_H
10 #define MAME_VIDEO_STIC_H
11 
12 // the Intellivision emulation scales to match the output format at the last
13 // step. The Intellivision keyboard component appears to be 320x96, but can
14 // also run Intellivision carts, so x-coordinates are conditionally scaled
15 // by 2.
16 #define INTV_X_SCALE                1
17 #define INTV_Y_SCALE                1
18 #define INTVKBD_X_SCALE             2
19 #define INTVKBD_Y_SCALE             INTV_Y_SCALE
20 
21 struct intv_sprite_type
22 {
23 	int visible;
24 	int xpos;
25 	int ypos;
26 	int coll;
27 	int collision;
28 	int doublex;
29 	int doubley;
30 	int quady;
31 	int xflip;
32 	int yflip;
33 	int behind_foreground;
34 	int grom;
35 	int card;
36 	int color;
37 	int doubleyres;
38 	int dirty;
39 };
40 
41 
42 // ======================> stic_device
43 
44 class stic_device :  public device_t, public device_video_interface
45 {
46 public:
47 	// GROM/GRAM cards are 8x8
48 	static constexpr unsigned   CARD_WIDTH              = 8;
49 	static constexpr unsigned   CARD_HEIGHT             = 8;
50 
51 	// Intellivision resolution is 20x12 BACKTAB CARDs, minus the rightmost column,
52 	// for an effective resolution of (19 * 8 + 1 * 7) x (12 * 8) == 159x96.
53 	//
54 	// MOB scanline height can be half of a card scanline height, so y-coordinates
55 	// are scaled by 2.
56 	static constexpr unsigned   X_SCALE                 = 1;
57 	static constexpr unsigned   Y_SCALE                 = 2;
58 
59 	// overscan sizes in intv pixels
60 	// these values are approximate.
61 	static constexpr unsigned   OVERSCAN_LEFT_WIDTH     = 13;
62 	static constexpr unsigned   OVERSCAN_RIGHT_WIDTH    = 17;
63 	static constexpr unsigned   OVERSCAN_TOP_HEIGHT     = 12;
64 	static constexpr unsigned   OVERSCAN_BOTTOM_HEIGHT  = 12;
65 
66 	//Timing constants based on  Joe Zbiciak's documentation
67 	static constexpr int        CYCLES_PER_SCANLINE     = 57;
68 	static constexpr int        ROW_BUSRQ               = 110; // CPU paused during backtab row buffering
69 	static constexpr int        FRAME_BUSRQ             = 42; // CPU paused just after end of vblank and before first row fetch (approximate)
70 	static constexpr int        VBLANK_END              = 3790;
71 	static constexpr int        FIRST_FETCH             = 3933;
72 
73 	/*** BACKTAB ****************************************************************/
74 
75 	// BACKTAB is made up of 20x12 cards
76 	// (the first 19 columns are 8x8, the 20th column is 7x8)
77 	static constexpr unsigned   BACKTAB_WIDTH           = 20;
78 	static constexpr unsigned   BACKTAB_HEIGHT          = 12;
79 
80 	static constexpr unsigned   SCREEN_WIDTH            = (OVERSCAN_LEFT_WIDTH + (BACKTAB_WIDTH * CARD_WIDTH) - 1 + OVERSCAN_RIGHT_WIDTH) * X_SCALE;
81 	static constexpr unsigned   SCREEN_HEIGHT           = (OVERSCAN_TOP_HEIGHT + (BACKTAB_HEIGHT * CARD_HEIGHT) + OVERSCAN_BOTTOM_HEIGHT) * Y_SCALE;
82 
83 	// construction/destruction
84 	stic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
85 	virtual ~stic_device();
86 
87 	uint16_t read(offs_t offset);
88 	uint16_t gram_read(offs_t offset);
grom_read(offs_t offset)89 	uint16_t grom_read(offs_t offset) { if (offset > 0x800) printf("help! %X\n", offset); return (0xff00 | m_grom[offset]); }
90 	void write(offs_t offset, uint16_t data);
91 	void gram_write(offs_t offset, uint16_t data);
92 
write_to_btb(int h,int w,uint16_t data)93 	void write_to_btb(int h, int w, uint16_t data) { m_backtab_buffer[h][w] = data; }
read_row_delay()94 	int read_row_delay() { return m_row_delay; }
read_stic_handshake()95 	int read_stic_handshake() { return m_stic_handshake; }
set_x_scale(int val)96 	void set_x_scale(int val) { m_x_scale = val; }
set_y_scale(int val)97 	void set_y_scale(int val) { m_y_scale = val; }
98 
99 	// device-level overrides
100 	virtual void device_start() override;
101 	virtual const tiny_rom_entry *device_rom_region() const override;
102 	virtual void device_reset() override;
103 
104 	void screenrefresh();
105 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
106 
107 private:
108 	/*** STIC registers *********************************************************/
109 
110 	// number of STIC registers
111 	static constexpr unsigned   STIC_REGISTERS  = 0x33;
112 
113 	// STIC MOBs (Moveable OBjects)
114 	enum
115 	{
116 		MOB0,
117 		MOB1,
118 		MOB2,
119 		MOB3,
120 		MOB4,
121 		MOB5,
122 		MOB6,
123 		MOB7,
124 
125 		MOBS
126 	};
127 
128 	// STIC Color Stack
129 	enum
130 	{
131 		CSR0,
132 		CSR1,
133 		CSR2,
134 		CSR3,
135 
136 		CSRS
137 	};
138 
139 
140 	required_region_ptr<uint8_t> m_grom;
141 
142 	void intv_set_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
143 	uint32_t intv_get_pixel(bitmap_ind16 &bitmap, int x, int y);
144 	void intv_plot_box(bitmap_ind16 &bm, int x, int y, int w, int h, int color);
145 	bool sprites_collide(int spriteNum1, int spriteNum2);
146 	void determine_sprite_collisions();
147 	void render_sprites();
148 	void render_line(bitmap_ind16 &bitmap, uint8_t nextByte, uint16_t x, uint16_t y, uint8_t fgcolor, uint8_t bgcolor);
149 	void render_colored_squares(bitmap_ind16 &bitmap, uint16_t x, uint16_t y, uint8_t color0, uint8_t color1, uint8_t color2, uint8_t color3);
150 	void render_color_stack_mode(bitmap_ind16 &bitmap);
151 	void render_fg_bg_mode(bitmap_ind16 &bitmap);
152 	void copy_sprites_to_background(bitmap_ind16 &bitmap);
153 	void render_background(bitmap_ind16 &bitmap);
154 	void draw_borders(bitmap_ind16 &bitmap);
155 
156 #ifdef UNUSED_CODE
157 	void draw_background(bitmap_ind16 &bitmap, int transparency);
158 	void draw_sprites(bitmap_ind16 &bitmap, int behind_foreground);
159 #endif
160 
161 	bitmap_ind16 m_bitmap;
162 
163 	intv_sprite_type m_sprite[MOBS];
164 	uint8_t m_sprite_buffers[MOBS][CARD_WIDTH * 2][CARD_HEIGHT * 4 * 2 * 2];
165 	uint16_t m_backtab_buffer[BACKTAB_HEIGHT][BACKTAB_WIDTH];
166 	int m_color_stack_mode;
167 	int m_stic_registers[STIC_REGISTERS];
168 	int m_color_stack_offset;
169 	int m_stic_handshake;
170 	int m_border_color;
171 	int m_col_delay;
172 	int m_row_delay;
173 	int m_left_edge_inhibit;
174 	int m_top_edge_inhibit;
175 	int m_x_scale;
176 	int m_y_scale;
177 
178 	uint8_t m_gramdirty;
179 	uint8_t m_gram[512];
180 	uint8_t m_gramdirtybytes[512];
181 };
182 
183 // device type definition
184 DECLARE_DEVICE_TYPE(STIC, stic_device)
185 
186 
187 #endif // MAME_VIDEO_STIC_H
188