New working machines

--------------------
ATM18 Mini Chess Computer (English) [hap]

New working clones
------------------
CC2-Schachzwerg (German)
This commit is contained in:
hap 2022-07-14 22:50:07 +02:00
parent 5c6511fada
commit 635cbc0c86
8 changed files with 261 additions and 49 deletions

View File

@ -238,7 +238,6 @@ void saitekosa_analyst_device::device_add_mconfig(machine_config &config)
// video hardware
HD44780(config, m_lcd, 0);
m_lcd->set_lcd_size(2, 8);
}

View File

@ -12,7 +12,7 @@
the existing opcodes has been shown to wildly corrupt the video output in Craft, so one can assume that the
existing timing is 100% correct.
Unimplemented opcodes: SPM, SPM Z+, SLEEP, BREAK, WDR, EICALL, JMP, CALL
Unimplemented opcodes: SPM, SPM Z+, SLEEP, BREAK, WDR, EICALL
- Changelist -
05 Jul. 2015 [Felipe Sanches]

View File

@ -91,8 +91,6 @@ void master_state::machine_start()
I/O
******************************************************************************/
// TTL/generic
void master_state::control_w(u8 data)
{
// d0-d3: 74145 A-D
@ -215,7 +213,7 @@ INPUT_PORTS_END
void master_state::master(machine_config &config)
{
/* basic machine hardware */
// basic machine hardware
Z80(config, m_maincpu, 8_MHz_XTAL/2);
m_maincpu->set_addrmap(AS_PROGRAM, &master_state::main_trampoline);
ADDRESS_MAP_BANK(config, "mainmap").set_map(&master_state::main_map).set_options(ENDIANNESS_LITTLE, 8, 16);
@ -228,11 +226,11 @@ void master_state::master(machine_config &config)
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
m_board->set_delay(attotime::from_msec(150));
/* video hardware */
// video hardware
PWM_DISPLAY(config, m_display).set_size(9, 2);
config.set_default_layout(layout_ck_master);
/* sound hardware */
// sound hardware
SPEAKER(config, "speaker").front_center();
DAC_2BIT_ONES_COMPLEMENT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.125);
}

View File

@ -142,8 +142,8 @@ u8 y532xl_state::input_r()
void y532xl_state::cb_w(u8 data)
{
// d0-d3: lcd data (see control_w)
// d0-d7: chessboard input mux
// d0-d3: lcd data
m_cb_mux = data;
update_display();
}
@ -173,10 +173,10 @@ void y532xl_state::control_w(offs_t offset, u8 data)
// Q7 rising edge: write to lcd
if (~prev & m_control & 0x80)
m_lcd->data_w(m_cb_mux & 0xf);
}
/******************************************************************************
Address Maps
******************************************************************************/
@ -232,7 +232,7 @@ INPUT_PORTS_END
void y532xl_state::y532xl(machine_config &config)
{
/* basic machine hardware */
// basic machine hardware
R65C02(config, m_maincpu, 4_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &y532xl_state::main_map);
@ -246,14 +246,14 @@ void y532xl_state::y532xl(machine_config &config)
m_board->set_delay(attotime::from_msec(150));
m_board->set_nvram_enable(true);
/* video hardware */
// video hardware
HD61603(config, m_lcd, 0);
m_lcd->write_segs().set(FUNC(y532xl_state::lcd_seg_w));
PWM_DISPLAY(config, m_display).set_size(9, 8);
config.set_default_layout(layout_yeno_532xl);
/* sound hardware */
// sound hardware
SPEAKER(config, "speaker").front_center();
DAC_2BIT_ONES_COMPLEMENT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.125);
}

View File

