summaryrefslogtreecommitdiffstats
path: root/src/devices/bus/ti99/internal/datamux.h
blob: 7269527933296e375620ab7950bc98d84d135489 (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
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************

    TI-99/4(A) databus multiplexer circuit
    See datamux.c for documentation

    Michael Zapf

    February 2012: Rewritten as class

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

#ifndef MAME_BUS_TI99_INTERNAL_DATAMUX_H
#define MAME_BUS_TI99_INTERNAL_DATAMUX_H

#pragma once

#include "bus/ti99/ti99defs.h"
#include "machine/tmc0430.h"
#include "bus/ti99/gromport/gromport.h"
#include "bus/ti99/internal/ioport.h"
#include "sound/sn76496.h"
#include "video/tms9928a.h"
#include "machine/ram.h"

namespace bus { namespace ti99 { namespace internal {

/*
    Main class
*/
class datamux_device : public device_t
{
public:
	datamux_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	DECLARE_READ16_MEMBER( read );
	DECLARE_WRITE16_MEMBER( write );
	DECLARE_READ8_MEMBER( setoffset );

	DECLARE_WRITE_LINE_MEMBER( clock_in );
	DECLARE_WRITE_LINE_MEMBER( dbin_in );
	DECLARE_WRITE_LINE_MEMBER( ready_line );

	DECLARE_WRITE_LINE_MEMBER( gromclk_in );

	template <class Object> devcb_base &set_ready_callback(Object &&cb) { return m_ready.set_callback(std::forward<Object>(cb)); }

protected:
	/* Constructor */
	void device_start() override;
	void device_stop() override;
	void device_reset() override;
	void device_config_complete() override;
	ioport_constructor device_input_ports() const override;

private:
	// Link to the video processor
	optional_device<tms9928a_device> m_video;

	// Link to the sound processor
	optional_device<sn76496_base_device> m_sound;

	// Link to the I/O port
	required_device<bus::ti99::internal::ioport_device> m_ioport;

	// Link to the cartridge port (aka GROM port)
	required_device<bus::ti99::gromport::gromport_device> m_gromport;

	// Memory expansion (internal, 16 bit)
	required_device<ram_device> m_ram16b;

	// Console RAM
	required_device<ram_device> m_padram;

	// Link to the CPU
	required_device<cpu_device> m_cpu;

	// Keeps the address space pointer
	address_space* m_spacep;

	// Console ROM
	uint16_t* m_consolerom;

	// Console GROMs
	tmc0430_device* m_grom[3];

	// Common read routine
	void read_all(address_space& space, uint16_t addr, uint8_t *target);

	// Common write routine
	void write_all(address_space& space, uint16_t addr, uint8_t value);

	// Common set address method
	void setaddress_all(address_space& space, uint16_t addr);

	// Debugger access
	uint16_t debugger_read(address_space& space, uint16_t addr);
	void debugger_write(address_space& space, uint16_t addr, uint16_t data);

	// Join own READY and external READY
	void ready_join();

	// Ready line to the CPU
	devcb_write_line m_ready;

	// Address latch (emu). In reality, the address bus remains constant.
	uint16_t m_addr_buf;

	// DBIN line
	int m_dbin;

	// Own ready state.
	int  m_muxready;

	// Ready state. Needed to control wait state generation via inbound READY
	int  m_sysready;

	// Latch which stores the first (odd) byte
	uint8_t m_latch;

	// Counter for the wait states.
	int   m_waitcount;

	// Keep the state of the ROMG* and MEMEN* lines so that debugger does not mess up things
	line_state m_romgq_state;
	line_state m_memen_state;

	// Use the memory expansion?
	bool m_use32k;

	// Memory base for piggy-back 32K expansion. If 0, expansion is not used.
	uint16_t  m_base32k;

	// Console GROMs are available (the HSGPL expects them to be removed)
	bool m_console_groms_present;

	// GROMs are idle, no need to propagate the clock
	bool m_grom_idle;
};

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

#define MCFG_DMUX_READY_HANDLER( _intcallb ) \
	downcast<bus::ti99::internal::datamux_device &>(*device).set_ready_callback(DEVCB_##_intcallb);

} } } // end namespace bus::ti99::internal

DECLARE_DEVICE_TYPE_NS(TI99_DATAMUX, bus::ti99::internal, datamux_device)

#endif // MAME_BUS_TI99_INTERNAL_DATAMUX_H