summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/bbc/1mhzbus/1mhzbus.h
blob: d2d3a3c6765e89daf06063fb83d1cc020c4b2964 (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
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************

    BBC 1MHz Bus emulation

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

  Pinout:

             0V   1   2  R/W
             0V   3   4  1MHzE
             0V   5   6  NNMI
             0V   7   8  NIRQ
             0V   9  10  NPGFC
             0V  11  12  NPGFD
             0V  13  14  NRST
             0V  15  16  Analog In
             0V  17  18  D0
             D1  19  20  D2
             D3  21  22  D4
             D5  23  24  D6
             D7  25  26  0V
             A0  27  28  A1
             A2  29  30  A3
             A4  31  32  A5
             A6  33  34  A7

  Signal Definitions:

              0 volts - This is connected to the main system 0 volts line. The reason for putting
                        0V lines between the active signal lines is to reduce the interference
                        between different signals.
          R/W (pin 2) - This is the read-not-write signal from the 6502 CPU, buffered by two
                        74LS04 inverters.
        1MHzE (pin 4) - This is the 1MHz system timing clock. It is a 50% duty-cycle square wave.
                        The 6502 CPU is operating at 2MHz, so the main processor clock is stretched
                        whenever 1MHz bus peripherals are being accessed. The trailing edges of the
                        1MHz and 2MHz processor clock are then coincidental. The processor clock
                        is only ever truly 2MHz when accessing main memory.
         NNMI (pin 6) - Not Non-Maskable Interrupt. This is connected directly to the 6502 NMI input.
                        It is pulled up to +5 volts with a 3K3 resistor. Both Disc and Econet systems
                        rely heavily upon NMIs for their operation so take care. Note that NMIs are
                        triggered on negative going edges of NMI signals.
         NIRQ (pin 8) - Not Interrupt Request. This is connected directly to the 6502 IRQ input. Any
                        devices connected to this input should have open collector outputs. The line
                        is pulled up to +5 volts with a 3K3 resistor. Interrupts from the 1MHz bus
                        must not occur until the software on the main system is able to cope with
                        them. All interrupts must therefore be disabled after a reset. Note that the
                        main system software may operate very slowly if considerable use is made of
                        interrupts. Certain functions such as the real time clock which is
                        incremented every 10 mS will be affected if interrupts are masked for more
                        than this period.
       NPGFC (pin 10) - Not page &FC. This signal is derived from the 6502 address bus. It goes low
                        whenever page &FC is written to or read from. FRED is the name given to this
                        page in memory.
      NPGGFD (pin 12) - Not page &FD. This signal is derived from the 6502 address bus. It goes low
                        whenever page &FD is accessed. JIM is the name given to this page in memory.
        NRST (pin 14) - Not RESET. This is an active low output from the system reset line. It may
                        be used to initialise peripherals whenever a power up or a BREAK causes a
                        reset.
   Analog In (pin 16) - This is an input to the audio amplifier on the main computer. The amplified
                        signal is produced over the speaker on the keyboard. Its input impedance is
                        9K Ohms and a 3 volt RMS signal will produce maximum volume on the speaker.
                        Note however that signals as large as this will cause distortion if the sound
                        or speech is used at the same time.
   D0-D7 (pins 18-24) - This is a bi-directional 8 bit data bus which is connected via a 74LS245
                        buffer (IC72) to the CPU. The direction of data transfer is determined by
                        the R/W line signal. The buffer is enabled whenever FRED or JIM are accessed.
   A0-A7 (pins 27-34) - These are connected directly to the lower 8 CPU address lines via a 74LS244
                        buffer (IC71) which is always enabled.

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

#ifndef MAME_BUS_BBC_1MHZBUS_1MHZBUS_H
#define MAME_BUS_BBC_1MHZBUS_1MHZBUS_H

#pragma once



//**************************************************************************
//  CONSTANTS
//**************************************************************************

#define BBC_1MHZBUS_SLOT_TAG      "1mhzbus"


//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_BBC_1MHZBUS_SLOT_ADD(_tag, _slot_intf, _def_slot) \
	MCFG_DEVICE_ADD(_tag, BBC_1MHZBUS_SLOT, 0) \
	MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)

#define MCFG_BBC_PASSTHRU_1MHZBUS_SLOT_ADD() \
	MCFG_BBC_1MHZBUS_SLOT_ADD(BBC_1MHZBUS_SLOT_TAG, bbc_1mhzbus_devices, nullptr) \
	MCFG_BBC_1MHZBUS_SLOT_IRQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, bbc_1mhzbus_slot_device, irq_w)) \
	MCFG_BBC_1MHZBUS_SLOT_NMI_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, bbc_1mhzbus_slot_device, nmi_w))

#define MCFG_BBC_1MHZBUS_SLOT_IRQ_HANDLER(_devcb) \
	devcb = &bbc_1mhzbus_slot_device::set_irq_handler(*device, DEVCB_##_devcb);

#define MCFG_BBC_1MHZBUS_SLOT_NMI_HANDLER(_devcb) \
	devcb = &bbc_1mhzbus_slot_device::set_nmi_handler(*device, DEVCB_##_devcb);


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> bbc_1mhzbus_slot_device

class device_bbc_1mhzbus_interface;

class bbc_1mhzbus_slot_device : public device_t, public device_slot_interface
{
public:
	// construction/destruction
	bbc_1mhzbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	virtual ~bbc_1mhzbus_slot_device();

	// callbacks
	template <class Object> static devcb_base &set_irq_handler(device_t &device, Object &&cb)
	{ return downcast<bbc_1mhzbus_slot_device &>(device).m_irq_handler.set_callback(std::forward<Object>(cb)); }

	template <class Object> static devcb_base &set_nmi_handler(device_t &device, Object &&cb)
	{ return downcast<bbc_1mhzbus_slot_device &>(device).m_nmi_handler.set_callback(std::forward<Object>(cb)); }

	DECLARE_WRITE_LINE_MEMBER( rst_w );
	DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
	DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }

protected:
	// device-level overrides
	virtual void device_validity_check(validity_checker &valid) const override;
	virtual void device_start() override;
	virtual void device_reset() override;

	device_bbc_1mhzbus_interface *m_card;

private:
	devcb_write_line m_irq_handler;
	devcb_write_line m_nmi_handler;
};


// ======================> device_bbc_1mhzbus_interface

class device_bbc_1mhzbus_interface : public device_slot_card_interface
{
public:
	// construction/destruction
	virtual ~device_bbc_1mhzbus_interface();

	virtual DECLARE_WRITE_LINE_MEMBER(rst_w) { }

protected:
	device_bbc_1mhzbus_interface(const machine_config &mconfig, device_t &device);

	bbc_1mhzbus_slot_device *m_slot;
};


// device type definition
DECLARE_DEVICE_TYPE(BBC_1MHZBUS_SLOT, bbc_1mhzbus_slot_device)

SLOT_INTERFACE_EXTERN( bbc_1mhzbus_devices );


#endif // MAME_BUS_BBC_1MHZBUS_1MHZBUS_H