summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/8364_paula.h
blob: 4dbd041c93f5c5c2ed4b7fcb7f711e7c548d55bf (plain) (tree)
1
2

                                            
































                                                                            
                                   







                                                                            


                                                                            










                                                                                










                                                                                                           









                                                                                                       
                      








                                                                                                                                          








































                                                                        











                                            






                                                                



                                             



                                 
                         


                          









                                            
// license: BSD-3-Clause
// copyright-holders: Aaron Giles, Dirk Best
/***************************************************************************

    Commodore 8364 "Paula"

    Multi-purpose chip that is part of the Amiga chipset. The name "Paula"
    is derived from "Ports, Audio, UART and Logic". It features 4-channel
    DMA driven audio, the floppy controller, a serial receiver/transmitter,
    analog inputs and contains the interrupt controller.

                ____ ____
        D8   1 |*   u    | 48  D9
        D7   2 |         | 47  D10
        D6   3 |         | 46  D11
        D5   4 |         | 45  D12
        D4   5 |         | 44  D13
        D3   6 |         | 43  D14
        D2   7 |         | 42  D15
       GND   8 |         | 41  RXD
        D1   9 |         | 40  TXD
        D0  10 |         | 39  DKWE
      /RES  11 |         | 38  /DKWD
      DMAL  12 |         | 37  /DKRD
     /IPL0  13 |         | 36  POT1Y
     /IPL1  14 |         | 35  POT1X
     /IPL2  15 |         | 34  ANAGND
     /INT2  16 |         | 33  POT0Y
     /INT3  17 |         | 32  POT0X
     /INT6  18 |         | 31  AUDL
      RGA8  19 |         | 30  AUDR
      RGA7  20 |         | 29  CCKQ
      RGA6  21 |         | 28  CCK
      RGA5  22 |         | 27  VCC
      RGA4  23 |         | 26  RGA1
      RGA3  24 |_________| 25  RGA2

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

#pragma once

#ifndef MAME_DEVICES_MACHINE_8364_PAULA_H
#define MAME_DEVICES_MACHINE_8364_PAULA_H



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

#define MCFG_PAULA_MEM_READ_CB(_devcb) \
	devcb = &paula_8364_device::set_mem_r_callback(*device, DEVCB_##_devcb);

#define MCFG_PAULA_INT_CB(_devcb) \
	devcb = &paula_8364_device::set_int_w_callback(*device, DEVCB_##_devcb);


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

// ======================> paula_8364_device

class paula_8364_device : public device_t, public device_sound_interface
{
public:
	paula_8364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	~paula_8364_device() {}

	// configuration
	template<class _Object> static devcb_base &set_mem_r_callback(device_t &device, _Object object)
		{ return downcast<paula_8364_device &>(device).m_mem_r.set_callback(object); }

	template<class _Object> static devcb_base &set_int_w_callback(device_t &device, _Object object)
		{ return downcast<paula_8364_device &>(device).m_int_w.set_callback(object); }

	DECLARE_READ16_MEMBER(reg_r);
	DECLARE_WRITE16_MEMBER(reg_w);

	void update();

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
	{
		CHAN_0 = 0,
		CHAN_1 = 1,
		CHAN_2 = 2,
		CHAN_3 = 3
	};

	enum
	{
		REG_DMACONR = 0x02/2,
		REG_ADKCONR = 0x10/2,
		REG_DMACON  = 0x96/2,
		REG_INTREQ  = 0x9c/2,
		REG_ADKCON  = 0x9e/2,
		REG_AUD0LCH = 0xa0/2,  // to be moved, not part of paula
		REG_AUD0LCL = 0xa2/2,  // to be moved, not part of paula
		REG_AUD0LEN = 0xa4/2,
		REG_AUD0PER = 0xa6/2,
		REG_AUD0VOL = 0xa8/2,
		REG_AUD0DAT = 0xaa/2,
		REG_AUD1LCH = 0xb0/2,  // to be moved, not part of paula
		REG_AUD1LCL = 0xb2/2,  // to be moved, not part of paula
		REG_AUD1LEN = 0xb4/2,
		REG_AUD1PER = 0xb6/2,
		REG_AUD1VOL = 0xb8/2,
		REG_AUD1DAT = 0xba/2,
		REG_AUD2LCH = 0xc0/2,  // to be moved, not part of paula
		REG_AUD2LCL = 0xc2/2,  // to be moved, not part of paula
		REG_AUD2LEN = 0xc4/2,
		REG_AUD2PER = 0xc6/2,
		REG_AUD2VOL = 0xc8/2,
		REG_AUD2DAT = 0xca/2,
		REG_AUD3LCH = 0xd0/2,  // to be moved, not part of paula
		REG_AUD3LCL = 0xd2/2,  // to be moved, not part of paula
		REG_AUD3LEN = 0xd4/2,
		REG_AUD3PER = 0xd6/2,
		REG_AUD3VOL = 0xd8/2,
		REG_AUD3DAT = 0xda/2
	};

	static const int CLOCK_DIVIDER = 16;

	struct audio_channel
	{
		emu_timer *irq_timer;
		uint32_t curlocation;
		uint16_t curlength;
		uint16_t curticks;
		uint8_t index;
		bool dma_enabled;
		bool manualmode;
		int8_t latched;

		// custom chip registers
		uint32_t loc;  // to be moved, not part of paula
		uint16_t len;
		uint16_t per;
		uint16_t vol;
		uint16_t dat;
	};

	void dma_reload(audio_channel *chan);

	// callbacks
	devcb_read16 m_mem_r;
	devcb_write_line m_int_w;

	// internal state
	uint16_t m_dmacon;
	uint16_t m_adkcon;

	audio_channel m_channel[4];
	sound_stream *m_stream;

	TIMER_CALLBACK_MEMBER( signal_irq );
};

// device type definition
extern const device_type PAULA_8364;

#endif // MAME_DEVICES_MACHINE_8364_PAULA_H