1 // license:GPL-2.0+
2 // copyright-holders:Felipe Sanches
3 /***************************************************************************
4   This driver covers only the Operator Panel of the BancTec 91690 Document Processor equipment
5 
6   Author: Felipe Sanches <juca@members.fsf.org>
7 
8   Maintainence Manual: <https://garoa.net.br/w/images/PAINEL_BANCTEC_91690.PDF>
9 
10   The display is considered a replaceable part, not repairable. Therefore the manual
11   has no circuit description or schematic. And so, much of the below is guesswork.
12 
13   Machine starts up and clears video ram, then nothing more. Location of videoram
14   in the memory map is unknown, left at 8000 for now.
15 
16 */
17 
18 #include "emu.h"
19 #include "cpu/mcs51/mcs51.h"
20 #include "cpu/m6800/m6801.h"
21 #include "video/mc6845.h"
22 #include "emupal.h"
23 #include "screen.h"
24 
25 class banctec_state : public driver_device
26 {
27 public:
banctec_state(const machine_config & mconfig,device_type type,const char * tag)28 	banctec_state(const machine_config &mconfig, device_type type, const char *tag)
29 		: driver_device(mconfig, type, tag)
30 		, m_palette(*this, "palette")
31 		, m_video_address(0)
32 		, m_maincpu(*this, "maincpu")
33 		, m_videoram(*this, "videoram")
34 		, m_p_chargen(*this, "chargen")
35 	{ }
36 
37 	void banctec(machine_config &config);
38 
39 protected:
40 	MC6845_UPDATE_ROW(crtc_update_row);
41 	MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr);
42 	void videoram_w(u8 data);
43 
44 	virtual void machine_reset() override;
45 	void banctec_mcu_mem(address_map &map);
46 	void banctec_mem(address_map &map);
47 
48 private:
49 	required_device<palette_device> m_palette;
50 	u8 m_video_address;
51 	required_device<cpu_device> m_maincpu;
52 	required_shared_ptr<u8> m_videoram;
53 	required_region_ptr<u8> m_p_chargen;
54 };
55 
banctec_mem(address_map & map)56 void banctec_state::banctec_mem(address_map &map)
57 {
58 	map(0x0000, 0x07ff).rom();
59 	map(0x0800, 0xffff).ram(); /* Probably wrong. Must be verified on pcb! */
60 }
61 
banctec_mcu_mem(address_map & map)62 void banctec_state::banctec_mcu_mem(address_map &map)
63 {
64 	map(0x2000, 0x2000).rw("crtc", FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w));
65 	map(0x2001, 0x2001).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
66 	map(0x2003, 0x2003).w(FUNC(banctec_state::videoram_w));
67 	map(0x8000, 0x80ff).ram().share("videoram"); /* Probably wrong. Must be verified on pcb! */
68 	map(0xe000, 0xffff).rom().region("mcu", 0x0000);
69 }
70 
machine_reset()71 void banctec_state::machine_reset()
72 {
73 }
74 
75 
76 /****************************
77 * Video/Character functions *
78 ****************************/
79 
videoram_w(u8 data)80 void banctec_state::videoram_w(u8 data)
81 {
82 	m_videoram[m_video_address] = data;
83 	m_video_address++;
84 }
85 
86 /* ROCKWELL 6545 - Transparent Memory Addressing */
87 
MC6845_UPDATE_ROW(banctec_state::crtc_update_row)88 MC6845_UPDATE_ROW( banctec_state::crtc_update_row )
89 {
90 	rgb_t const *const palette = m_palette->palette()->entry_list_raw();
91 	u32 *p = &bitmap.pix(y);
92 
93 	for (u16 x = 0; x < x_count; x++)
94 	{
95 		u16 const mem = (ma + x) & 0xff;
96 		u8 const chr = m_videoram[mem];
97 		u8 const gfx = m_p_chargen[chr | (ra << 8)] ^ ((x == cursor_x) ? 0xff : 0);
98 
99 		/* Display a scanline of a character (8 pixels) */
100 		*p++ = palette[BIT(gfx, 7)];
101 		*p++ = palette[BIT(gfx, 6)];
102 		*p++ = palette[BIT(gfx, 5)];
103 		*p++ = palette[BIT(gfx, 4)];
104 		*p++ = palette[BIT(gfx, 3)];
105 		*p++ = palette[BIT(gfx, 2)];
106 		*p++ = palette[BIT(gfx, 1)];
107 		*p++ = palette[BIT(gfx, 0)];
108 	}
109 }
110 
MC6845_ON_UPDATE_ADDR_CHANGED(banctec_state::crtc_addr)111 MC6845_ON_UPDATE_ADDR_CHANGED(banctec_state::crtc_addr)
112 {
113 	/* What is this function meant to do ? */
114 	m_video_address = address;
115 }
116 
117 /******************************
118 * Graphics Decode Information *
119 ******************************/
120 
121 const gfx_layout banctec_gfx_layout =
122 {
123 	8, 8,               /* 8x8 characters */
124 	256,                /* 256 characters */
125 	1,                  /* 1 bits per pixel */
126 	{0},                /* no bitplanes; 1 bit per pixel */
127 	{0, 1, 2, 3, 4, 5, 6, 7},
128 	{0 * 256*8, 1 * 256*8, 2 * 256*8, 3 * 256*8, 4 * 256*8, 5 * 256*8, 6 * 256*8, 7 * 256*8},
129 	8                 /* size of one char */
130 };
131 
132 static GFXDECODE_START( gfx_banctec )
133 	GFXDECODE_ENTRY( "chargen", 0x00000, banctec_gfx_layout, 0, 1 )
134 GFXDECODE_END
135 
banctec(machine_config & config)136 void banctec_state::banctec(machine_config &config)
137 {
138 	/* basic machine hardware */
139 
140 	I80C31(config, m_maincpu, XTAL(11'059'200));
141 	m_maincpu->set_addrmap(AS_PROGRAM, &banctec_state::banctec_mem);
142 
143 	m6803_cpu_device &mcu(M6803(config, "mcu", 4000000));     /* Actual MCU is a Motorola 6803 and the clock frequency is still unknown */
144 	mcu.set_addrmap(AS_PROGRAM, &banctec_state::banctec_mcu_mem);
145 
146 // The video signal is generated by a R6545EAP character generator chip
147 // The U20 EPROM holds the image data for the character set.
148 
149 	// video hardware
150 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
151 	screen.set_refresh_hz(60);
152 	screen.set_size((52+1)*8, (31+1)*8);
153 	screen.set_visarea(0*8, 40*8-1, 0*8, 25*8-1);
154 	screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update));
155 	PALETTE(config, m_palette, palette_device::MONOCHROME);
156 	GFXDECODE(config, "gfxdecode", m_palette, gfx_banctec);
157 
158 	r6545_1_device &crtc(R6545_1(config, "crtc", XTAL(2'000'000))); /* (?) */
159 	crtc.set_screen("screen");
160 	crtc.set_show_border_area(false);
161 	crtc.set_char_width(8);
162 	crtc.set_update_row_callback(FUNC(banctec_state::crtc_update_row));
163 	crtc.set_on_update_addr_change_callback(FUNC(banctec_state::crtc_addr));
164 }
165 
166 ROM_START(banctec)
167 	ROM_REGION(0x800, "maincpu", 0)
168 	ROM_LOAD("banctec_eseries_panel_opnl.u20", 0x000, 0x800, CRC(c2ab9c06) SHA1(a296589034f656790ad5ffbce028dd846a40cf03))
169 
170 	ROM_REGION(0x2000, "mcu", 0)
171 	ROM_LOAD("banctec_eseries_panel.u8", 0x0000, 0x2000, CRC(f3335e0a) SHA1(5ca45fdcb7ef45a65c28c79abfa9ebb7a8a06619))
172 
173 	ROM_REGION(0x1000, "chargen", 0)
174 	ROM_LOAD("banctec_eseries_panel.u20", 0x0000, 0x1000, CRC(5b6ecec9) SHA1(35aff8f965bce77205e3a43d71e39097585091a7))
175 ROM_END
176 
177 /***************************************************************************
178 
179   Game driver(s)
180 
181 ***************************************************************************/
182 
183 /*    YEAR  NAME     PARENT  COMPAT  MACHINE  INPUT  STATE          INIT        COMPANY              FULLNAME                 FLAGS */
184 CONS( 1989, banctec, 0,      0,      banctec, 0,     banctec_state, empty_init, "DALE Electronics",  "BancTec ESeries Panel", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
185