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
|
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
/**********************************************************************
Signetics 2636 Programmable Video Interface
**********************************************************************/
#ifndef MAME_MACHINE_S2636_H
#define MAME_MACHINE_S2636_H
#pragma once
#define S2636_IS_PIXEL_DRAWN(p) (((p) & 0x08) ? true : false)
#define S2636_PIXEL_COLOR(p) ((p) & 0x07)
/*************************************
*
* Device configuration macros
*
*************************************/
#define MCFG_S2636_OFFSETS(yoffs, xoffs) \
downcast<s2636_device &>(*device).set_offsets((yoffs), (xoffs));
#define MCFG_S2636_DIVIDER(divider) \
downcast<s2636_device &>(*device).set_divider((divider));
#define MCFG_S2623_SET_INTREQ_CALLBACK(cb) \
downcast<s2636_device &>(*device).set_intreq_cb(DEVCB_##cb);
/*************************************
*
* Device state class
*
*************************************/
class s2636_device : public device_t,
public device_video_interface,
public device_sound_interface
{
public:
s2636_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void set_offsets(int y_offset, int x_offset) { m_x_offset = x_offset; m_y_offset = y_offset; }
void set_divider(int divider) { m_divider = divider; }
template <class Object> devcb_base &set_intreq_cb(Object &&cb) { return m_intreq_cb.set_callback(std::forward<Object>(cb)); }
// returns a BITMAP_FORMAT_IND16 bitmap the size of the screen
// D0-D2 of each pixel is the pixel color
// D3 indicates how the S2636 drew this pixel - 0 = background, 1 = object/score
bitmap_ind16 const &bitmap() const { return m_bitmap; }
// this function is for backwards compatibility and will eventually be removed
// use the functions below for per-scanline drawing/collisions
bitmap_ind16 const &update(const rectangle &cliprect);
// call render_first_line to render the first line of the display and render_next_line for each additional line
void render_first_line();
void render_next_line();
DECLARE_READ8_MEMBER( read_data );
DECLARE_WRITE8_MEMBER( write_data );
DECLARE_WRITE_LINE_MEMBER( write_intack );
protected:
// device-level overrides
virtual void device_start() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
private:
enum
{
OBJ_COUNT = 4,
OBJ_WIDTH = 8,
OBJ_HEIGHT = 10,
BG_START_X = 32,
BG_START_Y = 20,
BG_WIDTH = 8 * 16,
BG_HEIGHT = 200,
SCORE_DIGITS = 4,
SCORE_WIDTH = 12,
SCORE_HEIGHT = 20,
OFFS_HC = 0x00a,
OFFS_HCB = 0x00b,
OFFS_VC = 0x00c,
OFFS_VCB = 0x00d,
OFFS_VBAR_DEF = 0x080,
OFFS_HBAR_DEF = 0x0a8,
REG_OBJ_SIZE = 0x0c0,
REG_OBJ_CLR_1_2 = 0x0c1,
REG_OBJ_CLR_3_4 = 0x0c2,
REG_SCORE_FMT = 0x0c3,
REG_BG_ENB_CLR = 0x0c6,
REG_SND_PERIOD = 0x0c7,
REG_SCORE_1_2 = 0x0c8,
REG_SCORE_3_4 = 0x0c9,
REG_COL_BG_CMPL = 0x0ca,
REG_VBL_COL_OBJ = 0x0cb,
REG_AD_POT1 = 0x0cc,
REG_AD_POT2 = 0x0cd
};
static int const OFFS_OBJ[OBJ_COUNT];
static uint16_t const SCORE_FONT[16][5];
static int const SCORE_START_X[2][SCORE_DIGITS];
static int const SCORE_START_Y[2];
static void mask_offset(offs_t &offset) { offset &= ((offset & 0x0c0) == 0x0c0) ? 0x0cf : 0x0ff; }
uint8_t object_scale(int obj) const { return (m_registers[REG_OBJ_SIZE] >> (2 * obj)) & 0x03; }
uint8_t object_color(int obj) const { return (m_registers[REG_OBJ_CLR_1_2 + (obj >> 1)] >> ((obj & 1) ? 0 : 3)) & 0x07; }
uint8_t score_digit(int digit) const { return (m_registers[REG_SCORE_1_2 + (digit >> 1)] >> ((digit & 1) ? 0 : 4)) & 0x0f; }
void update_intreq(int value);
// Configuration
int m_divider;
int m_y_offset;
int m_x_offset;
// interfacing with other devices
devcb_write_line m_intreq_cb;
bitmap_ind16 m_bitmap;
// 256-byte register file (not all of this really exists)
uint8_t m_registers[0x100];
// tracking where we're up to in the screen update
bool m_vrst;
int m_screen_line;
int m_vis_line;
// current display state of object
int m_obj_cnt[OBJ_COUNT];
bool m_obj_disp[OBJ_COUNT];
bool m_obj_dup[OBJ_COUNT];
// interrupt generation
int m_intreq;
int m_intack;
// sound generation state
sound_stream *m_stream;
int m_sample_cnt;
bool m_sound_lvl;
};
DECLARE_DEVICE_TYPE(S2636, s2636_device)
#endif // MAME_MACHINE_S2636_H
|