1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 
4 
5 #include "emu.h"
6 #include "cedar_magnet_plane.h"
7 
8 
9 DEFINE_DEVICE_TYPE(CEDAR_MAGNET_PLANE, cedar_magnet_plane_device, "cedmag_plane", "Cedar Plane")
10 
11 
cedar_magnet_plane_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)12 cedar_magnet_plane_device::cedar_magnet_plane_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
13 	: device_t(mconfig, CEDAR_MAGNET_PLANE, tag, owner, clock)
14 	, cedar_magnet_board_interface(mconfig, *this, "planecpu", "ram")
15 {
16 }
17 
18 
cedar_magnet_plane_map(address_map & map)19 void cedar_magnet_plane_device::cedar_magnet_plane_map(address_map &map)
20 {
21 	map(0x0000, 0xffff).ram().share("ram");
22 }
23 
cedar_magnet_plane_io(address_map & map)24 void cedar_magnet_plane_device::cedar_magnet_plane_io(address_map &map)
25 {
26 	map.global_mask(0xff);
27 
28 	map(0xc0, 0xc3).rw("z80pio0", FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
29 	map(0xc4, 0xc7).rw("z80pio1", FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
30 
31 	map(0xcc, 0xcc).w(FUNC(cedar_magnet_plane_device::plane_portcc_w));
32 	map(0xcd, 0xcd).w(FUNC(cedar_magnet_plane_device::plane_portcd_w));
33 	map(0xce, 0xce).w(FUNC(cedar_magnet_plane_device::plane_portce_w));
34 	map(0xcf, 0xcf).w(FUNC(cedar_magnet_plane_device::plane_portcf_w));
35 
36 }
37 
38 
plane_portcc_w(u8 data)39 void cedar_magnet_plane_device::plane_portcc_w(u8 data)
40 {
41 	m_framebuffer[((m_curline & 0xff) * 0x100) + (m_lineoffset & 0xff)] = data;
42 
43 	// counters simply wrap when they reach the maximum, don't move onto next row/colummn (confirmed by xain)
44 	if (m_pio0_pa_data&0x01)
45 	{
46 		m_lineoffset++;
47 	}
48 	else
49 	{
50 		m_curline++;
51 	}
52 }
53 
plane_portcd_w(u8 data)54 void cedar_magnet_plane_device::plane_portcd_w(u8 data)
55 {
56 	m_lineoffset = data;
57 }
58 
plane_portce_w(u8 data)59 void cedar_magnet_plane_device::plane_portce_w(u8 data)
60 {
61 	m_curline = data;
62 }
63 
plane_portcf_w(u8 data)64 void cedar_magnet_plane_device::plane_portcf_w(u8 data)
65 {
66 	// does it have a meaning or is it just some kind of watchdog?
67 	m_cf_data = data;
68 }
69 
device_add_mconfig(machine_config & config)70 void cedar_magnet_plane_device::device_add_mconfig(machine_config &config)
71 {
72 	z80_device &planecpu(Z80(config, "planecpu", 4000000));
73 	planecpu.set_addrmap(AS_PROGRAM, &cedar_magnet_plane_device::cedar_magnet_plane_map);
74 	planecpu.set_addrmap(AS_IO, &cedar_magnet_plane_device::cedar_magnet_plane_io);
75 
76 	z80pio_device& pio0(Z80PIO(config, "z80pio0", 4000000/2));
77 //  pio0.out_int_callback().set_inputline("maincpu", INPUT_LINE_IRQ0);
78 	pio0.in_pa_callback().set(FUNC(cedar_magnet_plane_device::pio0_pa_r));
79 	pio0.out_pa_callback().set(FUNC(cedar_magnet_plane_device::pio0_pa_w));
80 //  pio0.in_pb_callback().set(FUNC(cedar_magnet_plane_device::pio0_pb_r));
81 	pio0.out_pb_callback().set(FUNC(cedar_magnet_plane_device::pio0_pb_w));
82 
83 	z80pio_device& pio1(Z80PIO(config, "z80pio1", 4000000/2));
84 //  pio1.out_int_callback().set_inputline("maincpu", INPUT_LINE_IRQ0);
85 //  pio1.in_pa_callback().set(FUNC(cedar_magnet_plane_device::pio1_pa_r));
86 	pio1.out_pa_callback().set(FUNC(cedar_magnet_plane_device::pio1_pa_w));
87 //  pio1.in_pb_callback().set(FUNC(cedar_magnet_plane_device::pio1_pb_r));
88 	pio1.out_pb_callback().set(FUNC(cedar_magnet_plane_device::pio1_pb_w));
89 }
90 
91 
pio0_pa_r()92 u8 cedar_magnet_plane_device::pio0_pa_r()
93 {
94 // this is read
95 //  logerror("%s: pio0_pa_r\n", machine().describe_context());
96 	return 0x00;
97 }
98 
99 
pio0_pa_w(u8 data)100 void cedar_magnet_plane_device::pio0_pa_w(u8 data)
101 {
102 	m_pio0_pa_data = data;
103 
104 	// 7ex- 321d
105 	//
106 	// e = video enable
107 	// d = draw direction
108 	// x = done? gets set at end of each frame at least, but unlike video enable, also when video shouldn't be enabled
109 	// 7 = always set?
110 	// 321 = always set after startup?
111 }
112 
pio0_pb_w(u8 data)113 void cedar_magnet_plane_device::pio0_pb_w(u8 data)
114 {
115 	m_pio0_pb_data = data;
116 }
117 
pio1_pa_w(u8 data)118 void cedar_magnet_plane_device::pio1_pa_w(u8 data)
119 {
120 	m_scrollx = data;
121 }
122 
pio1_pb_w(u8 data)123 void cedar_magnet_plane_device::pio1_pb_w(u8 data)
124 {
125 	m_scrolly = data;
126 }
127 
device_start()128 void cedar_magnet_plane_device::device_start()
129 {
130 	m_framebuffer = make_unique_clear<u8[]>(0x10000);
131 	save_pointer(NAME(m_framebuffer), 0x10000);
132 }
133 
draw(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int palbase)134 u32 cedar_magnet_plane_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int palbase)
135 {
136 	int count = 0;
137 
138 	if (!(m_pio0_pa_data & 0x40))
139 		return 0;
140 
141 	for (int y = 0; y < 256;y++)
142 	{
143 		u16 *const dst = &bitmap.pix((y - m_scrolly) & 0xff);
144 
145 		for (int x = 0; x < 256;x++)
146 		{
147 			u8 pix = m_framebuffer[count];
148 			count++;
149 
150 			if (pix) dst[(x - m_scrollx) & 0xff] = pix + palbase * 0x100;
151 		}
152 	}
153 
154 	return 0;
155 }
156