summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/hng64_net.cpp
blob: 8908b933fe59f4a03a6f7ca9a8bd78882e4ef925 (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
// license:LGPL-2.1+
// copyright-holders:David Haywood, Angelo Salese, ElSemi, Andrew Gardner
/* HNG64 Communication / Network CPU */

// this is driven by a KL5C80A12CFP which is basically a super-charged Z80
// most of this MMU handling etc. should be moved to the core.

// I believe this CPU is used for network only (the racing games) and not related to the I/O MCU

/*
0x6010: tests RAM at [3]8000

*/

#include "emu.h"
#include "includes/hng64.h"
#include "cpu/z80/kl5c80a12.h"

uint8_t hng64_state::read_comm_data(uint32_t offset)
{
	if((offset & 0x10000) == 0)
		return m_comm_rom[offset & 0xffff];

	if(offset & 0x10000)
		return m_comm_ram[(offset & 0xffff)];

	printf("%08x\n",offset);
	return 0xff;
}

void hng64_state::write_comm_data(uint32_t offset,uint8_t data)
{
	if((offset & 0x10000) == 0)
	{
		//m_comm_rom[offset];
		return;
	}
	if(offset & 0x10000)
	{
		m_comm_ram[offset & 0xffff] = data;
		return;
	}


	printf("%08x %02x\n",offset,data);

}

READ8_MEMBER(hng64_state::hng64_comm_space_r)
{
	if((offset & 0xfc00) == 0) // B0 is fixed at 0-0x3ff
		return m_comm_rom[offset];

	for(int i=0;i<5;i++)
	{
		if(offset >= m_mmub[i] && offset <= m_mmub[i+1]-1)
			return read_comm_data(m_mmua[i]|offset);
	}

	return 0xff;
}

WRITE8_MEMBER(hng64_state::hng64_comm_space_w)
{
	if((offset & 0xfc00) == 0) // B0 is fixed at 0-0x3ff
		return;// m_comm_rom[offset];

	for(int i=0;i<5;i++)
	{
		if(offset >= m_mmub[i] && offset <= m_mmub[i+1]-1)
		{
			write_comm_data(m_mmua[i]|offset,data);
			return;
		}
	}
}

READ8_MEMBER(hng64_state::hng64_comm_mmu_r)
{
	return m_mmu_regs[offset];
}

#define MMUA (m_mmu_regs[(offset&~1)+0]>>6)|(m_mmu_regs[(offset&~1)+1]<<2)
#define MMUB (m_mmu_regs[(offset&~1)+0]&0x3f)

WRITE8_MEMBER(hng64_state::hng64_comm_mmu_w)
{
	m_mmu_regs[offset] = data;

	/* cheap: avoid to overwrite read only params*/
	if((offset & 6) == 6)
	{
		m_mmu_regs[6] = m_mmu_regs[6] & 0x3f;
		m_mmu_regs[7] = 0xf0;

	}

	{
		m_mmua[offset/2+1] = (m_mmu_regs[(offset&~1)+0]>>6)|(m_mmu_regs[(offset&~1)+1]<<2);
		m_mmua[offset/2+1]*= 0x400;
		m_mmub[offset/2+1] = (m_mmu_regs[(offset&~1)+0]&0x3f);
		m_mmub[offset/2+1]++;
		m_mmub[offset/2+1]*= 0x400;
		//printf("%d A %08x B %04x\n",offset/2,m_mmua[offset/2],m_mmub[offset/2]);
		//printf("A %04x B %02x\n",MMUA,MMUB);
	}
}

void hng64_state::hng_comm_map(address_map &map)
{
	map(0x0000, 0xffff).rw(this, FUNC(hng64_state::hng64_comm_space_r), FUNC(hng64_state::hng64_comm_space_w));
}

void hng64_state::hng_comm_io_map(address_map &map)
{
	map.global_mask(0xff);
	/* Reserved for the KL5C80 internal hardware */
	map(0x00, 0x07).rw(this, FUNC(hng64_state::hng64_comm_mmu_r), FUNC(hng64_state::hng64_comm_mmu_w));
//  AM_RANGE(0x08,0x1f) AM_NOP              /* Reserved */
//  AM_RANGE(0x20,0x25) AM_READWRITE        /* Timer/Counter B */           /* hng64 writes here */
//  AM_RANGE(0x27,0x27) AM_NOP              /* Reserved */
//  AM_RANGE(0x28,0x2b) AM_READWRITE        /* Timer/Counter A */           /* hng64 writes here */
//  AM_RANGE(0x2c,0x2f) AM_READWRITE        /* Parallel port A */
//  AM_RANGE(0x30,0x33) AM_READWRITE        /* Parallel port B */
//  AM_RANGE(0x34,0x37) AM_READWRITE        /* Interrupt controller */      /* hng64 writes here */
//  AM_RANGE(0x38,0x39) AM_READWRITE        /* Serial port */               /* hng64 writes here */
//  AM_RANGE(0x3a,0x3b) AM_READWRITE        /* System control register */   /* hng64 writes here */
//  AM_RANGE(0x3c,0x3f) AM_NOP              /* Reserved */

	/* General IO */
	map(0x50, 0x57).rw(this, FUNC(hng64_state::hng64_com_share_r), FUNC(hng64_state::hng64_com_share_w));
//  AM_RANGE(0x72,0x72) AM_WRITE            /* dunno yet */
}


void hng64_state::reset_net()
{
//  m_comm->pulse_input_line(INPUT_LINE_NMI, attotime::zero); // reset the CPU and let 'er rip
//  m_comm->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);     // hold on there pardner...

	m_mmub[0] = 0;
	m_mmub[5] = 0; // rolls back to 0xffff
}

MACHINE_CONFIG_START(hng64_state::hng64_network)
	MCFG_DEVICE_ADD("network", KL5C80A12, HNG64_MASTER_CLOCK / 4)        /* KL5C80A12CFP - binary compatible with Z80. */
	MCFG_DEVICE_PROGRAM_MAP(hng_comm_map)
	MCFG_DEVICE_IO_MAP(hng_comm_io_map)
MACHINE_CONFIG_END