mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
amstrad/nc: Rewrite driver
- Use memory views for banking - Simplify IRQ handling - Simplify power off handling - Replace custom PCMCIA hookup with MAME standard - Combine screen_update for all variants and update LCD colors - Add support for the NC200 floppy drive - Hook up RS232 ports - Split drivers into regional variants with matching keyboard - Support changing battery state - Add support for save states New working systems ------------------- NC100 (Sweden) [CPCWiki]
This commit is contained in:
parent
4ca6a1b3e9
commit
a8e9da5cf0
File diff suppressed because it is too large
Load Diff
@ -1,212 +0,0 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Wilbert Pol, Kevin Thacker
|
||||
/*****************************************************************************
|
||||
*
|
||||
* includes/nc.h
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef MAME_AMSTRAD_NC_H
|
||||
#define MAME_AMSTRAD_NC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "machine/upd765.h" // for NC200 disk drive interface
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/beep.h"
|
||||
#include "emupal.h"
|
||||
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/generic/carts.h"
|
||||
|
||||
#define NC_NUM_COLOURS 4
|
||||
|
||||
#define NC_SCREEN_WIDTH 480
|
||||
#define NC_SCREEN_HEIGHT 64
|
||||
|
||||
#define NC200_SCREEN_WIDTH 480
|
||||
#define NC200_SCREEN_HEIGHT 128
|
||||
|
||||
#define NC200_NUM_COLOURS 4
|
||||
|
||||
class nc_state : public driver_device
|
||||
{
|
||||
public:
|
||||
enum nc_type
|
||||
{
|
||||
NC_TYPE_1xx, // nc100/nc150
|
||||
NC_TYPE_200 // nc200
|
||||
};
|
||||
|
||||
nc_state(const machine_config &mconfig, device_type type, const char *tag, nc_type variant) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_beeper1(*this, "beep.1"),
|
||||
m_beeper2(*this, "beep.2"),
|
||||
m_centronics(*this, "centronics"),
|
||||
m_card(*this, "cardslot"),
|
||||
m_uart(*this, "uart"),
|
||||
m_uart_clock(*this, "uart_clock"),
|
||||
m_nvram(*this, "nvram"),
|
||||
m_fdc(*this, "upd765"),
|
||||
m_bankhandler_r(*this, "bank%u", 1U),
|
||||
m_bankhandler_w(*this, "bank%u", 5U),
|
||||
m_nc_type(variant)
|
||||
{
|
||||
}
|
||||
|
||||
void nc_base(machine_config &config);
|
||||
|
||||
void init_nc();
|
||||
|
||||
protected:
|
||||
uint8_t nc_memory_management_r(offs_t offset);
|
||||
void nc_memory_management_w(offs_t offset, uint8_t data);
|
||||
void nc_irq_mask_w(uint8_t data);
|
||||
void nc_irq_status_w(uint8_t data);
|
||||
uint8_t nc_irq_status_r();
|
||||
uint8_t nc_key_data_in_r(offs_t offset);
|
||||
void nc_sound_w(offs_t offset, uint8_t data);
|
||||
void nc_uart_control_w(uint8_t data);
|
||||
void nc100_display_memory_start_w(uint8_t data);
|
||||
|
||||
void nc_colours(palette_device &palette) const;
|
||||
TIMER_CALLBACK_MEMBER(nc_keyboard_timer_callback);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(dummy_timer_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_uart_clock);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( load_pcmcia_card );
|
||||
DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER( unload_pcmcia_card );
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
void nc_map(address_map &map);
|
||||
|
||||
uint32_t screen_update_nc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int height, int width, int const (&pens)[2]);
|
||||
void nc_update_interrupts();
|
||||
|
||||
private:
|
||||
int card_calculate_mask(int size);
|
||||
void set_card_present_state(int state);
|
||||
void nc_refresh_memory_bank_config(int bank);
|
||||
void nc_refresh_memory_config();
|
||||
void nc_sound_update(int channel);
|
||||
|
||||
protected: // HACK FOR MC6845
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<beep_device> m_beeper1;
|
||||
required_device<beep_device> m_beeper2;
|
||||
required_device<centronics_device> m_centronics;
|
||||
required_device<generic_slot_device> m_card;
|
||||
required_device<i8251_device> m_uart;
|
||||
required_device<clock_device> m_uart_clock;
|
||||
required_device<nvram_device> m_nvram;
|
||||
optional_device<upd765a_device> m_fdc;
|
||||
required_memory_bank_array<4> m_bankhandler_r, m_bankhandler_w;
|
||||
|
||||
char m_memory_config[4]{};
|
||||
emu_timer *m_keyboard_timer = nullptr;
|
||||
int m_membank_rom_mask = 0;
|
||||
int m_membank_internal_ram_mask = 0;
|
||||
uint8_t m_poweroff_control = 0;
|
||||
int m_card_status = 0;
|
||||
unsigned char m_uart_control = 0;
|
||||
int m_irq_mask = 0;
|
||||
int m_irq_status = 0;
|
||||
int m_irq_latch = 0;
|
||||
int m_irq_latch_mask = 0;
|
||||
int m_sound_channel_periods[2]{};
|
||||
int m_previous_inputport_10_state = 0;
|
||||
int m_previous_alarm_state = 0;
|
||||
memory_region *m_card_ram = nullptr;
|
||||
int m_membank_card_ram_mask = 0;
|
||||
int m_card_size = 0;
|
||||
unsigned long m_display_memory_start = 0;
|
||||
const nc_type m_nc_type;
|
||||
|
||||
int m_centronics_ack = 0;
|
||||
int m_centronics_busy = 0;
|
||||
};
|
||||
|
||||
|
||||
class nc100_state : public nc_state
|
||||
{
|
||||
public:
|
||||
nc100_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
nc_state(mconfig, type, tag, NC_TYPE_1xx)
|
||||
{
|
||||
}
|
||||
|
||||
void nc100(machine_config &config);
|
||||
|
||||
protected:
|
||||
void nc100_uart_control_w(uint8_t data);
|
||||
void nc100_poweroff_control_w(uint8_t data);
|
||||
uint8_t nc100_card_battery_status_r();
|
||||
void nc100_memory_card_wait_state_w(uint8_t data);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(nc100_tc8521_alarm_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(nc100_txrdy_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(nc100_rxrdy_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_nc100_centronics_ack);
|
||||
|
||||
virtual void machine_reset() override;
|
||||
|
||||
void nc100_io(address_map &map);
|
||||
|
||||
uint32_t screen_update_nc100(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class nc200_state : public nc_state
|
||||
{
|
||||
public:
|
||||
nc200_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
nc_state(mconfig, type, tag, NC_TYPE_200)
|
||||
{
|
||||
}
|
||||
|
||||
void nc200(machine_config &config);
|
||||
|
||||
protected:
|
||||
void nc200_irq_status_w(uint8_t data);
|
||||
uint8_t nc200_card_battery_status_r();
|
||||
uint8_t nc200_printer_status_r();
|
||||
void nc200_uart_control_w(uint8_t data);
|
||||
void nc200_memory_card_wait_state_w(uint8_t data);
|
||||
void nc200_poweroff_control_w(uint8_t data);
|
||||
[[maybe_unused]] void nc200_display_memory_start_w(uint8_t data);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(write_nc200_centronics_ack);
|
||||
DECLARE_WRITE_LINE_MEMBER(nc200_txrdy_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(nc200_rxrdy_callback);
|
||||
DECLARE_WRITE_LINE_MEMBER(nc200_fdc_interrupt);
|
||||
|
||||
[[maybe_unused]] void nc200_floppy_drive_index_callback(int drive_id);
|
||||
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint32_t screen_update_nc200(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void nc200_io(address_map &map);
|
||||
|
||||
private:
|
||||
void nc200_video_set_backlight(int state);
|
||||
void nc200_refresh_uart_interrupt();
|
||||
|
||||
uint8_t m_nc200_uart_interrupt_irq = 0;
|
||||
int m_nc200_backlight = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // MAME_AMSTRAD_NC_H
|
@ -1,87 +0,0 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Wilbert Pol, Kevin Thacker
|
||||
/***************************************************************************
|
||||
|
||||
nc.c
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "nc.h"
|
||||
#include "machine/i8251.h"
|
||||
|
||||
/*************************************************************************************************/
|
||||
/* PCMCIA Ram Card management */
|
||||
|
||||
/* the data is stored as a simple memory dump, there is no header or other information */
|
||||
/* stores size of actual file on filesystem */
|
||||
|
||||
|
||||
/* this is not a real register, it is used to record card status */
|
||||
/* ==0, card not inserted, !=0 card is inserted */
|
||||
|
||||
// set pcmcia card present state
|
||||
void nc_state::set_card_present_state(int state)
|
||||
{
|
||||
m_card_status = state;
|
||||
}
|
||||
|
||||
|
||||
// this mask will prevent overwrites from end of data
|
||||
int nc_state::card_calculate_mask(int size)
|
||||
{
|
||||
/* memory block is visible as 16k blocks */
|
||||
/* mask can only operate on power of two sizes */
|
||||
/* memory cards normally in power of two sizes */
|
||||
/* maximum of 64 16k blocks can be accessed using memory paging of nc computer */
|
||||
/* max card size is therefore 1mb */
|
||||
for (int i = 14; i < 20; i++)
|
||||
{
|
||||
if (size < (1 << i))
|
||||
return 0x03f >> (19 - i);
|
||||
}
|
||||
|
||||
return 0x03f;
|
||||
}
|
||||
|
||||
|
||||
// load pcmcia card data
|
||||
DEVICE_IMAGE_LOAD_MEMBER( nc_state::load_pcmcia_card )
|
||||
{
|
||||
uint32_t size = m_card->common_get_size("rom");
|
||||
|
||||
m_card->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
|
||||
m_card->common_load_rom(m_card->get_rom_base(), size, "rom");
|
||||
|
||||
set_card_present_state(1);
|
||||
m_membank_card_ram_mask = card_calculate_mask(size);
|
||||
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
|
||||
// save pcmcia card data back
|
||||
DEVICE_IMAGE_UNLOAD_MEMBER( nc_state::unload_pcmcia_card )
|
||||
{
|
||||
// if there is no data to write, quit
|
||||
if (!m_card_size)
|
||||
return;
|
||||
|
||||
logerror("attempting card save\n");
|
||||
|
||||
// write data
|
||||
image.fwrite(m_card_ram, m_card_size);
|
||||
|
||||
logerror("write succeeded!\r\n");
|
||||
|
||||
// set card not present state
|
||||
set_card_present_state(0);
|
||||
m_card_size = 0;
|
||||
}
|
||||
|
||||
void nc_state::init_nc()
|
||||
{
|
||||
// set card not present state
|
||||
set_card_present_state(0);
|
||||
m_card_size = 0;
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Wilbert Pol, Kevin Thacker
|
||||
/***************************************************************************
|
||||
|
||||
nc.c
|
||||
|
||||
Functions to emulate the video hardware of the Amstrad PCW.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "nc.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
/***************************************************************************
|
||||
Start the video hardware emulation.
|
||||
***************************************************************************/
|
||||
|
||||
void nc_state::video_start()
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* two colours */
|
||||
static const unsigned short nc_colour_table[NC_NUM_COLOURS] =
|
||||
{
|
||||
0, 1,2,3
|
||||
};
|
||||
#endif
|
||||
|
||||
/* black/white */
|
||||
static const rgb_t nc_palette[NC_NUM_COLOURS] =
|
||||
{
|
||||
rgb_t(0x060, 0x060, 0x060),
|
||||
rgb_t(0x000, 0x000, 0x000),
|
||||
rgb_t(0x080, 0x0a0, 0x060),
|
||||
rgb_t(0x000, 0x000, 0x000)
|
||||
};
|
||||
|
||||
|
||||
/* Initialise the palette */
|
||||
void nc_state::nc_colours(palette_device &palette) const
|
||||
{
|
||||
palette.set_pen_colors(0, nc_palette);
|
||||
}
|
||||
|
||||
|
||||
void nc200_state::nc200_video_set_backlight(int state)
|
||||
{
|
||||
m_nc200_backlight = state;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Draw the game screen in the given bitmap_ind16.
|
||||
Do NOT call osd_update_display() from this function,
|
||||
it will be called by the main emulation engine.
|
||||
***************************************************************************/
|
||||
uint32_t nc_state::screen_update_nc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int height, int width, int const (&pens)[2])
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
/* 64 bytes per line */
|
||||
char const *line_ptr = ((char const *)m_ram->pointer()) + m_display_memory_start + (y<<6);
|
||||
|
||||
for (int x = 0, by = 0; by < (width >> 3); by++)
|
||||
{
|
||||
unsigned char byte = line_ptr[0];
|
||||
|
||||
for (int b = 0; b < 8; b++)
|
||||
{
|
||||
bitmap.pix(y, x) = pens[(byte>>7) & 0x01];
|
||||
byte = byte<<1;
|
||||
x++;
|
||||
}
|
||||
|
||||
line_ptr++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t nc100_state::screen_update_nc100(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int const pens[]{ 2, 3 };
|
||||
return screen_update_nc(screen, bitmap, cliprect, NC_SCREEN_HEIGHT, NC_SCREEN_WIDTH, pens);
|
||||
}
|
||||
|
||||
|
||||
uint32_t nc200_state::screen_update_nc200(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int const pens[]{ m_nc200_backlight ? 2 : 0, m_nc200_backlight ? 3 : 1 };
|
||||
return screen_update_nc(screen, bitmap, cliprect, NC200_SCREEN_HEIGHT, NC200_SCREEN_WIDTH, pens);
|
||||
}
|
@ -688,10 +688,14 @@ gx4000 // Amstrad GX4000 - 1990
|
||||
kccomp // VEB KC compact
|
||||
|
||||
@source:amstrad/nc.cpp
|
||||
dw225 //
|
||||
nc100 // 1992 NC100
|
||||
nc150 // 1992 NC150
|
||||
nc200 // 1993 NC200
|
||||
nc100 // 1992 Amstrad
|
||||
nc100de // 1992 Amstrad
|
||||
nc100dk // 1992 Amstrad
|
||||
nc100sv // 1992 Amstrad
|
||||
dw225 // 1992 NTS
|
||||
nc150fr // 1992 Amstrad
|
||||
nc150it // 1992 Amstrad
|
||||
nc200 // 1993 Amstrad
|
||||
|
||||
@source:amstrad/pc1512.cpp
|
||||
pc1512 //
|
||||
|
Loading…
Reference in New Issue
Block a user