summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2023-04-18 13:32:08 +0200
committer Dirk Best <mail@dirk-best.de>2023-04-18 13:33:43 +0200
commit87dc49048b17dd187f06db744f21e5cfe8246706 (patch)
treeaaa75b548bd17706d9ffa893983b530507de8942 /src
parent46095704f1728cc9d3c36eb198a847bf7efd4cc0 (diff)
free220: Fix video emulation, add NVRAM, add aux port, mark working
Graphics still need work, but its usable as a terminal now. Systems promoted to working --------------------------- Liberty Electronics Freedom 220
Diffstat (limited to 'src')
-rw-r--r--src/mame/liberty/freedom220.cpp110
-rw-r--r--src/mame/liberty/freedom220_kbd.cpp8
-rw-r--r--src/mame/liberty/freedom220_kbd.h1
3 files changed, 61 insertions, 58 deletions
diff --git a/src/mame/liberty/freedom220.cpp b/src/mame/liberty/freedom220.cpp
index 850796868bc..1e31e3d4f34 100644
--- a/src/mame/liberty/freedom220.cpp
+++ b/src/mame/liberty/freedom220.cpp
@@ -26,8 +26,15 @@
- Expansion slot
TODO:
- - Fix and improve video emulation
- - Aux port
+ - Font selection
+ - Light/dark background
+ - Double sized characters
+ - Soft scroll
+ - Pixel clock, characters should be 9 pixels?
+
+ Notes:
+ - On first boot you will get an "error 8" - this is because
+ RAM is uninitialized.
****************************************************************************/
@@ -37,6 +44,7 @@
#include "cpu/z80/z80.h"
#include "machine/i8251.h"
#include "machine/input_merger.h"
+#include "machine/nvram.h"
#include "machine/pit8253.h"
#include "video/scn2674.h"
@@ -67,8 +75,7 @@ public:
m_translate(*this, "translate"),
m_charram(*this, "charram%u", 0U),
m_attrram(*this, "attrram%u", 0U),
- m_current_line(0),
- m_nmi_enabled(false)
+ m_video_ctrl(0x00)
{ }
void freedom220(machine_config &config);
@@ -88,20 +95,16 @@ private:
required_shared_ptr_array<uint8_t, 2> m_charram;
required_shared_ptr_array<uint8_t, 2> m_attrram;
- uint8_t m_current_line;
- bool m_nmi_enabled;
+ uint8_t m_video_ctrl;
void mem_map(address_map &map);
void io_map(address_map &map);
- void row_buffer_map(address_map &map);
- uint8_t mbc_char_r(offs_t offset);
- uint8_t mbc_attr_r(offs_t offset);
+ void char_map(address_map &map);
+ void attr_map(address_map &map);
void avdc_intr_w(int state);
- void avdc_breq_w(int state);
+ void video_ctrl_w(uint8_t data);
SCN2674_DRAW_CHARACTER_MEMBER(draw_character);
-
- void nmi_control_w(uint8_t data);
};
@@ -116,7 +119,7 @@ void freedom220_state::mem_map(address_map &map)
map(0x8800, 0x8fff).ram().share(m_attrram[0]);
map(0x9000, 0x97ff).ram().share(m_charram[1]);
map(0x9800, 0x9fff).ram().share(m_attrram[1]);
- map(0xa000, 0xafff).ram();
+ map(0xa000, 0xafff).ram().share("nvram");
}
void freedom220_state::io_map(address_map &map)
@@ -127,7 +130,7 @@ void freedom220_state::io_map(address_map &map)
map(0x40, 0x41).rw(m_usart[0], FUNC(i8251_device::read), FUNC(i8251_device::write));
map(0x60, 0x61).rw(m_usart[1], FUNC(i8251_device::read), FUNC(i8251_device::write));
map(0x80, 0x81).rw(m_usart[2], FUNC(i8251_device::read), FUNC(i8251_device::write));
- map(0xa0, 0xa0).w(FUNC(freedom220_state::nmi_control_w));
+ map(0xa0, 0xa0).w(FUNC(freedom220_state::video_ctrl_w));
}
@@ -135,40 +138,38 @@ void freedom220_state::io_map(address_map &map)
// VIDEO EMULATION
//**************************************************************************
-void freedom220_state::row_buffer_map(address_map &map)
-{
- map.global_mask(0xff);
- map(0x00, 0xff).ram();
-}
-
-uint8_t freedom220_state::mbc_char_r(offs_t offset)
+void freedom220_state::char_map(address_map &map)
{
- if (offset >= 0x800)
- logerror("%d read char offset %04x\n", m_current_line, offset);
-
- return m_charram[0][(m_current_line * 0x50 + offset) & 0x7ff];
+ map(0x0000, 0x07ff).ram().share(m_charram[0]);
+ map(0x1000, 0x17ff).ram().share(m_charram[1]);
+ map(0x2000, 0x2fff).ram().share("nvram");
}
-uint8_t freedom220_state::mbc_attr_r(offs_t offset)
+void freedom220_state::attr_map(address_map &map)
{
- return m_attrram[0][(m_current_line * 0x50 + offset) & 0x7ff];
+ map(0x0000, 0x07ff).ram().share(m_attrram[0]);
+ map(0x1000, 0x17ff).ram().share(m_attrram[1]);
+ map(0x2000, 0x2fff).ram().share("nvram");
}
void freedom220_state::avdc_intr_w(int state)
{
- if (state && m_nmi_enabled)
+ if (state)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
-void freedom220_state::avdc_breq_w(int state)
+void freedom220_state::video_ctrl_w(uint8_t data)
{
- if (state)
- {
- if (m_screen->vblank())
- m_current_line = 0;
- else
- m_current_line++;
- }
+ // 7------- unknown
+ // -6------ unknown
+ // --5----- unknown
+ // ---432-- font select
+ // ------1- normal/reverse video
+ // -------0 unknown
+
+ logerror("video_ctrl_w: %02x\n", data);
+
+ m_video_ctrl = data;
}
SCN2674_DRAW_CHARACTER_MEMBER( freedom220_state::draw_character )
@@ -197,8 +198,7 @@ SCN2674_DRAW_CHARACTER_MEMBER( freedom220_state::draw_character )
if (BIT(attrcode, 2))
data = ~data;
- // TODO
- if (0 && cursor)
+ if (cursor)
data = ~data;
// foreground/background colors
@@ -230,25 +230,14 @@ GFXDECODE_END
// MACHINE EMULATION
//**************************************************************************
-void freedom220_state::nmi_control_w(uint8_t data)
-{
- logerror("nmi_control_w: %02x\n", data);
-
- // unknown if a simple write is enough
- m_nmi_enabled = true;
-}
-
void freedom220_state::machine_start()
{
// register for save states
- save_item(NAME(m_current_line));
- save_item(NAME(m_nmi_enabled));
+ save_item(NAME(m_video_ctrl));
}
void freedom220_state::machine_reset()
{
- m_nmi_enabled = false;
-
// allow data to be send to keyboard
m_usart[2]->write_dsr(1);
m_usart[2]->write_cts(0);
@@ -268,6 +257,8 @@ void freedom220_state::freedom220(machine_config &config)
input_merger_device &irq(INPUT_MERGER_ANY_HIGH(config, "irq"));
irq.output_handler().set_inputline("maincpu", INPUT_LINE_IRQ0);
+ NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_color(rgb_t::green());
m_screen->set_raw(16000000, 768, 0, 640, 321, 0, 300); // clock unverified
@@ -279,14 +270,11 @@ void freedom220_state::freedom220(machine_config &config)
SCN2674(config, m_avdc, 16000000 / 8); // clock unverified
m_avdc->intr_callback().set(FUNC(freedom220_state::avdc_intr_w));
- m_avdc->breq_callback().set(FUNC(freedom220_state::avdc_breq_w));
m_avdc->set_screen(m_screen);
m_avdc->set_character_width(8); // unverified
- m_avdc->set_addrmap(0, &freedom220_state::row_buffer_map);
- m_avdc->set_addrmap(1, &freedom220_state::row_buffer_map);
+ m_avdc->set_addrmap(0, &freedom220_state::char_map);
+ m_avdc->set_addrmap(1, &freedom220_state::attr_map);
m_avdc->set_display_callback(FUNC(freedom220_state::draw_character));
- m_avdc->mbc_char_callback().set(FUNC(freedom220_state::mbc_char_r));
- m_avdc->mbc_attr_callback().set(FUNC(freedom220_state::mbc_attr_r));
pit8253_device &pit(PIT8253(config, "pit", 0));
pit.set_clk<0>(18.432_MHz_XTAL / 10);
@@ -306,15 +294,23 @@ void freedom220_state::freedom220(machine_config &config)
m_usart[0]->rts_handler().set("mainport", FUNC(rs232_port_device::write_rts));
I8251(config, m_usart[1], 0); // unknown clock
+ m_usart[1]->rxrdy_handler().set("irq", FUNC(input_merger_device::in_w<2>));
+ m_usart[1]->txrdy_handler().set("irq", FUNC(input_merger_device::in_w<3>));
+ m_usart[1]->txd_handler().set("auxport", FUNC(rs232_port_device::write_txd));
+ m_usart[1]->rts_handler().set("auxport", FUNC(rs232_port_device::write_rts));
I8251(config, m_usart[2], 0); // unknown clock
- m_usart[2]->rxrdy_handler().set("irq", FUNC(input_merger_device::in_w<2>));
+ m_usart[2]->rxrdy_handler().set("irq", FUNC(input_merger_device::in_w<4>));
m_usart[2]->txd_handler().set("kbd", FUNC(freedom220_kbd_device::rx_w));
rs232_port_device &mainport(RS232_PORT(config, "mainport", default_rs232_devices, nullptr));
mainport.rxd_handler().set(m_usart[0], FUNC(i8251_device::write_rxd));
mainport.cts_handler().set(m_usart[0], FUNC(i8251_device::write_cts));
+ rs232_port_device &auxport(RS232_PORT(config, "auxport", default_rs232_devices, nullptr));
+ auxport.rxd_handler().set(m_usart[1], FUNC(i8251_device::write_rxd));
+ auxport.cts_handler().set(m_usart[1], FUNC(i8251_device::write_cts));
+
freedom220_kbd_device &kbd(FREEDOM220_KBD(config, "kbd"));
kbd.tx_handler().set(m_usart[2], FUNC(i8251_device::write_rxd));
}
@@ -346,4 +342,4 @@ ROM_END
//**************************************************************************
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
-COMP( 1984, free220, 0, 0, freedom220, 0, freedom220_state, empty_init, "Liberty Electronics", "Freedom 220", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
+COMP( 1984, free220, 0, 0, freedom220, 0, freedom220_state, empty_init, "Liberty Electronics", "Freedom 220", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/liberty/freedom220_kbd.cpp b/src/mame/liberty/freedom220_kbd.cpp
index 5c7d9bc31ec..4dd2a751fe1 100644
--- a/src/mame/liberty/freedom220_kbd.cpp
+++ b/src/mame/liberty/freedom220_kbd.cpp
@@ -17,6 +17,7 @@
Notes:
- Also used by the Freedom 200?
+ - Data transfer with 1200 baud, 8n1
***************************************************************************/
@@ -42,7 +43,7 @@ void freedom220_kbd_device::mem_map(address_map &map)
void freedom220_kbd_device::io_map(address_map &map)
{
- map(0x00, 0xff).r(FUNC(freedom220_kbd_device::select_r));
+ map(0x00, 0xff).rw(FUNC(freedom220_kbd_device::select_r), FUNC(freedom220_kbd_device::speaker_w));
}
//-------------------------------------------------
@@ -277,6 +278,11 @@ uint8_t freedom220_kbd_device::select_r(offs_t offset)
return 0;
}
+void freedom220_kbd_device::speaker_w(offs_t offset, uint8_t data)
+{
+ // TODO
+}
+
uint8_t freedom220_kbd_device::p1_r()
{
return m_keys[m_select]->read();
diff --git a/src/mame/liberty/freedom220_kbd.h b/src/mame/liberty/freedom220_kbd.h
index c40113cad68..8357b9cd702 100644
--- a/src/mame/liberty/freedom220_kbd.h
+++ b/src/mame/liberty/freedom220_kbd.h
@@ -45,6 +45,7 @@ private:
void io_map(address_map &map);
uint8_t select_r(offs_t offset);
+ void speaker_w(offs_t offset, uint8_t data);
uint8_t p1_r();
void p2_w(uint8_t data);