@ -9,27 +9,51 @@ The chess engine is H.G. Muller's micro-Max 4.8, ATMega88 port and prototype
hardware design by Andre Adrian. PCB finalization by Elektor, published in
Elektor magazine in 2009.
The LCD version uses Elektor's ATM18 (aka CC2) system, and a 2-wire LCD module.
It was not manufactured by Elektor, only described as a homebrew project.
FN 1 = new game, FN 2 = set level, FN 3 = principle variation.
Moves are confirmed by pressing GO twice.
The program is the same for all versions, only the display differs.
Hardware notes:
LED version:
- PCB label 081101-1 (c)Elektor v1.4
- Atmel ATMega88P-20PU @ ~8MHz, 8KB internal ROM
- 4-digit 7seg display, button panel, no sound
LCD version:
- Elektor ATM18 Testboard (has ATmega88 TQFP32 @ 16MHz)
- Elektor 2-wire LCD board (CD4094, HD44780U, 4*20 display)
- custom keypad board
Elektor magazine references (English):
- 04/2008: ATM18 AVR Board
- 05/2008: Two-wire LCD
- 09/2009: ATM18 Mini Chess Computer
- 11/2009: AVR-Max Chess Computer
For the German magazine, AVR-Max-Schachzwerg and CC2-Schachzwerg are in 06/2009.
TODO:
- AVR8 SLEEP opcode is not working, it's used for power-saving here and was
harmless to hack out, but needs to be put back when it's emulated
- add Elektor CC2 version with custom LCD screen
******************************************************************************/
#include "emu.h"
#include "cpu/avr8/avr8.h"
#include "video/hd44780.h"
#include "video/pwm.h"
#include "screen.h"
// internal artwork
#include "avrmax.lh" // clickable
#include "atm18mcc.lh" // clickable
namespace {
@ -40,11 +64,14 @@ public:
avrmax_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_display(*this, "display"),
m_digit_pwm(*this, "digit_pwm"),
m_lcd(*this, "lcd"),
m_inputs(*this, "IN.%u", 0)
{ }
void base(machine_config &config);
void avrmax(machine_config &config);
void atm18mcc(machine_config &config);
protected:
virtual void machine_start() override;
@ -52,7 +79,8 @@ protected:
private:
// devices/pointers
required_device<avr8_device> m_maincpu;
required_device<pwm_display_device> m_display;
optional_device<pwm_display_device> m_digit_pwm;
optional_device<hd44780_device> m_lcd;
required_ioport_array<4> m_inputs;
// address maps
@ -60,20 +88,25 @@ private:
void data_map(address_map &map);
// I/O handlers
void update_display();
void mux_w(u8 data);
void led_w(u8 data);
void input_w(u8 data);
u8 input_r();
void digit_w(u8 data);
void segment_w(u8 data);
void lcd_w(u8 data);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u8 m_inp_mux = 0;
u8 m_7seg_data = 0;
u8 m_shift_reg = 0;
int m_shift_clk = 0;
};
void avrmax_state::machine_start()
{
// register for savestates
save_item(NAME(m_inp_mux));
save_item(NAME(m_7seg_data));
save_item(NAME(m_shift_reg));
save_item(NAME(m_shift_clk));
}
@ -82,23 +115,12 @@ void avrmax_state::machine_start()
I/O
******************************************************************************/
void avrmax_state::update_display()
{
m_display->matrix(m_inp_mux, m_7seg_data);
}
// common
void avrmax_state::mux_w(u8 data)
void avrmax_state::input_w(u8 data)
{
// PC0-PC3: input mux/digit select
// PC0-PC3: input mux
m_inp_mux = ~data & 0xf;
update_display();
}
void avrmax_state::led_w(u8 data)
{
// PD0-PD7: 7seg data
m_7seg_data = ~data;
update_display();
}
u8 avrmax_state::input_r()
@ -114,6 +136,68 @@ u8 avrmax_state::input_r()
}
// LED handlers
void avrmax_state::digit_w(u8 data)
{
// PC0-PC3: also digit select
input_w(data);
m_digit_pwm->write_my(m_inp_mux);
}
void avrmax_state::segment_w(u8 data)
{
// PD0-PD7: digit 7seg data
m_digit_pwm->write_mx(~data);
}
// LCD handlers
u32 avrmax_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0xffffff, cliprect);
const u8 *render = m_lcd->render();
// draw lcd characters
for (int i = 0; i < 80; i++)
{
const u8 *src = render + 16 * i;
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 5; x++)
{
int row = bitswap<2>(i / 20, 0, 1);
int col = i % 20;
u32 color = (BIT(src[y], 4 - x)) ? 0 : 0xe8e8e8;
bitmap.pix(row * 9 + y + 1, col * 6 + x + 1) = color;
}
}
}
return 0;
}
void avrmax_state::lcd_w(u8 data)
{
// PD2: CD4094 data
int shift_data = BIT(data, 2);
// PD3: CD4094 clock
int shift_clk = BIT(data, 3);
if (shift_clk && !m_shift_clk)
m_shift_reg = (m_shift_reg << 1) | shift_data;
m_shift_clk = shift_clk;
// CD4094 Q2-Q5: LCD data
// CD4094 Q6: LCD RS
// CD4094 Q7: LCD E (ANDed with CD4094 data)
m_lcd->db_w(m_shift_reg << 3 & 0xf0);
m_lcd->rs_w(BIT(m_shift_reg, 5));
m_lcd->e_w(BIT(m_shift_reg, 6) & shift_data);
}
/******************************************************************************
Address Maps
@ -163,23 +247,50 @@ INPUT_PORTS_END
Machine Configs
******************************************************************************/
void avrmax_state::avrmax(machine_config &config)
void avrmax_state::base(machine_config &config)
{
/* basic machine hardware */
ATMEGA88(config, m_maincpu, 8000000); // internal R/C clock
// basic machine hardware
ATMEGA88(config, m_maincpu, 16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &avrmax_state::main_map);
m_maincpu->set_addrmap(AS_DATA, &avrmax_state::data_map);
m_maincpu->set_eeprom_tag("eeprom");
m_maincpu->gpio_in<AVR8_IO_PORTB>().set(FUNC(avrmax_state::input_r));
m_maincpu->gpio_out<AVR8_IO_PORTC>().set(FUNC(avrmax_state::mux_w));
m_maincpu->gpio_out<AVR8_IO_PORTD>().set(FUNC(avrmax_state::led_w));
m_maincpu->gpio_out<AVR8_IO_PORTC>().set(FUNC(avrmax_state::input_w));
}
/* video hardware */
PWM_DISPLAY(config, m_display).set_size(4, 8);
m_display->set_segmask(0xf, 0xff);
void avrmax_state::avrmax(machine_config &config)
{
base(config);
// basic machine hardware
m_maincpu->set_clock(8000000); // internal R/C clock
m_maincpu->gpio_out<AVR8_IO_PORTC>().set(FUNC(avrmax_state::digit_w));
m_maincpu->gpio_out<AVR8_IO_PORTD>().set(FUNC(avrmax_state::segment_w));
// video hardware
PWM_DISPLAY(config, m_digit_pwm).set_size(4, 8);
m_digit_pwm->set_segmask(0xf, 0xff);
config.set_default_layout(layout_avrmax);
}
void avrmax_state::atm18mcc(machine_config &config)
{
base(config);
// basic machine hardware
m_maincpu->gpio_out<AVR8_IO_PORTD>().set(FUNC(avrmax_state::lcd_w));
// video hardware
auto &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(60);
screen.set_size(20 * 6 + 1, 4 * 9 + 1);
screen.set_visarea_full();
screen.set_screen_update(FUNC(avrmax_state::screen_update));
HD44780(config, m_lcd, 0);
config.set_default_layout(layout_atm18mcc);
}
/******************************************************************************
@ -188,7 +299,7 @@ void avrmax_state::avrmax(machine_config &config)
ROM_START( avrmax )
ROM_REGION( 0x2000, "maincpu", 0 )
ROM_LOAD( "elektor_081101-41.ic1", 0x0000, 0x2000, CRC(86d2a654) SHA1(3c235b8f6f735eaf408f54cbf44872166e7161d5) )
ROM_LOAD( "elektor_081101-41.ic1", 0x0000, 0x2000, CRC(86d2a654) SHA1(3c235b8f6f735eaf408f54cbf44872166e7161d5) ) // avrmax_en-v1.0.hex
// HACK: changed SLEEP to NOP
ROM_FILL( 0x025c, 2, 0x00 )
@ -203,7 +314,7 @@ ROM_END
ROM_START( avrmaxg )
ROM_REGION( 0x2000, "maincpu", 0 )
ROM_LOAD( "elektor_081101-41_d.ic1", 0x0000, 0x2000, CRC(18ec7a56) SHA1(a018421aa0ad8cce3d852f7519dec3691f3c55a0) )
ROM_LOAD( "elektor_081101-41_d.ic1", 0x0000, 0x2000, CRC(18ec7a56) SHA1(a018421aa0ad8cce3d852f7519dec3691f3c55a0) ) // avrmax_de-v1.0.hex
// HACK: changed SLEEP to NOP
ROM_FILL( 0x025c, 2, 0x00 )
@ -216,6 +327,36 @@ ROM_START( avrmaxg )
ROM_REGION( 0x200, "eeprom", ROMREGION_ERASE00 )
ROM_END
ROM_START( atm18mcc )
ROM_REGION( 0x2000, "maincpu", 0 )
ROM_LOAD( "avrmax_cc2_en-v1.0.bin", 0x0000, 0x2000, CRC(715f4642) SHA1(d20739c6caa49a01e002b3dfbf0f39abf7992540) )
// HACK: changed SLEEP to NOP
ROM_FILL( 0x05da, 2, 0x00 )
ROM_FILL( 0x1466, 2, 0x00 )
ROM_FILL( 0x14a2, 2, 0x00 )
ROM_FILL( 0x14de, 2, 0x00 )
ROM_FILL( 0x1528, 2, 0x00 )
ROM_FILL( 0x16fe, 2, 0x00 )
ROM_REGION( 0x200, "eeprom", ROMREGION_ERASE00 )
ROM_END
ROM_START( cc2schach )
ROM_REGION( 0x2000, "maincpu", 0 )
ROM_LOAD( "avrmax_cc2_de-v1.0.bin", 0x0000, 0x2000, CRC(64cfc646) SHA1(4c371ea9f48c8745cf5f5bcf10973838e239e564) )
// HACK: changed SLEEP to NOP
ROM_FILL( 0x05da, 2, 0x00 )
ROM_FILL( 0x1466, 2, 0x00 )
ROM_FILL( 0x14a2, 2, 0x00 )
ROM_FILL( 0x14de, 2, 0x00 )
ROM_FILL( 0x1528, 2, 0x00 )
ROM_FILL( 0x16fe, 2, 0x00 )
ROM_REGION( 0x200, "eeprom", ROMREGION_ERASE00 )
ROM_END
} // anonymous namespace
@ -224,6 +365,9 @@ ROM_END
Drivers
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
CONS( 2009, avrmax, 0, 0, avrmax, avrmax, avrmax_state, empty_init, "Elektor", "AVR-Max Chess Computer (English)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW )
CONS( 2009, avrmaxg, avrmax, 0, avrmax, avrmax, avrmax_state, empty_init, "Elektor", "AVR-Max-Schachzwerg (German)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW ) // German 'text'
// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
CONS( 2009, avrmax, 0, 0, avrmax, avrmax, avrmax_state, empty_init, "Elektor", "AVR-Max Chess Computer (English)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW )
CONS( 2009, avrmaxg, avrmax, 0, avrmax, avrmax, avrmax_state, empty_init, "Elektor", "AVR-Max-Schachzwerg (German)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW ) // German 'text'
CONS( 2009, atm18mcc, 0, 0, atm18mcc, avrmax, avrmax_state, empty_init, "Elektor", "ATM18 Mini Chess Computer (English)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW )
CONS( 2009, cc2schach, atm18mcc, 0, atm18mcc, avrmax, avrmax_state, empty_init, "Elektor", "CC2-Schachzwerg (German)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW )

View File

@ -58,8 +58,8 @@ $2400 // Chess Board
$2800 // Chess Board
$3000 // Chess Board
$4000-7FFF Opening Modul HG550
$8000-$FFF ROM
$4000-$7FFF Opening Module HG550
$8000-$FFFF ROM
===============================================================================

View File

@ -0,0 +1,69 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<!-- NOTE: no chesspieces simulation here -->
<!-- define elements -->
<element name="lcdw"><rect><color red="1" green="1" blue="1" /></rect></element>
<element name="lcdm"><rect><color red="0.37" green="0.45" blue="0.1" /></rect></element>
<element name="lcda"><rect><color red="0.02" green="0.06" blue="0.08" /></rect></element>
<element name="but" defstate="0">
<disk state="0"><color red="0.21" green="0.2" blue="0.2" /></disk>
<disk state="1"><color red="0.31" green="0.3" blue="0.3" /></disk>
</element>
<element name="text_1"><text string="A1"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_2"><text string="B2"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_3"><text string="C3"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_4"><text string="D4"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_5"><text string="E5"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_6"><text string="F6"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_7"><text string="G7"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_8"><text string="H8"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_fn"><text string="FN"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_cl"><text string="CL"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_go"><text string="GO"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<!-- build screen -->
<view name="Internal Layout">
<bounds left="-13.492" right="80" top="5" bottom="47" />
<element ref="lcdw"><bounds x="-8.492" y="10" width="48.492" height="15" /></element>
<screen index="0"><bounds x="-7.792" y="10.3" width="47.092" height="14.4" /></screen>
<element ref="lcdm" blend="multiply"><bounds x="-8.492" y="10" width="48.492" height="15" /></element>
<element ref="lcda" blend="add"><bounds x="-8.492" y="10" width="48.492" height="15" /></element>
<element ref="text_1"><bounds x="50" y="6" width="5" height="4" /></element>
<element ref="text_2"><bounds x="60" y="6" width="5" height="4" /></element>
<element ref="text_3"><bounds x="70" y="6" width="5" height="4" /></element>
<element ref="text_4"><bounds x="50" y="16" width="5" height="4" /></element>
<element ref="text_5"><bounds x="60" y="16" width="5" height="4" /></element>
<element ref="text_6"><bounds x="70" y="16" width="5" height="4" /></element>
<element ref="text_7"><bounds x="50" y="26" width="5" height="4" /></element>
<element ref="text_8"><bounds x="60" y="26" width="5" height="4" /></element>
<element ref="text_fn"><bounds x="50" y="36" width="5" height="4" /></element>
<element ref="text_cl"><bounds x="60" y="36" width="5" height="4" /></element>
<element ref="text_go"><bounds x="70" y="36" width="5" height="4" /></element>
<element ref="but" inputtag="IN.0" inputmask="0x01"><bounds x="50" y="10" width="5" height="5" /></element>
<element ref="but" inputtag="IN.1" inputmask="0x01"><bounds x="60" y="10" width="5" height="5" /></element>
<element ref="but" inputtag="IN.2" inputmask="0x01"><bounds x="70" y="10" width="5" height="5" /></element>
<element ref="but" inputtag="IN.3" inputmask="0x01"><bounds x="50" y="20" width="5" height="5" /></element>
<element ref="but" inputtag="IN.0" inputmask="0x02"><bounds x="60" y="20" width="5" height="5" /></element>
<element ref="but" inputtag="IN.1" inputmask="0x02"><bounds x="70" y="20" width="5" height="5" /></element>
<element ref="but" inputtag="IN.2" inputmask="0x02"><bounds x="50" y="30" width="5" height="5" /></element>
<element ref="but" inputtag="IN.3" inputmask="0x02"><bounds x="60" y="30" width="5" height="5" /></element>
<element ref="but" inputtag="IN.0" inputmask="0x04"><bounds x="50" y="40" width="5" height="5" /></element>
<element ref="but" inputtag="IN.1" inputmask="0x04"><bounds x="60" y="40" width="5" height="5" /></element>
<element ref="but" inputtag="IN.2" inputmask="0x04"><bounds x="70" y="40" width="5" height="5" /></element>
</view>
</mamelayout>

View File

@ -3257,8 +3257,10 @@ avigo_it // 1997 Avigo (Italian)
aviion_4600 // Data General AViiON 4600
@source:elektor/avrmax.cpp
atm18mcc
avrmax
avrmaxg
cc2schach
@source:misc/avt.cpp
avtbingo // (c) 1985 AVT