mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
agat: basic emulation of agat9 (video, apple compat mode, LLE floppy)
also included: MX floppy format (nw)
This commit is contained in:
parent
35af77fcfa
commit
a152d1125f
@ -2115,6 +2115,8 @@ if (BUSES["A2BUS"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/a2bus/agat7ram.h",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/agat840k_hle.cpp",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/agat840k_hle.h",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/agat_fdc.cpp",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/agat_fdc.h",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/ssprite.cpp",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/ssprite.h",
|
||||
MAME_DIR .. "src/devices/bus/a2bus/ssbapple.cpp",
|
||||
|
@ -197,6 +197,18 @@ if (FORMATS["AGAT840K_HLE_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/aim_dsk.h,FORMATS["AIM_DSK"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (FORMATS["AIM_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
files {
|
||||
MAME_DIR.. "src/lib/formats/aim_dsk.cpp",
|
||||
MAME_DIR.. "src/lib/formats/aim_dsk.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/ami_dsk.h,FORMATS["AMI_DSK"] = true
|
||||
@ -689,6 +701,18 @@ if (FORMATS["DMK_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/ds9_dsk.h,FORMATS["DS9_DSK"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (FORMATS["DS9_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
files {
|
||||
MAME_DIR.. "src/lib/formats/ds9_dsk.cpp",
|
||||
MAME_DIR.. "src/lib/formats/ds9_dsk.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/sdf_dsk.h,FORMATS["SDF_DSK"] = true
|
||||
@ -725,6 +749,18 @@ if (FORMATS["DMV_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/dvk_mx_dsk.h,FORMATS["DVK_MX_DSK"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (FORMATS["DVK_MX_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
files {
|
||||
MAME_DIR.. "src/lib/formats/dvk_mx_dsk.cpp",
|
||||
MAME_DIR.. "src/lib/formats/dvk_mx_dsk.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/esq16_dsk.h,FORMATS["ESQ16_DSK"] = true
|
||||
|
@ -883,6 +883,7 @@ FORMATS["ADAM_CAS"] = true
|
||||
FORMATS["ADAM_DSK"] = true
|
||||
FORMATS["AFS_DSK"] = true
|
||||
FORMATS["AGAT840K_HLE_DSK"] = true
|
||||
FORMATS["AIM_DSK"] = true
|
||||
FORMATS["AMI_DSK"] = true
|
||||
FORMATS["AP2_DSK"] = true
|
||||
FORMATS["APD_DSK"] = true
|
||||
@ -925,6 +926,7 @@ FORMATS["DCP_DSK"] = true
|
||||
FORMATS["DIM_DSK"] = true
|
||||
FORMATS["DIP_DSK"] = true
|
||||
FORMATS["DMK_DSK"] = true
|
||||
FORMATS["DS9_DSK"] = true
|
||||
FORMATS["SDF_DSK"] = true
|
||||
FORMATS["EP64_DSK"] = true
|
||||
FORMATS["DMV_DSK"] = true
|
||||
@ -1523,6 +1525,8 @@ files {
|
||||
MAME_DIR .. "src/mame/includes/apple2.h",
|
||||
MAME_DIR .. "src/mame/video/agat7.cpp",
|
||||
MAME_DIR .. "src/mame/video/agat7.h",
|
||||
MAME_DIR .. "src/mame/video/agat9.cpp",
|
||||
MAME_DIR .. "src/mame/video/agat9.h",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "akai")
|
||||
|
@ -26,6 +26,7 @@
|
||||
DEFINE_DEVICE_TYPE(A2BUS_DISKII, a2bus_diskii_device, "a2diskii", "Apple Disk II controller")
|
||||
DEFINE_DEVICE_TYPE(A2BUS_IWM_FDC, a2bus_iwmflop_device, "a2iwm_flop", "Apple IWM floppy card")
|
||||
DEFINE_DEVICE_TYPE(A2BUS_AGAT7_FDC, a2bus_agat7flop_device, "agat7_flop", "Agat-7 140K floppy card")
|
||||
DEFINE_DEVICE_TYPE(A2BUS_AGAT9_FDC, a2bus_agat9flop_device, "agat9_flop", "Agat-9 140K floppy card")
|
||||
|
||||
#define DISKII_ROM_REGION "diskii_rom"
|
||||
#define FDC_TAG "diskii_fdc"
|
||||
@ -57,6 +58,11 @@ ROM_START( agat7 )
|
||||
ROM_LOAD( "shugart7.rom", 0x0000, 0x0100, CRC(c6e4850c) SHA1(71626d3d2d4bbeeac2b77585b45a5566d20b8d34) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( agat9 )
|
||||
ROM_REGION(0x100, DISKII_ROM_REGION, 0)
|
||||
ROM_LOAD( "shugart9.rom", 0x0000, 0x0100, CRC(964a0ce2) SHA1(bf955189ebffe874c20ef649a3db8177dc16af61) )
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
@ -89,6 +95,11 @@ const tiny_rom_entry *a2bus_agat7flop_device::device_rom_region() const
|
||||
return ROM_NAME( agat7 );
|
||||
}
|
||||
|
||||
const tiny_rom_entry *a2bus_agat9flop_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( agat9 );
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
@ -115,6 +126,11 @@ a2bus_agat7flop_device::a2bus_agat7flop_device(const machine_config &mconfig, co
|
||||
{
|
||||
}
|
||||
|
||||
a2bus_agat9flop_device::a2bus_agat9flop_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
a2bus_floppy_device(mconfig, A2BUS_AGAT9_FDC, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
@ -67,9 +67,18 @@ public:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
};
|
||||
|
||||
class a2bus_agat9flop_device: public a2bus_floppy_device
|
||||
{
|
||||
public:
|
||||
a2bus_agat9flop_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(A2BUS_DISKII, a2bus_diskii_device)
|
||||
DECLARE_DEVICE_TYPE(A2BUS_IWM_FDC, a2bus_iwmflop_device)
|
||||
DECLARE_DEVICE_TYPE(A2BUS_AGAT7_FDC, a2bus_agat7flop_device)
|
||||
DECLARE_DEVICE_TYPE(A2BUS_AGAT9_FDC, a2bus_agat9flop_device)
|
||||
|
||||
#endif // MAME_BUS_A2BUS_A2DISKII_H
|
||||
|
@ -326,24 +326,28 @@ uint8_t a2bus_agat840k_hle_device::read_cnxx(uint8_t offset)
|
||||
|
||||
legacy_floppy_image_device *a2bus_agat840k_hle_device::floppy_image(int drive)
|
||||
{
|
||||
const char *floppy_name = nullptr;
|
||||
|
||||
switch (drive)
|
||||
{
|
||||
case 0:
|
||||
floppy_name = FLOPPY_0;
|
||||
break;
|
||||
case 1:
|
||||
floppy_name = FLOPPY_1;
|
||||
break;
|
||||
switch(drive) {
|
||||
case 0 : return subdevice<legacy_floppy_image_device>(FLOPPY_0);
|
||||
case 1 : return subdevice<legacy_floppy_image_device>(FLOPPY_1);
|
||||
}
|
||||
return subdevice<legacy_floppy_image_device>(floppy_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// all signals active low. write support not implemented; WPT is always active.
|
||||
/*
|
||||
* all signals active low. write support not implemented; WPT is always active.
|
||||
*
|
||||
* b0-b1 type of drive 2: 00 - ES 5323.01 "1000 KB", 01 - "500 KB", 10 - "250 KB", 11 - not present
|
||||
* b2-b3 type of drive 1: -""-
|
||||
* b4 INDEX/SECTOR
|
||||
* b5 WRITE PROTECT
|
||||
* b6 TRACK 0
|
||||
* b7 READY
|
||||
*
|
||||
* C0x1
|
||||
*/
|
||||
READ8_MEMBER(a2bus_agat840k_hle_device::d14_i_b)
|
||||
{
|
||||
u8 data = 0x03; // one drive present, because drive select is broken
|
||||
u8 data = 0x3;
|
||||
|
||||
m_floppy->floppy_drive_set_ready_state(FLOPPY_DRIVE_READY, 1);
|
||||
|
||||
@ -373,7 +377,6 @@ READ8_MEMBER(a2bus_agat840k_hle_device::d14_i_b)
|
||||
*/
|
||||
WRITE8_MEMBER(a2bus_agat840k_hle_device::d14_o_c)
|
||||
{
|
||||
// drive select is broken in legacy flopdrv.cpp -- floppy_get_drive
|
||||
m_unit = BIT(data, 3);
|
||||
m_floppy = floppy_image(m_unit);
|
||||
if (m_unit)
|
||||
@ -402,6 +405,8 @@ WRITE8_MEMBER(a2bus_agat840k_hle_device::d14_o_c)
|
||||
data, m_unit, m_side, !BIT(data, 2), !BIT(data, 6), !BIT(data, 7));
|
||||
}
|
||||
|
||||
// C0x4
|
||||
//
|
||||
// data are latched in by write to PC4
|
||||
READ8_MEMBER(a2bus_agat840k_hle_device::d15_i_a)
|
||||
{
|
||||
|
488
src/devices/bus/a2bus/agat_fdc.cpp
Normal file
488
src/devices/bus/a2bus/agat_fdc.cpp
Normal file
@ -0,0 +1,488 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
agat_fdc.c
|
||||
|
||||
Implementation of the Agat 840K floppy controller card
|
||||
|
||||
Technical manual:
|
||||
http://agatcomp.ru/Reading/serkov/hainfo/023-01to.shtml
|
||||
http://agatcomp.ru/Reading/serkov/hainfo/023-01to1.shtml
|
||||
|
||||
Schematic:
|
||||
http://agatcomp.ru/Reading/fl800k/FD840/TEAC_023-adj-HI.jpg
|
||||
|
||||
On-disk format:
|
||||
https://github.com/sintech/AGAT/blob/master/docs/agat-840k-format.txt
|
||||
http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "agat_fdc.h"
|
||||
|
||||
#include "formats/aim_dsk.h"
|
||||
#include "formats/ds9_dsk.h"
|
||||
|
||||
|
||||
#define LOG_LSS (1U << 1) // Show warnings
|
||||
#define LOG_SHIFT (1U << 2) // Shows shift register contents
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL | LOG_SHIFT | LOG_LSS)
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGLSS(...) LOGMASKED(LOG_LSS, __VA_ARGS__)
|
||||
#define LOGSHIFT(...) LOGMASKED(LOG_SHIFT, __VA_ARGS__)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(A2BUS_AGAT_FDC, a2bus_agat_fdc_device, "agat_fdc", "Agat 840K floppy card")
|
||||
|
||||
#define AGAT_FDC_ROM_REGION "agat_fdc_rom"
|
||||
#define AGAT_FDC_ROM_D6_REGION "agat_fdc_d6_rom"
|
||||
|
||||
ROM_START( agat9 )
|
||||
ROM_REGION(0x100, AGAT_FDC_ROM_REGION, 0)
|
||||
// zagorsk
|
||||
ROM_LOAD( "teac.rom", 0x0000, 0x0100, CRC(94266928) SHA1(5d369bad6cdd6a70b0bb16480eba69640de87a2e) )
|
||||
|
||||
ROM_REGION(0x200, AGAT_FDC_ROM_D6_REGION, 0)
|
||||
ROM_LOAD( "d6encdec.bin", 0x0000, 0x0200, CRC(66e7e896) SHA1(b5305e82c81240a6fdc932a559b5493c59f302c6) )
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
|
||||
FLOPPY_FORMATS_MEMBER( a2bus_agat_fdc_device::floppy_formats )
|
||||
FLOPPY_DS9_FORMAT,
|
||||
FLOPPY_AIM_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
static void agat_floppies(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("525dsqd", FLOPPY_525_QD);
|
||||
}
|
||||
|
||||
void a2bus_agat_fdc_device::device_add_mconfig (machine_config &config)
|
||||
{
|
||||
FLOPPY_CONNECTOR(config, floppy0, agat_floppies, "525dsqd", a2bus_agat_fdc_device::floppy_formats);
|
||||
FLOPPY_CONNECTOR(config, floppy1, agat_floppies, "525dsqd", a2bus_agat_fdc_device::floppy_formats);
|
||||
|
||||
I8255(config, m_d14);
|
||||
// PA not connected
|
||||
m_d14->in_pb_callback().set(FUNC(a2bus_agat_fdc_device::d14_i_b)); // status signals from drive
|
||||
m_d14->out_pc_callback().set(FUNC(a2bus_agat_fdc_device::d14_o_c)); // control
|
||||
|
||||
I8255(config, m_d15);
|
||||
m_d15->in_pa_callback().set(FUNC(a2bus_agat_fdc_device::d15_i_a)); // read data
|
||||
// m_d15->out_pb_callback().set(FUNC(a2bus_agat_fdc_device::d15_o_b)); // write data
|
||||
m_d15->in_pc_callback().set(FUNC(a2bus_agat_fdc_device::d15_i_c));
|
||||
m_d15->out_pc_callback().set(FUNC(a2bus_agat_fdc_device::d15_o_c));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
const tiny_rom_entry *a2bus_agat_fdc_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( agat9 );
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
a2bus_agat_fdc_device::a2bus_agat_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_a2bus_card_interface(mconfig, *this)
|
||||
, m_d14(*this, "d14")
|
||||
, m_d15(*this, "d15")
|
||||
, floppy0(*this, "0")
|
||||
, floppy1(*this, "1")
|
||||
, m_rom(nullptr)
|
||||
, m_rom_d6(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
a2bus_agat_fdc_device::a2bus_agat_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
a2bus_agat_fdc_device(mconfig, A2BUS_AGAT_FDC, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void a2bus_agat_fdc_device::device_start()
|
||||
{
|
||||
set_unscaled_clock((XTAL(14'300'000) / 14.0) * 4.0);
|
||||
|
||||
m_rom = device().machine().root_device().memregion(this->subtag(AGAT_FDC_ROM_REGION).c_str())->base();
|
||||
m_rom_d6 = device().machine().root_device().memregion(this->subtag(AGAT_FDC_ROM_D6_REGION).c_str())->base();
|
||||
|
||||
floppy = nullptr;
|
||||
if (floppy0)
|
||||
{
|
||||
floppy = floppy0->get_device();
|
||||
}
|
||||
|
||||
m_mxcs = MXCSR_SYNC;
|
||||
|
||||
m_timer_lss = timer_alloc(TIMER_ID_LSS);
|
||||
m_timer_motor = timer_alloc(TIMER_ID_MOTOR);
|
||||
|
||||
m_seektime = 6; // ms, per es5323.txt
|
||||
m_waittime = 32; // us - 16 bits x 2 us
|
||||
}
|
||||
|
||||
void a2bus_agat_fdc_device::device_reset()
|
||||
{
|
||||
active = 0;
|
||||
cycles = time_to_cycles(machine().time());
|
||||
data_reg = 0x00;
|
||||
address = 0xff;
|
||||
|
||||
m_mxcs |= MXCSR_SYNC;
|
||||
m_mxcs &= ~MXCSR_TR;
|
||||
|
||||
// Just a timer to be sure that the lss is updated from time to
|
||||
// time, so that there's no hiccup when it's talked to again.
|
||||
m_timer_lss->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
|
||||
}
|
||||
|
||||
void a2bus_agat_fdc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_ID_LSS:
|
||||
lss_sync();
|
||||
break;
|
||||
|
||||
case TIMER_ID_MOTOR:
|
||||
active = 0;
|
||||
floppy->mon_w(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t a2bus_agat_fdc_device::time_to_cycles(const attotime &tm)
|
||||
{
|
||||
// Clock is falling edges of the ~4Mhz clock
|
||||
|
||||
uint64_t cycles = tm.as_ticks(clock()*2);
|
||||
cycles = (cycles+1) >> 1;
|
||||
return cycles;
|
||||
}
|
||||
|
||||
attotime a2bus_agat_fdc_device::cycles_to_time(uint64_t cycles)
|
||||
{
|
||||
return attotime::from_ticks(cycles*2+1, clock()*2);
|
||||
}
|
||||
|
||||
void a2bus_agat_fdc_device::lss_start()
|
||||
{
|
||||
cycles = time_to_cycles(machine().time()) + 1;
|
||||
data_reg = 0x00;
|
||||
address = 0xff;
|
||||
bits = 8;
|
||||
}
|
||||
|
||||
void a2bus_agat_fdc_device::lss_sync()
|
||||
{
|
||||
if(!active)
|
||||
return;
|
||||
|
||||
attotime next_flux = floppy ? floppy->get_next_transition(cycles_to_time(cycles-1)) : attotime::never;
|
||||
uint64_t cycles_limit = time_to_cycles(machine().time());
|
||||
uint64_t cycles_next_flux = next_flux != attotime::never ? time_to_cycles(next_flux) : uint64_t(-1);
|
||||
uint64_t cycles_next_flux_down = cycles_next_flux != uint64_t(-1) ? cycles_next_flux+1 : uint64_t(-1);
|
||||
|
||||
LOGLSS("LSS at %11.6f: %d (limit %d next %d) in %02x\n",
|
||||
machine().time().as_double(), cycles, cycles_limit, cycles_next_flux, address);
|
||||
|
||||
if(cycles >= cycles_next_flux && cycles < cycles_next_flux_down)
|
||||
address &= ~0x40;
|
||||
else
|
||||
address |= 0x40;
|
||||
|
||||
while (cycles < cycles_limit) {
|
||||
uint64_t cycles_next_trans = cycles_limit;
|
||||
if(cycles_next_trans > cycles_next_flux && cycles < cycles_next_flux)
|
||||
{
|
||||
cycles_next_trans = cycles_next_flux;
|
||||
LOGLSS("lss: next_trans up (%d < %d; %d)\n", cycles, cycles_next_flux, cycles_limit);
|
||||
}
|
||||
if(cycles_next_trans > cycles_next_flux_down && cycles < cycles_next_flux_down)
|
||||
{
|
||||
cycles_next_trans = cycles_next_flux_down;
|
||||
LOGLSS("lss: next_trans down (%d < %d; %d)\n", cycles, cycles_next_flux_down, cycles_limit);
|
||||
}
|
||||
|
||||
while (cycles < cycles_next_trans) {
|
||||
uint8_t opcode = m_rom_d6[address];
|
||||
|
||||
if (cycles_next_flux != uint64_t(-1))
|
||||
{
|
||||
LOGLSS("lss: %d (limit %d next %d) in %03x out %02x (addr %02x end %d bit %d sync %d)\n",
|
||||
cycles, cycles_limit, cycles_next_flux, address, opcode,
|
||||
opcode & 0x3f, BIT(opcode, 6), BIT(opcode, 5), BIT(opcode, 7));
|
||||
}
|
||||
if (!BIT(opcode, 6)) // end bit
|
||||
{
|
||||
data_reg <<= 1;
|
||||
data_reg |= !BIT(opcode, 5);
|
||||
LOGSHIFT("lss shift: %d (to %02x, %2d bits) at %d%s\n", BIT(opcode, 5), data_reg, bits, cycles,
|
||||
BIT(opcode, 7) ? " (sync)":"");
|
||||
|
||||
if (BIT(opcode, 7) == BIT(opcode, 5)) // hack
|
||||
{
|
||||
bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mxcs &= ~MXCSR_SYNC;
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
if (bits == 16)
|
||||
{
|
||||
address |= 0x80;
|
||||
m_d15->pc4_w(0);
|
||||
m_d15->pc4_w(1);
|
||||
bits = 8;
|
||||
LOGSHIFT("lss data: %02x\n", data_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
address &= ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
address &= ~0x3f;
|
||||
address |= (opcode & 0x3f);
|
||||
|
||||
cycles++;
|
||||
}
|
||||
|
||||
if(cycles == cycles_next_flux)
|
||||
address &= ~0x40;
|
||||
else if(cycles == cycles_next_flux_down) {
|
||||
address |= 0x40;
|
||||
next_flux = floppy ? floppy->get_next_transition(cycles_to_time(cycles)) : attotime::never;
|
||||
if (next_flux != attotime::never) {
|
||||
cycles_next_flux = time_to_cycles(next_flux);
|
||||
LOGLSS("lss next: %d cycles\n", cycles_next_flux+1-cycles_next_flux_down);
|
||||
cycles_next_flux_down = cycles_next_flux+1;
|
||||
} else {
|
||||
cycles_next_flux = uint64_t(-1);
|
||||
cycles_next_flux_down = uint64_t(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_c0nx - called for reads from this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t a2bus_agat_fdc_device::read_c0nx(uint8_t offset)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
lss_sync();
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
data = m_d14->read(offset);
|
||||
break;
|
||||
|
||||
case 4: case 5: case 6: case 7:
|
||||
data = m_d15->read(offset - 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
data = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_c0nx - called for writes to this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
void a2bus_agat_fdc_device::write_c0nx(uint8_t offset, uint8_t data)
|
||||
{
|
||||
lss_sync();
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
m_d14->write(offset, data);
|
||||
break;
|
||||
|
||||
case 4: case 5: case 6: case 7:
|
||||
m_d15->write(offset - 4, data);
|
||||
break;
|
||||
|
||||
case 8: // D9.15 - write desync
|
||||
break;
|
||||
|
||||
case 9: // D9.14 - step
|
||||
LOG("step at %11.6f\n", machine().time().as_double());
|
||||
if (floppy && active)
|
||||
{
|
||||
floppy->stp_w(1);
|
||||
floppy->stp_w(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 10: // D9.13 - reset desync flipflop
|
||||
m_mxcs |= MXCSR_SYNC;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_cnxx - called for reads from this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t a2bus_agat_fdc_device::read_cnxx(uint8_t offset)
|
||||
{
|
||||
return m_rom[offset];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* all signals active low. write support not implemented; WPT is always active.
|
||||
*
|
||||
* b0-b1 type of drive 2: 00 - ES 5323.01 "1000 KB", 01 - "500 KB", 10 - "250 KB", 11 - not present
|
||||
* b2-b3 type of drive 1: -""-
|
||||
* b4 INDEX/SECTOR
|
||||
* b5 WRITE PROTECT
|
||||
* b6 TRACK 0
|
||||
* b7 READY
|
||||
*
|
||||
* C0x1
|
||||
*/
|
||||
READ8_MEMBER(a2bus_agat_fdc_device::d14_i_b)
|
||||
{
|
||||
u8 data = 0x3;
|
||||
|
||||
// all signals active low
|
||||
if (floppy)
|
||||
{
|
||||
data |= (floppy->idx_r() << 4) ^ 0x10;
|
||||
// data |= floppy->wpt_r() << 5;
|
||||
data |= floppy->trk00_r() << 6;
|
||||
data |= floppy->ready_r() << 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
data |= 0xf0;
|
||||
}
|
||||
|
||||
LOG("status A: %s %s (t %d) %s %s\n", BIT(data, 7) ? "ready" : "READY", BIT(data, 6) ? "tk00" : "TK00",
|
||||
floppy ? floppy->get_cyl() : -1, BIT(data, 5) ? "wpt" : "WPT", BIT(data, 4) ? "index" : "INDEX");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* b0 AH strong write precomp
|
||||
* b1 -- NC
|
||||
* b2 -- step direction (1 - inward, 0 - outward)
|
||||
* b3 -- drive select (0 - drive 1, 1 - drive 2)
|
||||
* b4 -- head select (0 - bottom, 1 - top)
|
||||
* b5 AH write precomp off
|
||||
* b6 AH write enable
|
||||
* b7 AH motor on
|
||||
*
|
||||
* C0x2
|
||||
*/
|
||||
WRITE8_MEMBER(a2bus_agat_fdc_device::d14_o_c)
|
||||
{
|
||||
m_unit = BIT(data, 3);
|
||||
|
||||
if (floppy)
|
||||
{
|
||||
floppy->dir_w(!BIT(data, 2));
|
||||
floppy->ss_w(BIT(data, 4));
|
||||
// floppy->wtg_w(!BIT(data, 6));
|
||||
// floppy->mon_w(!BIT(data, 7)); // tied to 'drive select', 'motor on' and 'head load'
|
||||
}
|
||||
if (BIT(data, 7))
|
||||
{
|
||||
m_d15->pc4_w(0);
|
||||
m_d15->pc4_w(1);
|
||||
floppy->mon_w(0);
|
||||
if (!active)
|
||||
{
|
||||
active = 1;
|
||||
lss_start();
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
m_timer_motor->adjust(attotime::from_msec(1000));
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG("D14 C <- %02X (unit %d side %d drtn %d wtg %d mon %d)\n",
|
||||
data, m_unit, BIT(data, 4), !BIT(data, 2), !BIT(data, 6), !BIT(data, 7));
|
||||
}
|
||||
|
||||
// data are latched in by write to PC4
|
||||
READ8_MEMBER(a2bus_agat_fdc_device::d15_i_a)
|
||||
{
|
||||
return data_reg;
|
||||
}
|
||||
|
||||
// C0x6
|
||||
//
|
||||
// b6 AL desync detected
|
||||
// b7 AH read or write data ready
|
||||
READ8_MEMBER(a2bus_agat_fdc_device::d15_i_c)
|
||||
{
|
||||
LOG("status B: @ %4d %s %s\n", 0,
|
||||
BIT(m_mxcs, 7) ? "ready" : "READY", BIT(m_mxcs, 6) ? "SYNC" : "sync");
|
||||
|
||||
return m_mxcs;
|
||||
}
|
||||
|
||||
// C0x7
|
||||
//
|
||||
// b0 -- connected to b7, set if m_intr[PORT_B]
|
||||
// b2 AH b7 = ready for write data
|
||||
// b3 -- connected to b7, set if m_intr[PORT_A]
|
||||
// b4 AH b7 = read data ready
|
||||
WRITE8_MEMBER(a2bus_agat_fdc_device::d15_o_c)
|
||||
{
|
||||
if (BIT(data, 0) || BIT(data, 3))
|
||||
{
|
||||
m_mxcs |= MXCSR_TR;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mxcs &= ~MXCSR_TR;
|
||||
}
|
||||
}
|
||||
|
105
src/devices/bus/a2bus/agat_fdc.h
Normal file
105
src/devices/bus/a2bus/agat_fdc.h
Normal file
@ -0,0 +1,105 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
agat_fdc.h
|
||||
|
||||
Implementation of the Agat 840K floppy controller card
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_A2BUS_AGAT_FDC_H
|
||||
#define MAME_BUS_A2BUS_AGAT_FDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "a2bus.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/i8255.h"
|
||||
|
||||
|
||||
#define MXCSR_SYNC 0x40
|
||||
#define MXCSR_TR 0x80
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class a2bus_agat_fdc_device:
|
||||
public device_t,
|
||||
public device_a2bus_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a2bus_agat_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ8_MEMBER(d14_i_b);
|
||||
DECLARE_READ8_MEMBER(d15_i_a);
|
||||
DECLARE_READ8_MEMBER(d15_i_c);
|
||||
DECLARE_WRITE8_MEMBER(d14_o_c);
|
||||
DECLARE_WRITE8_MEMBER(d15_o_b);
|
||||
DECLARE_WRITE8_MEMBER(d15_o_c);
|
||||
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
a2bus_agat_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
// overrides of standard a2bus slot functions
|
||||
virtual uint8_t read_c0nx(uint8_t offset) override;
|
||||
virtual void write_c0nx(uint8_t offset, uint8_t data) override;
|
||||
virtual uint8_t read_cnxx(uint8_t offset) override;
|
||||
|
||||
enum
|
||||
{
|
||||
TIMER_ID_LSS = 0,
|
||||
TIMER_ID_SEEK,
|
||||
TIMER_ID_MOTOR
|
||||
};
|
||||
|
||||
required_device<i8255_device> m_d14;
|
||||
required_device<i8255_device> m_d15;
|
||||
|
||||
private:
|
||||
required_device<floppy_connector> floppy0;
|
||||
required_device<floppy_connector> floppy1;
|
||||
|
||||
uint64_t time_to_cycles(const attotime &tm);
|
||||
attotime cycles_to_time(uint64_t cycles);
|
||||
|
||||
void lss_start();
|
||||
void lss_sync();
|
||||
|
||||
floppy_image_device *floppy;
|
||||
int active, bits;
|
||||
uint8_t data_reg;
|
||||
uint16_t address;
|
||||
uint64_t cycles;
|
||||
|
||||
u8 m_mxcs;
|
||||
int m_unit;
|
||||
int m_state;
|
||||
|
||||
int m_seektime;
|
||||
int m_waittime;
|
||||
|
||||
emu_timer *m_timer_lss;
|
||||
emu_timer *m_timer_seek;
|
||||
emu_timer *m_timer_motor;
|
||||
|
||||
uint8_t *m_rom;
|
||||
uint8_t *m_rom_d6;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(A2BUS_AGAT_FDC, a2bus_agat_fdc_device)
|
||||
|
||||
#endif // MAME_BUS_A2BUS_AGAT_FDC_H
|
108
src/lib/formats/aim_dsk.cpp
Normal file
108
src/lib/formats/aim_dsk.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/aim_dsk.h
|
||||
|
||||
AIM disk images
|
||||
|
||||
References:
|
||||
- http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
|
||||
- http://agatcomp.ru/Soft/agat.shtml
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "aim_dsk.h"
|
||||
|
||||
|
||||
aim_format::aim_format()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char *aim_format::name() const
|
||||
{
|
||||
return "aim";
|
||||
}
|
||||
|
||||
|
||||
const char *aim_format::description() const
|
||||
{
|
||||
return "AIM disk image";
|
||||
}
|
||||
|
||||
|
||||
const char *aim_format::extensions() const
|
||||
{
|
||||
return "aim";
|
||||
}
|
||||
|
||||
|
||||
int aim_format::identify(io_generic *io, uint32_t form_factor)
|
||||
{
|
||||
if (io_generic_size(io) == 2068480)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool aim_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
|
||||
{
|
||||
image->set_variant(floppy_image::DSQD);
|
||||
|
||||
const int tracks = 80;
|
||||
const int track_size = 6464 * 2;
|
||||
const int heads = 2;
|
||||
|
||||
for (int track = 0; track < tracks; track++)
|
||||
{
|
||||
for (int head = 0; head < heads; head++)
|
||||
{
|
||||
std::vector<uint8_t> track_data(track_size);
|
||||
std::vector<uint32_t> raw_track_data;
|
||||
int data_count = 0;
|
||||
bool header = false;
|
||||
|
||||
// Read track
|
||||
io_generic_read(io, &track_data[0], ( heads * track + head ) * track_size, track_size);
|
||||
|
||||
for (int offset = 0; offset < track_size; offset += 2)
|
||||
{
|
||||
switch (track_data[offset + 1] & 1)
|
||||
{
|
||||
case 0:
|
||||
if (data_count == 0)
|
||||
header = (track_data[offset] == 0x95) ? true : false;
|
||||
data_count++;
|
||||
mfm_w(raw_track_data, 8, track_data[offset]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (header && data_count < 11) // XXX hack
|
||||
{
|
||||
for (; data_count < 12; data_count++)
|
||||
{
|
||||
mfm_w(raw_track_data, 8, 0xaa);
|
||||
}
|
||||
}
|
||||
raw_w(raw_track_data, 16, 0x8924);
|
||||
raw_w(raw_track_data, 16, 0x5555);
|
||||
data_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
generate_track_from_levels(track, head, raw_track_data, 0, image);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const floppy_format_type FLOPPY_AIM_FORMAT = &floppy_image_format_creator<aim_format>;
|
34
src/lib/formats/aim_dsk.h
Normal file
34
src/lib/formats/aim_dsk.h
Normal file
@ -0,0 +1,34 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/aim_dsk.h
|
||||
|
||||
AIM disk images
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef AIM_DSK_H
|
||||
#define AIM_DSK_H
|
||||
|
||||
#include "flopimg.h"
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
class aim_format : public floppy_image_format_t
|
||||
{
|
||||
public:
|
||||
aim_format();
|
||||
|
||||
virtual int identify(io_generic *io, uint32_t form_factor) override;
|
||||
virtual bool load(io_generic *io, uint32_t form_factor, floppy_image *image) override;
|
||||
|
||||
virtual const char *name() const override;
|
||||
virtual const char *description() const override;
|
||||
virtual const char *extensions() const override;
|
||||
virtual bool supports_save() const override { return false; }
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_AIM_FORMAT;
|
||||
|
||||
#endif /* AIM_DSK_H */
|
156
src/lib/formats/ds9_dsk.cpp
Normal file
156
src/lib/formats/ds9_dsk.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/**********************************************************************
|
||||
|
||||
formats/ds9_dsk.cpp
|
||||
|
||||
Floppies used by Agat-9 840KB controller
|
||||
|
||||
http://agatcomp.ru/Reading/docs/es5323.txt
|
||||
|
||||
https://github.com/sintech/AGAT/blob/master/docs/agat-840k-format.txt
|
||||
|
||||
http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "formats/ds9_dsk.h"
|
||||
|
||||
|
||||
static FLOPPY_IDENTIFY(ds9_dsk_identify)
|
||||
{
|
||||
switch (floppy_image_size(floppy))
|
||||
{
|
||||
case (80 * 2 * 21 * 256):
|
||||
case 860164:
|
||||
case 860288:
|
||||
*vote = 100;
|
||||
break;
|
||||
|
||||
default:
|
||||
*vote = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static FLOPPY_CONSTRUCT(ds9_dsk_construct)
|
||||
{
|
||||
struct basicdsk_geometry geometry;
|
||||
memset(&geometry, 0, sizeof(geometry));
|
||||
geometry.heads = 2;
|
||||
geometry.first_sector_id = 0;
|
||||
geometry.sector_length = 256;
|
||||
geometry.tracks = 80;
|
||||
geometry.sectors = 21;
|
||||
return basicdsk_construct(floppy, &geometry);
|
||||
}
|
||||
|
||||
LEGACY_FLOPPY_OPTIONS_START( ds9 )
|
||||
LEGACY_FLOPPY_OPTION( ds9_dsk, "ds9,dsk,raw", "Agat 840K DSK image",
|
||||
ds9_dsk_identify, ds9_dsk_construct, nullptr, nullptr)
|
||||
LEGACY_FLOPPY_OPTIONS_END
|
||||
|
||||
// exactly 6500 bytes
|
||||
const floppy_image_format_t::desc_e ds9_format::ds9_desc[] = {
|
||||
/* 01 */ { MFM, 0xaa, 32 }, // GAP1
|
||||
/* 02 */ { SECTOR_LOOP_START, 0, 20 }, // 21 sectors
|
||||
/* 03 */ { RAWBITS, 0x8924, 16 }, // sync mark: xA4, 2 us zero level interval, 0xFF
|
||||
/* 04 */ { RAWBITS, 0x5555, 16 },
|
||||
/* 05 */ { MFM, 0x95, 1 }, // address field prologue
|
||||
/* 06 */ { MFM, 0x6a, 1 },
|
||||
/* 07 */ { MFM, 0xfe, 1 }, // volume number
|
||||
/* 08 */ { OFFSET_ID },
|
||||
/* 09 */ { SECTOR_ID },
|
||||
/* 10 */ { MFM, 0x5a, 1 }, // address field epilogue
|
||||
/* 11 */ { MFM, 0xaa, 5 }, // GAP2 (min 4 bytes)
|
||||
/* 12 */ { RAWBITS, 0x8924, 16 }, // sync mark
|
||||
/* 13 */ { RAWBITS, 0x5555, 16 },
|
||||
/* 14 */ { MFM, 0x6a, 1 }, // data field prologue
|
||||
/* 15 */ { MFM, 0x95, 1 },
|
||||
/* 16 */ { SECTOR_DATA_DS9, -1 },
|
||||
/* 17 */ { MFM, 0x5a, 1 }, // data field epilogue
|
||||
/* 18 */ { MFM, 0xaa, 33 }, // GAP3
|
||||
/* 19 */ { SECTOR_LOOP_END },
|
||||
/* 20 */ { END }
|
||||
};
|
||||
|
||||
ds9_format::ds9_format()
|
||||
{
|
||||
}
|
||||
|
||||
const char *ds9_format::name() const
|
||||
{
|
||||
return "a9dsk";
|
||||
}
|
||||
|
||||
const char *ds9_format::description() const
|
||||
{
|
||||
return "Agat-9 840K floppy image";
|
||||
}
|
||||
|
||||
const char *ds9_format::extensions() const
|
||||
{
|
||||
return "ds9";
|
||||
}
|
||||
|
||||
void ds9_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count)
|
||||
{
|
||||
uint32_t expected_size = 0;
|
||||
uint64_t size = io_generic_size(io);
|
||||
|
||||
head_count = 2;
|
||||
track_count = 80;
|
||||
sector_count = 21;
|
||||
expected_size = 256 * track_count * head_count * sector_count;
|
||||
|
||||
if (size >= expected_size) // standard format has 860160 bytes
|
||||
return;
|
||||
|
||||
track_count = head_count = sector_count = 0;
|
||||
}
|
||||
|
||||
int ds9_format::identify(io_generic *io, uint32_t form_factor)
|
||||
{
|
||||
uint8_t track_count, head_count, sector_count;
|
||||
find_size(io, track_count, head_count, sector_count);
|
||||
|
||||
if (track_count) return 50;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ds9_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
|
||||
{
|
||||
uint8_t track_count, head_count, sector_count;
|
||||
find_size(io, track_count, head_count, sector_count);
|
||||
if (track_count == 0) return false;
|
||||
|
||||
uint8_t sectdata[21 * 256];
|
||||
desc_s sectors[21];
|
||||
for (int i = 0; i < sector_count; i++)
|
||||
{
|
||||
sectors[i].data = sectdata + 256 * i;
|
||||
sectors[i].size = 256;
|
||||
sectors[i].sector_id = i;
|
||||
}
|
||||
|
||||
int track_size = sector_count * 256;
|
||||
for (int track = 0; track < track_count; track++)
|
||||
{
|
||||
for (int head = 0; head < head_count; head++)
|
||||
{
|
||||
io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
|
||||
generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image);
|
||||
}
|
||||
}
|
||||
|
||||
image->set_variant(floppy_image::DSQD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const floppy_format_type FLOPPY_DS9_FORMAT = &floppy_image_format_creator<ds9_format>;
|
38
src/lib/formats/ds9_dsk.h
Normal file
38
src/lib/formats/ds9_dsk.h
Normal file
@ -0,0 +1,38 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/ds9_dsk.h
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef DS9_DSK_H_
|
||||
#define DS9_DSK_H_
|
||||
|
||||
#include "flopimg.h"
|
||||
#include "formats/basicdsk.h"
|
||||
|
||||
LEGACY_FLOPPY_OPTIONS_EXTERN(ds9);
|
||||
|
||||
class ds9_format : public floppy_image_format_t
|
||||
{
|
||||
public:
|
||||
ds9_format();
|
||||
|
||||
virtual int identify(io_generic *io, uint32_t form_factor) override;
|
||||
virtual bool load(io_generic *io, uint32_t form_factor, floppy_image *image) override;
|
||||
|
||||
virtual const char *name() const override;
|
||||
virtual const char *description() const override;
|
||||
virtual const char *extensions() const override;
|
||||
virtual bool supports_save() const override { return false; }
|
||||
|
||||
static const desc_e ds9_desc[];
|
||||
|
||||
private:
|
||||
void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count);
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_DS9_FORMAT;
|
||||
|
||||
#endif /* DS9_DSK_H_ */
|
177
src/lib/formats/dvk_mx_dsk.cpp
Normal file
177
src/lib/formats/dvk_mx_dsk.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/**********************************************************************
|
||||
|
||||
formats/dvk_mx_dsk.cpp
|
||||
|
||||
Floppies used by DVK MX: controller
|
||||
|
||||
http://torlus.com/floppy/forum/viewtopic.php?f=19&t=1384
|
||||
|
||||
Track format is almost entirely driver-dependent (only sync word
|
||||
0x00f3 is mandatory), because hardware always reads or writes
|
||||
entire track. 'old' format is used by stock driver, 'new' --
|
||||
by 3rd party one. Formatting tools produce yet other variants...
|
||||
|
||||
Floppy drives were 40- and 80-track, double-sided. 'new' driver
|
||||
also supports single-sided floppies.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "flopimg.h"
|
||||
#include "formats/dvk_mx_dsk.h"
|
||||
|
||||
const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_new_desc[] = {
|
||||
/* 01 */ { FM, 0x00, 8*2 }, // eight 0x0000 words
|
||||
/* 03 */ { FM, 0x00, 1 },
|
||||
/* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
|
||||
/* 05 */ { FM, 0x00, 1 },
|
||||
/* 04 */ { TRACK_ID_FM }, // track number word
|
||||
/* 05 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
|
||||
/* 07 */ { SECTOR_DATA_MX, -1 },
|
||||
/* 10 */ { SECTOR_LOOP_END },
|
||||
/* 13 */ { FM, 0x83, 1 },
|
||||
/* 12 */ { OFFSET_ID_FM },
|
||||
/* 15 */ { FM, 0x83, 1 },
|
||||
/* 14 */ { OFFSET_ID_FM },
|
||||
/* 17 */ { FM, 0x83, 1 },
|
||||
/* 16 */ { OFFSET_ID_FM },
|
||||
/* 18 */ { END }
|
||||
};
|
||||
|
||||
const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_old_desc[] = {
|
||||
/* 01 */ { FM, 0x00, 30*2 },
|
||||
/* 03 */ { FM, 0x00, 1 },
|
||||
/* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
|
||||
/* 05 */ { FM, 0x00, 1 },
|
||||
/* 04 */ { TRACK_ID_FM }, // track number word
|
||||
/* 06 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
|
||||
/* 07 */ { SECTOR_DATA_MX, -1 },
|
||||
/* 10 */ { SECTOR_LOOP_END },
|
||||
/* 13 */ { FM, 0x83, 1 },
|
||||
/* 11 */ { FM, 0x01, 1 },
|
||||
/* 15 */ { FM, 0x83, 1 },
|
||||
/* 14 */ { FM, 0x01, 1 },
|
||||
/* 16 */ { END }
|
||||
};
|
||||
|
||||
dvk_mx_format::dvk_mx_format()
|
||||
{
|
||||
}
|
||||
|
||||
const char *dvk_mx_format::name() const
|
||||
{
|
||||
return "mx";
|
||||
}
|
||||
|
||||
const char *dvk_mx_format::description() const
|
||||
{
|
||||
return "DVK MX: floppy image";
|
||||
}
|
||||
|
||||
const char *dvk_mx_format::extensions() const
|
||||
{
|
||||
return "mx";
|
||||
}
|
||||
|
||||
bool dvk_mx_format::supports_save() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count)
|
||||
{
|
||||
uint64_t size = io_generic_size(io);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 112640:
|
||||
track_count = 40;
|
||||
sector_count = 11;
|
||||
head_count = 1;
|
||||
break;
|
||||
case 225280:
|
||||
track_count = 40;
|
||||
sector_count = 11;
|
||||
head_count = 2;
|
||||
break;
|
||||
case 450560:
|
||||
track_count = 80;
|
||||
sector_count = 11;
|
||||
head_count = 2;
|
||||
break;
|
||||
default:
|
||||
track_count = head_count = sector_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int dvk_mx_format::identify(io_generic *io, uint32_t form_factor)
|
||||
{
|
||||
uint8_t track_count, head_count, sector_count;
|
||||
|
||||
find_size(io, track_count, head_count, sector_count);
|
||||
|
||||
if (track_count)
|
||||
{
|
||||
uint8_t sectdata[512];
|
||||
io_generic_read(io, sectdata, 512, 512);
|
||||
// check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp
|
||||
if (pick_integer_le(sectdata, 0724, 2) == 6)
|
||||
return 100;
|
||||
else
|
||||
return 75;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
|
||||
{
|
||||
uint8_t track_count, head_count, sector_count;
|
||||
|
||||
find_size(io, track_count, head_count, sector_count);
|
||||
if (track_count == 0) return false;
|
||||
|
||||
uint8_t sectdata[11 * 256];
|
||||
desc_s sectors[11];
|
||||
for (int i = 0; i < sector_count; i++)
|
||||
{
|
||||
sectors[i].data = sectdata + 256 * i;
|
||||
sectors[i].size = 256;
|
||||
sectors[i].sector_id = i;
|
||||
}
|
||||
|
||||
int track_size = sector_count * 256;
|
||||
for (int track = 0; track < track_count; track++)
|
||||
{
|
||||
for (int head = 0; head < head_count; head++)
|
||||
{
|
||||
io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
|
||||
generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image);
|
||||
}
|
||||
}
|
||||
|
||||
if (head_count == 1)
|
||||
{
|
||||
image->set_variant(floppy_image::SSDD);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (track_count > 40)
|
||||
{
|
||||
image->set_variant(floppy_image::DSQD);
|
||||
}
|
||||
else
|
||||
{
|
||||
image->set_variant(floppy_image::DSDD);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const floppy_format_type FLOPPY_DVK_MX_FORMAT = &floppy_image_format_creator<dvk_mx_format>;
|
39
src/lib/formats/dvk_mx_dsk.h
Normal file
39
src/lib/formats/dvk_mx_dsk.h
Normal file
@ -0,0 +1,39 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/dvk_mx_dsk.h
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef DVK_MX_DSK_H_
|
||||
#define DVK_MX_DSK_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flopimg.h"
|
||||
#include "imageutl.h"
|
||||
|
||||
class dvk_mx_format : public floppy_image_format_t
|
||||
{
|
||||
public:
|
||||
dvk_mx_format();
|
||||
|
||||
virtual int identify(io_generic *io, uint32_t form_factor) override;
|
||||
virtual bool load(io_generic *io, uint32_t form_factor, floppy_image *image) override;
|
||||
|
||||
virtual const char *name() const override;
|
||||
virtual const char *description() const override;
|
||||
virtual const char *extensions() const override;
|
||||
virtual bool supports_save() const override;
|
||||
|
||||
static const desc_e dvk_mx_old_desc[];
|
||||
static const desc_e dvk_mx_new_desc[];
|
||||
|
||||
private:
|
||||
void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count);
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_DVK_MX_FORMAT;
|
||||
|
||||
#endif /* DVK_MX_DSK_H_ */
|
@ -1038,6 +1038,7 @@ bool floppy_image_format_t::type_data_mfm(int type, int p1, const gen_crc_info *
|
||||
type == SIZE_ID ||
|
||||
type == OFFSET_ID_O ||
|
||||
type == OFFSET_ID_E ||
|
||||
type == OFFSET_ID_FM ||
|
||||
type == SECTOR_ID_O ||
|
||||
type == SECTOR_ID_E ||
|
||||
type == REMAIN_O ||
|
||||
@ -1521,6 +1522,14 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
|
||||
mfm_half_w(buffer, 6, track*2+head);
|
||||
break;
|
||||
|
||||
case OFFSET_ID_FM:
|
||||
fm_w(buffer, 8, track*2+head);
|
||||
break;
|
||||
|
||||
case OFFSET_ID:
|
||||
mfm_w(buffer, 8, track*2+head);
|
||||
break;
|
||||
|
||||
case SECTOR_ID_O:
|
||||
mfm_half_w(buffer, 7, sector_idx);
|
||||
break;
|
||||
@ -1650,6 +1659,37 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
|
||||
break;
|
||||
}
|
||||
|
||||
case SECTOR_DATA_MX: {
|
||||
const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
|
||||
uint16_t cksum = 0, data;
|
||||
for(int i=0; i < csect->size; i+=2)
|
||||
{
|
||||
data = csect->data[i+1];
|
||||
fm_w(buffer, 8, data);
|
||||
data = (data << 8) | csect->data[i];
|
||||
fm_w(buffer, 8, csect->data[i]);
|
||||
cksum += data;
|
||||
}
|
||||
fm_w(buffer, 16, cksum);
|
||||
break;
|
||||
}
|
||||
|
||||
case SECTOR_DATA_DS9: {
|
||||
const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
|
||||
uint8_t data;
|
||||
int cksum = 0;
|
||||
for(int i=0; i != csect->size; i++)
|
||||
{
|
||||
if (cksum > 255) { cksum++; cksum &= 255; }
|
||||
data = csect->data[i];
|
||||
mfm_w(buffer, 8, data);
|
||||
cksum += data;
|
||||
}
|
||||
cksum &= 255;
|
||||
mfm_w(buffer, 8, cksum);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("%d.%d.%d (%d) unhandled\n", desc[index].type, desc[index].p1, desc[index].p2, index);
|
||||
break;
|
||||
|
@ -333,6 +333,8 @@ protected:
|
||||
SECTOR_INFO_GCR6, //!< Sector info byte, gcr6-encoded
|
||||
OFFSET_ID_O, //!< Offset (track*2+head) byte, odd bits, mfm-encoded
|
||||
OFFSET_ID_E, //!< Offset (track*2+head) byte, even bits, mfm-encoded
|
||||
OFFSET_ID_FM, //!< Offset (track*2+head) byte, fm-encoded
|
||||
OFFSET_ID, //!< Offset (track*2+head) byte, mfm-encoded
|
||||
SECTOR_ID_O, //!< Sector id byte, odd bits, mfm-encoded
|
||||
SECTOR_ID_E, //!< Sector id byte, even bits, mfm-encoded
|
||||
REMAIN_O, //!< Remaining sector count, odd bits, mfm-encoded, total sector count in p1
|
||||
@ -345,6 +347,8 @@ protected:
|
||||
SECTOR_DATA_GCR5, //!< Sector data to gcr5-encode, which in p1, -1 for the current one per the sector id
|
||||
SECTOR_DATA_MAC, //!< Transformed sector data + checksum, mac style, id in p1, -1 for the current one per the sector id
|
||||
SECTOR_DATA_8N1, //!< Sector data to 8N1-encode, which in p1, -1 for the current one per the sector id
|
||||
SECTOR_DATA_MX, //!< Sector data to MX-encode, which in p1, -1 for the current one per the sector id
|
||||
SECTOR_DATA_DS9, //!< Sector data to DS9-encode, which in p1, -1 for the current one per the sector id
|
||||
|
||||
CRC_CCITT_START, //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
|
||||
CRC_CCITT_FM_START, //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -94,7 +94,9 @@ void agat7video_device::device_reset()
|
||||
|
||||
READ8_MEMBER(agat7video_device::read)
|
||||
{
|
||||
do_io(offset);
|
||||
if(!machine().side_effects_disabled())
|
||||
do_io(offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -110,7 +112,7 @@ void agat7video_device::do_io(int offset)
|
||||
{
|
||||
case 0:
|
||||
m_video_mode = GRAPHICS_LORES;
|
||||
m_start_address = (offset) << 9;
|
||||
m_start_address = (offset & 0x30) << 9;
|
||||
logerror("offset %04X, video mode 0 (GRAPHICS_LORES)\n", m_start_address);
|
||||
break;
|
||||
|
||||
@ -134,7 +136,7 @@ void agat7video_device::do_io(int offset)
|
||||
|
||||
case 3:
|
||||
m_video_mode = GRAPHICS_MONO;
|
||||
m_start_address = ((offset & 0x3f) - 0x03) << 9;
|
||||
m_start_address = ((offset - 0x03) & 0x30) << 9;
|
||||
logerror("offset %04X, video mode 3 (GRAPHICS_MONO)\n", m_start_address);
|
||||
break;
|
||||
}
|
||||
@ -184,14 +186,12 @@ void agat7video_device::text_update_lores(screen_device &screen, bitmap_ind16 &b
|
||||
address = m_start_address + (col * 2) + (row * 8);
|
||||
ch = m_ram_dev->read(address);
|
||||
attr = m_ram_dev->read(address + 1);
|
||||
fg = bitswap<8>(attr,7,6,5,3,4,2,1,0) & 15;
|
||||
if (BIT(attr, 5)) {
|
||||
fg = bitswap<8>(attr,7,6,5,3,4,2,1,0) & 15;
|
||||
bg = 0;
|
||||
plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, fg, bg);
|
||||
} else {
|
||||
fg = 0;
|
||||
bg = bitswap<8>(attr,7,6,5,3,4,2,1,0) & 15;
|
||||
plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, bg, fg);
|
||||
}
|
||||
plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,25 +352,3 @@ uint32_t agat7video_device::screen_update(screen_device &screen, bitmap_ind16 &b
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static const rgb_t agat7_palette[] =
|
||||
{
|
||||
rgb_t::black(),
|
||||
rgb_t(0xFF, 0x00, 0x00), /* White */
|
||||
rgb_t(0x00, 0xFF, 0x00), /* White */
|
||||
rgb_t(0xFF, 0xFF, 0x00), /* White */
|
||||
rgb_t(0x00, 0x00, 0xFF), /* White */
|
||||
rgb_t(0xFF, 0x00, 0xFF), /* White */
|
||||
rgb_t(0xFF, 0xFF, 0x00), /* White */
|
||||
rgb_t(0xFF, 0xFF, 0xFF), /* White */
|
||||
rgb_t::black(),
|
||||
rgb_t(0x7F, 0x00, 0x00), /* White */
|
||||
rgb_t(0x00, 0x7F, 0x00), /* White */
|
||||
rgb_t(0x7F, 0x7F, 0x00), /* White */
|
||||
rgb_t(0x00, 0x00, 0x7F), /* White */
|
||||
rgb_t(0x7F, 0x00, 0x7F), /* White */
|
||||
rgb_t(0x7F, 0x7F, 0x00), /* White */
|
||||
rgb_t(0x7F, 0x7F, 0x7F) /* White */
|
||||
};
|
||||
#endif
|
||||
|
715
src/mame/video/agat9.cpp
Normal file
715
src/mame/video/agat9.cpp
Normal file
@ -0,0 +1,715 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
agat9video.cpp
|
||||
|
||||
Implementation of Agat-9 onboard video.
|
||||
|
||||
6 native video modes:
|
||||
- 32x32 color text
|
||||
- 64x32 mono text with reverse video
|
||||
- 128x128 16 color graphics
|
||||
- 256x256 4 color graphics
|
||||
- 256x256 and 512x256 mono graphics
|
||||
|
||||
2 apple video modes: 40col text and HGR.
|
||||
|
||||
C7xx: video mode select
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "video/agat9.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
#define BLACK 0
|
||||
#define RED 1
|
||||
#define GREEN 2
|
||||
#define YELLOW 3
|
||||
#define BLUE 4
|
||||
#define PURPLE 5
|
||||
#define CYAN 6
|
||||
#define WHITE 7
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(AGAT9VIDEO, agat9video_device, "agat9video", "Agat-9 Video")
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
|
||||
void agat9video_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(XTAL(10'500'000), 672, 0, 512, 312, 0, 256);
|
||||
m_screen->set_screen_update(FUNC(agat9video_device::screen_update));
|
||||
m_screen->set_palette(DEVICE_SELF);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
agat9video_device::agat9video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, AGAT9VIDEO, tag, owner, clock),
|
||||
device_palette_interface(mconfig, *this),
|
||||
m_screen(*this, "a9screen"),
|
||||
m_ram_dev(*this, finder_base::DUMMY_TAG),
|
||||
m_char_region(*this, finder_base::DUMMY_TAG),
|
||||
m_char_ptr(nullptr),
|
||||
m_char_size(0),
|
||||
m_start_address(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void agat9video_device::device_start()
|
||||
{
|
||||
int i, j;
|
||||
uint16_t c;
|
||||
|
||||
static const uint8_t hires_artifact_color_table[] =
|
||||
{
|
||||
BLACK, PURPLE, GREEN, WHITE,
|
||||
BLACK, BLUE, RED, WHITE
|
||||
};
|
||||
|
||||
m_char_ptr = m_char_region->base();
|
||||
m_char_size = m_char_region->bytes();
|
||||
|
||||
/* 2^3 dependent pixels * 2 color sets * 2 offsets */
|
||||
m_hires_artifact_map = std::make_unique<uint16_t[]>(8 * 2 * 2);
|
||||
|
||||
/* build hires artifact map */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (i & 0x02)
|
||||
{
|
||||
if ((i & 0x05) != 0)
|
||||
c = 3;
|
||||
else
|
||||
c = j ? 2 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = 0;
|
||||
}
|
||||
m_hires_artifact_map[0 + j * 8 + i] = hires_artifact_color_table[(c + 0) % 8];
|
||||
m_hires_artifact_map[16 + j * 8 + i] = hires_artifact_color_table[(c + 4) % 8];
|
||||
}
|
||||
}
|
||||
|
||||
// per http://agatcomp.ru/Reading/IiO/87-2-077.djvu
|
||||
for (int i = 0; 8 > i; ++i)
|
||||
{
|
||||
set_pen_color(i + 0, rgb_t(BIT(i, 0) ? 0xff : 0, BIT(i, 1) ? 0xff : 0, BIT(i, 2) ? 0xff : 0));
|
||||
set_pen_color(i + 8, rgb_t(BIT(i, 0) ? 0x7f : 0, BIT(i, 1) ? 0x7f : 0, BIT(i, 2) ? 0x7f : 0));
|
||||
}
|
||||
|
||||
save_item(NAME(m_start_address));
|
||||
|
||||
save_item(NAME(m_page2));
|
||||
save_item(NAME(m_flash));
|
||||
save_item(NAME(m_mix));
|
||||
save_item(NAME(m_graphics));
|
||||
}
|
||||
|
||||
void agat9video_device::device_reset()
|
||||
{
|
||||
// XXX to be confirmed
|
||||
m_video_mode = TEXT_LORES;
|
||||
m_start_address = 0x7800;
|
||||
m_mode = palette_index = 0;
|
||||
|
||||
// apple
|
||||
m_page2 = false;
|
||||
m_flash = false;
|
||||
m_mix = false;
|
||||
m_graphics = false;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(agat9video_device::read)
|
||||
{
|
||||
if(!machine().side_effects_disabled())
|
||||
do_io(offset);
|
||||
// XXX only 'Moscow' revision
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(agat9video_device::write)
|
||||
{
|
||||
do_io(offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER(agat9video_device::apple_read)
|
||||
{
|
||||
logerror("%s: %04x read (%s)\n", machine().describe_context(), 0xc050 + offset, offset<8?"apple":"palette");
|
||||
|
||||
if(!machine().side_effects_disabled())
|
||||
do_apple_io(offset);
|
||||
// XXX
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(agat9video_device::apple_write)
|
||||
{
|
||||
logerror("%s: %04x write (%s)\n", machine().describe_context(), 0xc050 + offset, offset<8?"apple":"palette");
|
||||
|
||||
do_apple_io(offset);
|
||||
}
|
||||
|
||||
void agat9video_device::do_apple_io(int offset)
|
||||
{
|
||||
if (offset < 0x8)
|
||||
{
|
||||
m_video_mode = APPLE;
|
||||
m_screen->set_visible_area(0, 280-1, 0, 192-1);
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x0:
|
||||
m_graphics = true;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
m_graphics = false;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
m_mix = false;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
m_mix = true;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
m_page2 = false;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
m_page2 = true;
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
palette_index &= 0xfe;
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
palette_index |= 0x01;
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
palette_index &= 0xfd;
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
palette_index |= 0x02;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::do_io(int offset)
|
||||
{
|
||||
logerror("%s: %04x access, ", machine().describe_context(), 0xc700 + offset);
|
||||
|
||||
m_mode = offset;
|
||||
|
||||
m_screen->set_visible_area(0, 2*256-1, 0, 256-1);
|
||||
|
||||
switch (offset & 3)
|
||||
{
|
||||
case 0:
|
||||
// 256x256, 4 colors, 64 bytes per scanline, 0x4000 page length, odd scanlines at 0x2000
|
||||
m_video_mode = GRAPHICS_COLOR_HIRES;
|
||||
m_start_address = ((offset & 0x60) << 9) + ((offset & 0x08) << 13);
|
||||
logerror("offset %04X, video mode 0 (COLOR_HIRES)\n", m_start_address);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// 128x128, 16 colors, 64 bytes per scanline, 0x2000 page length, linear
|
||||
m_video_mode = GRAPHICS_COLOR_LORES;
|
||||
m_start_address = ((offset & 0x70) << 9) + ((offset & 0x08) << 13);
|
||||
logerror("offset %04X, video mode 1 (COLOR_LORES)\n", m_start_address);
|
||||
break;
|
||||
|
||||
// b6..b4 == page number, b3..b2 == subpage number
|
||||
case 2:
|
||||
// 64x32, 0x1000 page length
|
||||
if (offset > 0x80)
|
||||
{
|
||||
m_video_mode = TEXT_HIRES;
|
||||
m_start_address = (offset - 0x82) << 9;
|
||||
logerror("offset %04X, video mode 2 (TEXT_HIRES)\n", m_start_address);
|
||||
}
|
||||
// 32x32, 0x1000 page length
|
||||
else
|
||||
{
|
||||
m_video_mode = TEXT_LORES;
|
||||
m_start_address = (offset - 0x02) << 9;
|
||||
logerror("offset %04X, video mode 2 (TEXT_LORES)\n", m_start_address);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// 512x256, 64 bytes per scanline, 0x4000 page length, odd scanlines at 0x2000
|
||||
if (offset > 0x80)
|
||||
{
|
||||
m_video_mode = GRAPHICS_MONO_HIRES;
|
||||
m_start_address = ((offset & 0x60) << 9) + ((offset & 0x08) << 13);
|
||||
logerror("offset %04X, video mode 3 (MONO_HIRES)\n", m_start_address);
|
||||
}
|
||||
// 256x256, 32 bytes per scanline, 0x2000 page length, linear
|
||||
else
|
||||
{
|
||||
m_video_mode = GRAPHICS_MONO_LORES;
|
||||
m_start_address = ((offset & 0x70) << 9) + ((offset & 0x08) << 13);
|
||||
logerror("offset %04X, video mode 3 (MONO_LORES)\n", m_start_address);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void agat9video_device::plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code,
|
||||
const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg)
|
||||
{
|
||||
int x, y, i;
|
||||
const uint8_t *chardata;
|
||||
uint16_t color;
|
||||
|
||||
/* look up the character data */
|
||||
chardata = &textgfx_data[(code * 8)];
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
color = (chardata[y] & (1 << (7 - x))) ? fg : bg;
|
||||
|
||||
for (i = 0; i < xscale; i++)
|
||||
{
|
||||
bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int color_1_p[4] =
|
||||
{
|
||||
0, 4, 0, 5
|
||||
};
|
||||
|
||||
int color_2_p[4][2] =
|
||||
{
|
||||
{ 0, 7 },
|
||||
{ 7, 0 },
|
||||
{ 0, 2 },
|
||||
{ 2, 0 },
|
||||
};
|
||||
|
||||
void agat9video_device::text_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col;
|
||||
uint32_t address;
|
||||
uint8_t ch, attr;
|
||||
int fg = 0;
|
||||
int bg = color_1_p[palette_index];
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 32; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = m_start_address + (col * 2) + (row * 8);
|
||||
ch = m_ram_dev->read(address);
|
||||
attr = m_ram_dev->read(address + 1);
|
||||
fg = bitswap<8>(attr,7,6,5,3,4,2,1,0) & 15;
|
||||
if (BIT(attr, 5)) {
|
||||
plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, fg, bg);
|
||||
} else {
|
||||
plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, bg, fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::text_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col;
|
||||
uint32_t address;
|
||||
uint8_t ch;
|
||||
int fg, bg;
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
if (m_start_address & 0x800)
|
||||
{
|
||||
fg = color_2_p[palette_index][1];
|
||||
bg = color_2_p[palette_index][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
fg = color_2_p[palette_index][0];
|
||||
bg = color_2_p[palette_index][1];
|
||||
}
|
||||
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 64; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = m_start_address + col + (row * 8);
|
||||
ch = m_ram_dev->read(address);
|
||||
plot_text_character(bitmap, col * 8, row, 1, ch, m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::graph_update_mono_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, b;
|
||||
uint32_t address;
|
||||
uint16_t *p;
|
||||
uint8_t gfx, v;
|
||||
int fg = 7, bg = 0;
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
p = &bitmap.pix16(row);
|
||||
for (col = 0; col < 32; col++)
|
||||
{
|
||||
address = m_start_address + col + (row * 0x20);
|
||||
gfx = m_ram_dev->read(address);
|
||||
|
||||
for (b = 0; b < 8; b++)
|
||||
{
|
||||
v = (gfx & 0x80) >> 7;
|
||||
v = color_2_p[palette_index][v];
|
||||
gfx <<= 1;
|
||||
*(p++) = v ? fg : bg;
|
||||
*(p++) = v ? fg : bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::graph_update_mono_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, b;
|
||||
uint32_t address;
|
||||
uint16_t *p;
|
||||
uint8_t gfx, v;
|
||||
int fg = 7, bg = 0;
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
p = &bitmap.pix16(row);
|
||||
for (col = 0; col < 64; col++)
|
||||
{
|
||||
address = m_start_address + col + ((row / 2) * 0x40) + 0x2000 * (row & 1);
|
||||
gfx = m_ram_dev->read(address);
|
||||
|
||||
for (b = 0; b < 8; b++)
|
||||
{
|
||||
v = (gfx & 0x80) >> 7;
|
||||
v = color_2_p[palette_index][v];
|
||||
gfx <<= 1;
|
||||
*(p++) = v ? fg : bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int color_4_p[4][4] =
|
||||
{
|
||||
{ 0, 1, 2, 4 },
|
||||
{ 7, 1, 2, 4 },
|
||||
{ 0, 0, 2, 4 },
|
||||
{ 0, 1, 0, 4 }
|
||||
};
|
||||
|
||||
void agat9video_device::graph_update_color_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, b;
|
||||
uint32_t address;
|
||||
uint16_t *p;
|
||||
uint8_t gfx, v;
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
p = &bitmap.pix16(row);
|
||||
for (col = 0; col < 0x40; col++)
|
||||
{
|
||||
address = m_start_address + col + ((row / 2) * 0x40) + 0x2000 * (row & 1);
|
||||
gfx = m_ram_dev->read(address);
|
||||
|
||||
for (b = 0; b < 4; b++)
|
||||
{
|
||||
v = (gfx & 0xc0) >> 6;
|
||||
v = color_4_p[palette_index][v];
|
||||
gfx <<= 2;
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::graph_update_color_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, b;
|
||||
uint32_t address;
|
||||
uint16_t *p;
|
||||
uint8_t gfx, v;
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
p = &bitmap.pix16(row);
|
||||
for (col = 0; col < 0x40; col++)
|
||||
{
|
||||
address = m_start_address + col + ((row / 2) * 0x40);
|
||||
gfx = m_ram_dev->read(address);
|
||||
|
||||
for (b = 0; b < 2; b++)
|
||||
{
|
||||
v = (gfx & 0xf0) >> 4;
|
||||
gfx <<= 4;
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apple ][ video modes
|
||||
|
||||
void agat9video_device::plot_text_character_apple(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code,
|
||||
const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg)
|
||||
{
|
||||
int x, y, i;
|
||||
const uint8_t *chardata;
|
||||
uint16_t color;
|
||||
|
||||
if ((code >= 0x40) && (code <= 0x7f))
|
||||
{
|
||||
code &= 0x3f;
|
||||
|
||||
if (m_flash)
|
||||
{
|
||||
i = fg;
|
||||
fg = bg;
|
||||
bg = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* look up the character data */
|
||||
chardata = &textgfx_data[(code * 8)];
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
color = (chardata[y] & (1 << (6 - x))) ? fg : bg;
|
||||
|
||||
for (i = 0; i < xscale; i++)
|
||||
{
|
||||
bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::text_update_apple(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col;
|
||||
uint32_t start_address;
|
||||
uint32_t address;
|
||||
int fg, bg;
|
||||
|
||||
start_address = m_page2 ? 0x800 : 0x400;
|
||||
|
||||
fg = color_2_p[palette_index][1];
|
||||
bg = color_2_p[palette_index][0];
|
||||
|
||||
beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
plot_text_character_apple(bitmap, col * 7, row, 1, m_ram_dev->read(address),
|
||||
m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void agat9video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, b, va;
|
||||
int offset;
|
||||
uint8_t vram_row[42];
|
||||
uint16_t v;
|
||||
uint16_t *p;
|
||||
uint32_t w;
|
||||
uint16_t *artifact_map_ptr;
|
||||
int begincol = 0, endcol = 40;
|
||||
|
||||
/* sanity checks */
|
||||
if (beginrow < cliprect.min_y)
|
||||
beginrow = cliprect.min_y;
|
||||
if (endrow > cliprect.max_y)
|
||||
endrow = cliprect.max_y;
|
||||
if (endrow < beginrow)
|
||||
return;
|
||||
|
||||
// we generate 2 pixels per "column" so adjust
|
||||
if (begincol < (cliprect.min_x/7))
|
||||
begincol = (cliprect.min_x/7);
|
||||
if (endcol > (cliprect.max_x/7))
|
||||
endcol = (cliprect.max_x/7);
|
||||
if (cliprect.max_x > 39*7)
|
||||
endcol = 40;
|
||||
if (endcol < begincol)
|
||||
return;
|
||||
|
||||
va = m_page2 ? 0x4000 : 0x2000;
|
||||
|
||||
vram_row[0] = 0;
|
||||
vram_row[41] = 0;
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
for (col = begincol; col < endcol; col++)
|
||||
{
|
||||
offset = ((((row / 8) & 0x07) << 7) | (((row / 8) & 0x18) * 5 + col)) | ((row & 7) << 10);
|
||||
vram_row[1 + col] = m_ram_dev->read(va + offset);
|
||||
}
|
||||
|
||||
p = &bitmap.pix16(row);
|
||||
|
||||
/*
|
||||
* p. 50 of technical manual:
|
||||
*
|
||||
* 1. a 'zero' bit is always drawn as 'black' pixel
|
||||
* 2. two consecutive 'one' bits are always drawn as 'white' pixel, even bits from different bytes
|
||||
* 3. even pixels can be 'black', 'purple' (5) or 'blue' (4)
|
||||
* 4. odd pixels can be 'black', 'green' (2) or 'red' (1)
|
||||
* 5. bit 7 affects color of pixels in this byte. zero = 'blue' or 'red', one = 'purple' or 'green'.
|
||||
*/
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
w = (((uint32_t) vram_row[col+0] & 0x7f) << 0)
|
||||
| (((uint32_t) vram_row[col+1] & 0x7f) << 7)
|
||||
| (((uint32_t) vram_row[col+2] & 0x7f) << 14);
|
||||
|
||||
artifact_map_ptr = &m_hires_artifact_map[((vram_row[col + 1] & 0x80) >> 7) * 16];
|
||||
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = artifact_map_ptr[((w >> (b + 7 - 1)) & 0x07) | (((b ^ col) & 0x01) << 3)];
|
||||
*(p++) = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t agat9video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
switch (m_video_mode)
|
||||
{
|
||||
case APPLE: // from apple2e.cpp
|
||||
// always update the flash timer here so it's smooth regardless of mode switches
|
||||
m_flash = ((machine().time() * 4).seconds() & 1) ? true : false;
|
||||
|
||||
if (m_graphics)
|
||||
{
|
||||
if (m_mix)
|
||||
{
|
||||
hgr_update(screen, bitmap, cliprect, 0, 159);
|
||||
text_update_apple(screen, bitmap, cliprect, 160, 191);
|
||||
}
|
||||
else
|
||||
{
|
||||
hgr_update(screen, bitmap, cliprect, 0, 191);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text_update_apple(screen, bitmap, cliprect, 0, 191);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_LORES:
|
||||
text_update_lores(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
case TEXT_HIRES:
|
||||
text_update_hires(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
case GRAPHICS_MONO_LORES:
|
||||
graph_update_mono_lores(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
case GRAPHICS_MONO_HIRES:
|
||||
graph_update_mono_hires(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
case GRAPHICS_COLOR_LORES:
|
||||
graph_update_color_lores(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
case GRAPHICS_COLOR_HIRES:
|
||||
graph_update_color_hires(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
|
||||
default:
|
||||
graph_update_mono_lores(screen, bitmap, cliprect, 0, 255);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
96
src/mame/video/agat9.h
Normal file
96
src/mame/video/agat9.h
Normal file
@ -0,0 +1,96 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
agat9video.h
|
||||
|
||||
Implementation of Agat-9 onboard video.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_VIDEO_AGAT9_H
|
||||
#define MAME_VIDEO_AGAT9_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/ram.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class agat9video_device : public device_t, public device_palette_interface
|
||||
{
|
||||
public:
|
||||
template <typename T, typename U>
|
||||
agat9video_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&ram_tag, U &&char_tag)
|
||||
: agat9video_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
m_ram_dev.set_tag(std::forward<T>(ram_tag));
|
||||
m_char_region.set_tag(std::forward<U>(char_tag));
|
||||
}
|
||||
|
||||
agat9video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ8_MEMBER(read);
|
||||
DECLARE_WRITE8_MEMBER(write);
|
||||
DECLARE_READ8_MEMBER(apple_read);
|
||||
DECLARE_WRITE8_MEMBER(apple_write);
|
||||
|
||||
bool m_page2;
|
||||
bool m_flash;
|
||||
bool m_mix;
|
||||
bool m_graphics;
|
||||
std::unique_ptr<uint16_t[]> m_hires_artifact_map;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
virtual u32 palette_entries() const override { return 16; }
|
||||
|
||||
void text_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void text_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void graph_update_mono_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void graph_update_mono_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void graph_update_color_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void graph_update_color_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
|
||||
void text_update_apple(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void hgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
|
||||
private:
|
||||
void do_io(int offset);
|
||||
void do_apple_io(int offset);
|
||||
|
||||
void plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code, const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg);
|
||||
void plot_text_character_apple(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code, const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<ram_device> m_ram_dev;
|
||||
required_memory_region m_char_region;
|
||||
|
||||
uint8_t *m_char_ptr;
|
||||
int m_char_size;
|
||||
uint32_t m_start_address;
|
||||
enum {
|
||||
TEXT_LORES = 0,
|
||||
TEXT_HIRES,
|
||||
GRAPHICS_COLOR_LORES,
|
||||
GRAPHICS_COLOR_HIRES,
|
||||
GRAPHICS_MONO_LORES,
|
||||
GRAPHICS_MONO_HIRES,
|
||||
APPLE
|
||||
} m_video_mode;
|
||||
int m_mode;
|
||||
int palette_index;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(AGAT9VIDEO, agat9video_device)
|
||||
|
||||
#endif // MAME_VIDEO_AGAT9_H
|
@ -51,6 +51,10 @@
|
||||
|
||||
#include "formats/hpi_dsk.h"
|
||||
|
||||
#include "formats/dvk_mx_dsk.h"
|
||||
#include "formats/aim_dsk.h"
|
||||
|
||||
|
||||
static floppy_format_type floppy_formats[] = {
|
||||
FLOPPY_MFI_FORMAT,
|
||||
FLOPPY_DFI_FORMAT,
|
||||
@ -89,7 +93,10 @@ static floppy_format_type floppy_formats[] = {
|
||||
|
||||
FLOPPY_APPLIX_FORMAT,
|
||||
|
||||
FLOPPY_HPI_FORMAT
|
||||
FLOPPY_HPI_FORMAT,
|
||||
|
||||
FLOPPY_DVK_MX_FORMAT,
|
||||
FLOPPY_AIM_FORMAT
|
||||
};
|
||||
|
||||
void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...)
|
||||
|
Loading…
Reference in New Issue
Block a user