summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/74181.c
blob: 18f41703922d7b39ce07e9d73745f39641e2f55d (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
/*
 * 74181
 *
 * 4-bit arithmetic Logic Unit
 *
 */

#include "emu.h"
#include "74181.h"



#define TTL74181_MAX_CHIPS		(2)
#define TTL74181_INPUT_TOTAL	(14)
#define TTL74181_OUTPUT_TOTAL	(8)



typedef struct _TTL74181_state TTL74181_state;
struct _TTL74181_state
{
	UINT8 inputs[TTL74181_INPUT_TOTAL];
	UINT8 outputs[TTL74181_OUTPUT_TOTAL];
	UINT8 dirty;
};

static TTL74181_state chips[TTL74181_MAX_CHIPS];


void TTL74181_config(running_machine *machine, int which, void *intf)
{
	TTL74181_state *c;

	assert_always(mame_get_phase(machine) == MAME_PHASE_INIT, "Can only call at init time!");
	assert_always(intf == 0, "Interface must be NULL");
	assert_always((which >= 0) && (which < TTL74181_MAX_CHIPS), "Exceeded maximum number of 74181 chips");

	c = &chips[which];

	c->dirty = 1;

	state_save_register_item_array(machine, "TTL74181", NULL, which, c->inputs);
	state_save_register_item_array(machine, "TTL74181", NULL, which, c->outputs);
	state_save_register_item      (machine, "TTL74181", NULL, which, c->dirty);
}


void TTL74181_reset(int which)
{
	/* nothing to do */
}


static void TTL74181_update(int which)
{
	TTL74181_state *c = &chips[which];

	UINT8 a0 =  c->inputs[TTL74181_INPUT_A0];
	UINT8 a1 =  c->inputs[TTL74181_INPUT_A1];
	UINT8 a2 =  c->inputs[TTL74181_INPUT_A2];
	UINT8 a3 =  c->inputs[TTL74181_INPUT_A3];

	UINT8 b0 =  c->inputs[TTL74181_INPUT_B0];
	UINT8 b1 =  c->inputs[TTL74181_INPUT_B1];
	UINT8 b2 =  c->inputs[TTL74181_INPUT_B2];
	UINT8 b3 =  c->inputs[TTL74181_INPUT_B3];

	UINT8 s0 =  c->inputs[TTL74181_INPUT_S0];
	UINT8 s1 =  c->inputs[TTL74181_INPUT_S1];
	UINT8 s2 =  c->inputs[TTL74181_INPUT_S2];
	UINT8 s3 =  c->inputs[TTL74181_INPUT_S3];

	UINT8 cp =  c->inputs[TTL74181_INPUT_C];
	UINT8 mp = !c->inputs[TTL74181_INPUT_M];

	UINT8 ap0 = !(a0 | (b0 & s0) | (s1 & !b0));
	UINT8 bp0 = !(((!b0) & s2 & a0) | (a0 & b0 & s3));
	UINT8 ap1 = !(a1 | (b1 & s0) | (s1 & !b1));
	UINT8 bp1 = !(((!b1) & s2 & a1) | (a1 & b1 & s3));
	UINT8 ap2 = !(a2 | (b2 & s0) | (s1 & !b2));
	UINT8 bp2 = !(((!b2) & s2 & a2) | (a2 & b2 & s3));
	UINT8 ap3 = !(a3 | (b3 & s0) | (s1 & !b3));
	UINT8 bp3 = !(((!b3) & s2 & a3) | (a3 & b3 & s3));

	UINT8 fp0 = !(cp & mp) ^ ((!ap0) & bp0);
	UINT8 fp1 = (!((mp & ap0) | (mp & bp0 & cp))) ^ ((!ap1) & bp1);
	UINT8 fp2 = (!((mp & ap1) | (mp & ap0 & bp1) | (mp & cp & bp0 & bp1))) ^ ((!ap2) & bp2);
	UINT8 fp3 = (!((mp & ap2) | (mp & ap1 & bp2) | (mp & ap0 & bp1 & bp2) | (mp & cp & bp0 & bp1 & bp2))) ^ ((!ap3) & bp3);

	UINT8 aeqb = fp0 & fp1 & fp2 & fp3;
	UINT8 pp = !(bp0 & bp1 & bp2 & bp3);
	UINT8 gp = !((ap0 & bp1 & bp2 & bp3) | (ap1 & bp2 & bp3) | (ap2 & bp3) | ap3);
	UINT8 cn4 = (!(cp & bp0 & bp1 & bp2 & bp3)) | gp;

	c->outputs[TTL74181_OUTPUT_F0]   = fp0;
	c->outputs[TTL74181_OUTPUT_F1]   = fp1;
	c->outputs[TTL74181_OUTPUT_F2]   = fp2;
	c->outputs[TTL74181_OUTPUT_F3]   = fp3;
	c->outputs[TTL74181_OUTPUT_AEQB] = aeqb;
	c->outputs[TTL74181_OUTPUT_P]    = pp;
	c->outputs[TTL74181_OUTPUT_G]    = gp;
	c->outputs[TTL74181_OUTPUT_CN4]  = cn4;
}


void TTL74181_write(int which, int startline, int lines, UINT8 data)
{
	int line;
	TTL74181_state *c;

	assert_always((which >= 0) && (which < TTL74181_MAX_CHIPS), "Chip index out of range");

	c = &chips[which];

	assert_always(c != NULL, "Invalid index - chip has not been configured");
	assert_always(lines >= 1, "Must set at least one line");
	assert_always(lines <= 4, "Can't set more than 4 lines at once");
	assert_always((startline + lines) <= TTL74181_INPUT_TOTAL, "Input line index out of range");

	for (line = 0; line < lines; line++)
	{
		UINT8 input = (data >> line) & 0x01;

		if (c->inputs[startline + line] != input)
		{
			c->inputs[startline + line] = input;

			c->dirty = 1;
		}
	}
}


UINT8 TTL74181_read(int which, int startline, int lines)
{
	int line;
	UINT8 data;
	TTL74181_state *c;

	assert_always((which >= 0) && (which < TTL74181_MAX_CHIPS), "Chip index out of range");

	c = &chips[which];

	assert_always(c != NULL, "Invalid index - chip has not been configured");
	assert_always(lines >= 1, "Must read at least one line");
	assert_always(lines <= 4, "Can't read more than 4 lines at once");
	assert_always((startline + lines) <= TTL74181_OUTPUT_TOTAL, "Output line index out of range");

	if (c->dirty)
	{
		TTL74181_update(which);

		c->dirty = 0;
	}


	data = 0;

	for (line = 0; line < lines; line++)
	{
		data = data | (c->outputs[startline + line] << line);
	}

	return data;
}