summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/kc/kc.cpp
blob: 99da30bb188a1d1ceadacb2ca5fb1594076cc391 (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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/*********************************************************************

    kc.c

    KC85_2/3/4/5 expansion slot emulation

**********************************************************************

        GND          1      30          GND
        GND          2      31          GND
        NC           3      32          NC
        DB7          4      33          DB6
        DB5          5      34          DB4
        DB3          6      35          DB2
        DB1          7      36          DB0
        /WR          8      37          /RD
        /WREQ        9      38          /IORQ
        IEO         10      39          NC
        AB14        11      40          AB15
        AB12        12      41          AB13
        AB10        13      42          AB11
        AB8         14      43          AB9
        /WAIT       15      44          /RFSH
        AB6         16      45          AB7
        AB4         17      46          AB5
        AB2         18      47          AB3
        AB0         19      48          AB1
        /RESET      20      49          /BUSRQ
        TATK        21      50          GND
        /M1         22      51          /HALT
        /NMI        23      52          /INT
        MEO         24      53          MEI
        /ZI         25      54          /BI
        /NC         26      55          /HELL
        /BUSAK      27      56          NC
        VCC         28      57          NC
        NC          29      58          NC

    Slots are organized into a chain (MEI -> MEO) , the first module that
    decode the address on bus, clear the MEO line for disable other modules
    with less priority.

************************************************************************

    Known KC85 modules

    Name    ID     Control     Emulated   Description

    M001    EF    ---- ---M       no      Digital IN/OUT
    M002    DA    ---- ---M       no      PIO 3
    M003    EE    ---- ---M       no      V.24
    M005          ---- ----       no      User
    M006    FC    AA-- ---M       yes     BASIC for KC85/2 (16KB ROM)
    M007          ---- ----       no      Adapter
    M008          ---- ----       no      Joystick
    M009    ED    ---- ---M       no      TLCM Spracheingabe/Datenkompr
    M010    E7    ---- ---M       no      ADU 1 (4 analog inputs)
    M011    F6    AA-- --WM       yes     64KB RAM
    M012    FB    AAA- ---M       yes     Texor (8KB ROM)
    M021          ---- ----       no      Joystick + Centronics
    M022    F4    AA-- --WM       yes     16KB RAM
    M024    F5    AA-- --WM       no      32KB RAM
    M025    F7    AAA- ---M       no      User PROM 8KB
    M026    FB    AAA- ---M       yes     FORTH (8KB ROM)
    M027    FB    AAA- ---M       yes     Development (8KB ROM)
    M028    FB    AA-- ---M       no      16KB EPROM(2x U2764)
    M029    E3    ---- ---M       no      DAU 1 (2 analog outputs)
    M030    DB    AAA- ---M       no      EPROMER 8KB EPROM
    M032    79    A-SS SSWM       yes     256KB segmented RAM (16 segments of 16KB)
    M033    01    AA0S ---M       yes     Typestar (8KB x 2 ROM)
    M034    7A    ASSS SSWM       yes     512KB segmented RAM (32 segments of 16KB)
    M035    7B    SSSS SSWM       yes     1MB segmented RAM (64 segments of 16KB)
    M036    78    A--S SSWM       yes     128KB segmented RAM (8 segments of 16KB)
    M040    F8    AA-- ---M       no      User PROM 8/16KB
    M045    70    AASS ---M       no      User 32KB segmented ROM (4 segments of 8KB)
    M046    71    AASS -S-M       no      User 64KB segmented ROM (8 segments of 8KB)
    M047    72    AASS SS-M       no      User 128KB segmented ROM (16 segments of 8KB)
    M048    73    SSSS SS-M       no      User 256KB segmented ROM (16 segments of 16KB)
    M051    EC    ---- ----       no      Scanner Module
    M052    FD    ---- ----       no      USB + NET (TCP/IP)
    M053    EE    ---- ---M       no      RS-232
    M061          ---- ----       no      3x E/A-Modul
    M120    F0    AAA- --WM       no      8KB CMOS-RAM
    M122    F1    AA-- --WM       no      16KB CMOS-RAM
    M124    F2    AA-- --WM       no      32KB CMOS-RAM

    D001          ---- ----       yes     Basis Device
    D002          ---- ----       yes     Bus driver expansion
    D003          ---- ----       no      PROM programmer for KC-PROM Module
    D004    A7    --A- -K-M       yes     Floppy Disk Interface
    D005          ---- ----       no      Komfort-Tastatur for KC85/4


    Control byte                  ID byte
    A - Base Address              01    - Autostart modules
    K - Power on/off              7x    - Segmented memory
    S - Active segment            Dx/Ex - IN/OUT modules
    W - Write enabled             Fx    - memory modules
    M - Module enabled

    Info taken from: http://www.mpm-kc85.de/html/ModulListe.htm

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

#include "emu.h"
#include "kc.h"

#define  LOG    0


/***************************************************************************
    PARAMETERS
***************************************************************************/

//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

DEFINE_DEVICE_TYPE(KCEXP_SLOT,  kcexp_slot_device,  "kcexp_slot",  "KC85 Expansion Slot")
DEFINE_DEVICE_TYPE(KCCART_SLOT, kccart_slot_device, "kccart_slot", "KC85 Cartridge Slot")


//**************************************************************************
//    KC85 Expansion Interface
//**************************************************************************

//-------------------------------------------------
//  device_kcexp_interface - constructor
//-------------------------------------------------

device_kcexp_interface::device_kcexp_interface(const machine_config &mconfig, device_t &device)
	: device_slot_card_interface(mconfig, device)
{
}


//-------------------------------------------------
//  ~device_kcexp_interface - destructor
//-------------------------------------------------

device_kcexp_interface::~device_kcexp_interface()
{
}


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  kcexp_slot_device - constructor
//-------------------------------------------------
kcexp_slot_device::kcexp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	kcexp_slot_device(mconfig, KCEXP_SLOT, tag, owner, clock)
{
}

kcexp_slot_device::kcexp_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
	device_t(mconfig, type, tag, owner, clock),
	device_slot_interface(mconfig, *this),
	m_out_irq_cb(*this),
	m_out_nmi_cb(*this),
	m_out_halt_cb(*this),
	m_cart(nullptr), m_next_slot_tag(nullptr), m_next_slot(nullptr)
{
}

void kcexp_slot_device::static_set_next_slot(device_t &device, const char *next_slot_tag)
{
	kcexp_slot_device &kc_slot = dynamic_cast<kcexp_slot_device &>(device);

	kc_slot.m_next_slot_tag = next_slot_tag;
}

//-------------------------------------------------
//  kcexp_slot_device - destructor
//-------------------------------------------------

kcexp_slot_device::~kcexp_slot_device()
{
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void kcexp_slot_device::device_start()
{
	m_cart = dynamic_cast<device_kcexp_interface *>(get_card_device());
	m_next_slot = m_next_slot_tag ? owner()->subdevice<kcexp_slot_device>(m_next_slot_tag) : nullptr;

	// resolve callbacks
	m_out_irq_cb.resolve_safe();
	m_out_nmi_cb.resolve_safe();
	m_out_halt_cb.resolve_safe();
}


/*-------------------------------------------------
    module id read
-------------------------------------------------*/

uint8_t kcexp_slot_device::module_id_r()
{
	uint8_t result = 0xff;

	if (m_cart)
		result = m_cart->module_id_r();

	return result;
}

/*-------------------------------------------------
    module control write
-------------------------------------------------*/
void kcexp_slot_device::control_w(uint8_t data)
{
	if (m_cart)
		m_cart->control_w(data);
}

/*-------------------------------------------------
    read
-------------------------------------------------*/

void kcexp_slot_device::read(offs_t offset, uint8_t &data)
{
	if (m_cart)
		m_cart->read(offset, data);
}


/*-------------------------------------------------
    write
-------------------------------------------------*/

void kcexp_slot_device::write(offs_t offset, uint8_t data)
{
	if (m_cart)
		m_cart->write(offset, data);
}

/*-------------------------------------------------
    IO read
-------------------------------------------------*/

void kcexp_slot_device::io_read(offs_t offset, uint8_t &data)
{
	if (m_cart)
		m_cart->io_read(offset, data);
}


/*-------------------------------------------------
   IO write
-------------------------------------------------*/

void kcexp_slot_device::io_write(offs_t offset, uint8_t data)
{
	if (m_cart)
		m_cart->io_write(offset, data);
}

/*-------------------------------------------------
   MEI line write
-------------------------------------------------*/

WRITE_LINE_MEMBER( kcexp_slot_device::mei_w )
{
	if (LOG) logerror("KCEXP '%s': %s MEI line\n", tag(), state != CLEAR_LINE ? "ASSERT": "CLEAR");

	if (m_cart)
		m_cart->mei_w(state);
}

/*-------------------------------------------------
   MEO line write
-------------------------------------------------*/

WRITE_LINE_MEMBER( kcexp_slot_device::meo_w )
{
	if (LOG) logerror("KCEXP '%s': %s MEO line\n", tag(), state != CLEAR_LINE ? "ASSERT": "CLEAR");

	if (m_next_slot)
		m_next_slot->mei_w(state);
}


//**************************************************************************
//     KC85 Cartridges Interface
//**************************************************************************

//-------------------------------------------------
//  kccart_slot_device - constructor
//-------------------------------------------------
kccart_slot_device::kccart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	kcexp_slot_device(mconfig, KCCART_SLOT, tag, owner, clock),
	device_image_interface(mconfig, *this)
{
}

//-------------------------------------------------
//  kccart_slot_device - destructor
//-------------------------------------------------

kccart_slot_device::~kccart_slot_device()
{
}

/*-------------------------------------------------
    call load
-------------------------------------------------*/

image_init_result kccart_slot_device::call_load()
{
	if (m_cart)
	{
		offs_t read_length;
		uint8_t *cart_base = m_cart->get_cart_base();

		if (cart_base != nullptr)
		{
			if (!loaded_through_softlist())
			{
				read_length = length();
				fread(m_cart->get_cart_base(), read_length);
			}
			else
			{
				read_length = get_software_region_length("rom");
				memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length);
			}
		}
		else
			return image_init_result::FAIL;
	}

	return image_init_result::PASS;
}

/*-------------------------------------------------
    get default card software
-------------------------------------------------*/

std::string kccart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
	return software_get_default_slot("standard");
}