Compare commits

...

38 commits
v5.0 ... master

Author SHA1 Message Date
Rob Tuccitto
7a2afdc1ea
Update a7800.cpp
Proper external source reference
2024-11-16 23:33:03 -05:00
Rob Tuccitto
bdcdd0246a
Merge pull request #24 from trebor68/master
Fixed palette washout and color clipping.
2024-11-11 23:12:10 -05:00
Rob Tuccitto
6aeb297b9c
Fixed palette washout and color clipping. 2024-11-11 23:09:33 -05:00
Rob Tuccitto
72e73ffb60
Merge pull request #21 from trebor68/master
Luminance, dominant palette, nomenclature updates
2024-07-06 09:52:43 -04:00
Rob Tuccitto
1f2a3d946f
Luminance and nomenclature updates.
Luminance fix, dominant palette updates, nomenclature corrected.
2024-07-06 09:50:21 -04:00
Rob Tuccitto
dffb7cad53
Order and nomenclature fix.
Respective dominant palette temperature set to primary machine across both regions.
Alternate palette temperature and corresponding machines nomenclature corrected.
2024-07-06 09:47:50 -04:00
Rob Tuccitto
172d3c7342
Merge pull request #20 from trebor68/master
Palette order restored. Verified HW impact to PAL.
2024-02-10 21:25:22 -05:00
Rob Tuccitto
3fcf439cec
Palette order restores. Verified HW impact to PAL.
Restored palette logic order:  Cool --> Warm (u1) --> Hot (u2) for both regions.  Verified with intended original hardware combination, the effect to PAL palette.
2024-02-10 21:22:07 -05:00
Rob Tuccitto
cf5de6eb97
Remove display variance factor for PAL
Remove CRT variance factor for PAL palettes.  Extremely significant for NTSC, typically subtle to non-existent respecting PAL.
2024-01-20 23:55:14 -05:00
Rob Tuccitto
163e43aa26
Merge pull request #19 from trebor68/master
Height crop fine-tuning.
2023-12-03 20:49:38 -05:00
Rob Tuccitto
caac9c7298
Height crop fine-tuning. 2023-12-03 20:47:31 -05:00
Rob Tuccitto
94ea89f998
Merge pull request #18 from trebor68/master
Added associated update notes.
2023-12-03 19:26:00 -05:00
Rob Tuccitto
db59cf7ade
Added associated update notes. 2023-12-03 19:24:05 -05:00
Rob Tuccitto
121422d794
Merge pull request #17 from trebor68/master
PAL and NTSC entangled palettes fixed.
2023-12-03 18:08:08 -05:00
Rob Tuccitto
4cb7d47324
Case matters 2023-12-03 17:55:52 -05:00
Rob Tuccitto
8a46f26dbd
Untangle PAL from NTSC Part 2 - Cool and Hot 2023-12-03 13:38:27 -05:00
Rob Tuccitto
ecca587b7d
Untangle PAL from NTSC Part 1 - Warm 2023-12-02 16:41:16 -05:00
Rob Tuccitto
26aec227c4
Merge pull request #16 from trebor68/master
updated notes
2023-11-28 07:06:55 -05:00
Rob Tuccitto
571b11acb4
updated notes 2023-11-28 07:04:26 -05:00
Rob Tuccitto
6a4827d0b5
Merge pull request #14 from trebor68/master
Updated to TREBORS_ATARI_PRO_PALETTES_V3
2023-10-11 21:09:54 -04:00
Rob Tuccitto
f30781271b
Updated to TREBORS_ATARI_PRO_PALETTES_V3
-Luminance ramp properly calibrated per CPS 7800 Diagnostic Test Cartridge for cool, warm, and hot palettes. Ensures all intended graphic details, difference in shading, and color distinction is visible.
2023-10-11 21:07:36 -04:00
Rob Tuccitto
b06cf3e74d
Allow contrast to be adjusted in step with brightness 2023-10-06 22:19:49 -04:00
Rob Tuccitto
307ad734b9
Formatting - Pt 2 2023-09-05 18:36:42 -04:00
Rob Tuccitto
f60f8b6254
Update a7800.cpp - formatting 2023-09-04 11:23:09 -04:00
Rob Tuccitto
c913882c9b
Palettes and driver notes updated 2023-08-23 23:57:25 -04:00
msaarna@gmail.com
4dbf85ea90 up the version to 5.2 2022-06-20 08:55:54 -04:00
msaarna@gmail.com
53c8b4ed70 fix poly9 and default boot state is in-reset 2022-06-08 08:51:42 -04:00
msaarna@gmail.com
861fb14574 comment update 2022-05-02 00:20:33 -04:00
msaarna@gmail.com
13db9390ab fix supergame+cart_ram+pokey part 2 2022-04-29 17:02:33 -04:00
msaarna@gmail.com
406ab98965 fix supergame+cart_ram+pokey 2022-04-29 16:55:16 -04:00
msaarna@gmail.com
ab83f5f651 pokey two-tone fixes 2022-04-26 20:42:20 -04:00
msaarna@gmail.com
a87d4ebe92 Merge branch 'master' of https://github.com/7800-devtools/a7800 2022-04-10 11:49:38 -04:00
msaarna@gmail.com
95731552d8 fix poly17 2022-04-10 11:49:24 -04:00
trebor68
f038eae0d8
Update README.md 2022-04-04 12:22:14 -04:00
msaarna@gmail.com
67a975207f silence debug output 2022-04-03 18:49:25 -04:00
msaarna@gmail.com
8b623a2cc8 revert poly17/poly9 2022-04-03 18:34:58 -04:00
msaarna@gmail.com
bd5604a6f7 update poly17/poly9 2022-04-03 18:16:02 -04:00
msaarna@gmail.com
e0dded6b96 fix poly5 2022-04-03 14:58:16 -04:00
11 changed files with 1059 additions and 687 deletions

View file

@ -6,8 +6,17 @@ A7800 is a fork of the MAME Atari 7800 driver, with several enhancements added.
* Support for emulation of Proline Joysticks, VCS Joysticks, Lightguns, Paddles, Driving Controllers, Keypads, Trak-Balls, Amiga Mice, and ST Mice.
* Maria DMA timing has been improved further, with the addition of accurate DMA hole penalties.
* Improved saturated/normalized colors with palette selection.
* Streamlined UI including menu options to have an Atari 7800 system focus.
* A bug in the existing RIOT emulation has been fixed.
* POKEY sound emulation improvements.
* SALLY (CPU) and MARIA (Graphics chip) performance adjustments.
* Selectable and improved palettes with enhanced screen options.
* Audio indication of no ROM loaded silenced.
* BIOS file(s) no longer required and made optional.
* Streamlined UI including menu options to have an Atari 7800 system focus.
* Implementation of XM control registers updated.
* Graphical register updates made mid-scanline are now displayed mid-scanline.
* Bankset bankswitching support added.
* POKEY@800 added for non-banked, supergame, and bankset formats.
* Machine targets a7800dev and a7800pdev added, which display DMA usage per-scanline.
MAME compatibility and syntax has been maintained, to allow for the reuse of MAME configuration files and front-ends.

View file

@ -1553,14 +1553,14 @@ endif
ifeq (posix,$(SHELLTYPE))
$(GENDIR)/version.cpp: $(GENDIR)/git_desc | $(GEN_FOLDERS)
@echo '#define BARE_BUILD_VERSION "5.0"' > $@
@echo '#define BARE_BUILD_VERSION "5.2"' > $@
@echo 'extern const char bare_build_version[];' >> $@
@echo 'extern const char build_version[];' >> $@
@echo 'const char bare_build_version[] = BARE_BUILD_VERSION;' >> $@
@echo 'const char build_version[] = BARE_BUILD_VERSION " A7800";' >> $@
else
$(GENDIR)/version.cpp: $(GENDIR)/git_desc
@echo #define BARE_BUILD_VERSION "5.0" > $@
@echo #define BARE_BUILD_VERSION "5.2" > $@
@echo extern const char bare_build_version[]; >> $@
@echo extern const char build_version[]; >> $@
@echo const char bare_build_version[] = BARE_BUILD_VERSION; >> $@

View file

@ -1559,14 +1559,14 @@ endif
ifeq (posix,$(SHELLTYPE))
$(GENDIR)/version.cpp: $(GENDIR)/git_desc | $(GEN_FOLDERS)
@echo '#define BARE_BUILD_VERSION "5.0"' > $@
@echo '#define BARE_BUILD_VERSION "5.2"' > $@
@echo 'extern const char bare_build_version[];' >> $@
@echo 'extern const char build_version[];' >> $@
@echo 'const char bare_build_version[] = BARE_BUILD_VERSION;' >> $@
@echo 'const char build_version[] = BARE_BUILD_VERSION " A7800";' >> $@
else
$(GENDIR)/version.cpp: $(GENDIR)/git_desc
@echo #define BARE_BUILD_VERSION "5.0" > $@
@echo #define BARE_BUILD_VERSION "5.2" > $@
@echo extern const char bare_build_version[]; >> $@
@echo extern const char build_version[]; >> $@
@echo const char bare_build_version[] = BARE_BUILD_VERSION; >> $@

View file

@ -517,7 +517,7 @@ image_init_result a78_cart_slot_device::call_load()
m_cart->rom_alloc(len, tag());
fread(m_cart->get_rom_base(), len);
if (m_type == A78_TYPE6 || m_type == A78_TYPE8)
if (m_type == A78_TYPE6 || m_type == A78_TYPE8 || m_type == A78_TYPE6_POK800 )
m_cart->ram_alloc(0x4000);
if (m_type == A78_MEGACART || (m_type == A78_BANKSET_SG_BANKRAM) || (m_type == A78_BANKSET_SG_BANKRAM_POK800) || (m_type == A78_BANKSET_BANKRAM) || (m_type == A78_BANKSET_BANKRAM_POK800) || (m_type >= A78_VERSABOARD && m_type <= A78_VERSA_POK450))
m_cart->ram_alloc(0x8000);

View file

@ -47,7 +47,7 @@ DEFINE_DEVICE_TYPE(A78_ROM_P450_SG9, a78_rom_p450_sg9_device, "a78_p450_ta
DEFINE_DEVICE_TYPE(A78_ROM_P800, a78_rom_p800_device, "a78_p800_t0", "Atari 7800 ROM Carts w/POKEY @ 0x0800")
DEFINE_DEVICE_TYPE(A78_ROM_P800_POKEY, a78_rom_p800_pokey_device, "a78_p800_t1", "Atari 7800 ROM Carts w/no Bankswitch + POKEY + POKEY @ 0x0800")
DEFINE_DEVICE_TYPE(A78_ROM_P800_SG, a78_rom_p800_sg_device, "a78_p800_t2", "Atari 7800 ROM Carts w/SuperGame Bankswitch + POKEY @ 0x0800")
DEFINE_DEVICE_TYPE(A78_ROM_P800_SG_RAM, a78_rom_p800_sg_ram_device, "a78_p800_t6", "Atari 7800 ROM Carts w/SuperGame Bankswitch + RAM + POKEY @ 0x0800")
DEFINE_DEVICE_TYPE(A78_ROM_P800_SG_RAM, a78_rom_p800_sg_ram_device, "a78_p800_t6", "Atari 7800 ROM Carts w/SuperGame Bankswitch + RAM0 0x800")
DEFINE_DEVICE_TYPE(A78_ROM_P800_SG9, a78_rom_p800_sg9_device, "a78_p800_ta", "Atari 7800 ROM Carts w/SuperGame 9Banks + POKEY @ 0x0800")

View file

@ -2,13 +2,21 @@
// copyright-holders:Brad Oliver, Eric Smith, Juergen Buchmueller
/*****************************************************************************
*
* POKEY chip emulator 4.7 (a7800)
* POKEY chip emulator 4.9 (a7800)
*
* Based on original info found in Ron Fries' Pokey emulator,
* with additions by Brad Oliver, Eric Smith and Juergen Buchmueller,
* paddle (a/d conversion) details from the Atari 400/800 Hardware Manual.
* Polynomial algorithms according to info supplied by Perry McFarlane.
*
* 4.9 (a7800):
* - Two-tone mode updated for better accuracy.
*
* 4.8 (a7800):
* - Poly5 related modes had a pitch shift issue. The poly4/5 init routine
* was replaced with one based on Altira's implementation, which resolved
* the issue.
*
* 4.7 (a7800):
* [1] https://www.virtualdub.org/downloads/Altirra%20Hardware%20Reference%20Manual.pdf
* - updated to reflect that borrowing cycle delays only impacts voices
@ -91,9 +99,9 @@
#define POKEY_DEFAULT_GAIN (32767/11/4)
#define VERBOSE 0
#define VERBOSE_SOUND 0
#define VERBOSE_SOUND 1
#define VERBOSE_TIMER 0
#define VERBOSE_POLY 1
#define VERBOSE_POLY 0
#define VERBOSE_RAND 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
@ -242,8 +250,8 @@ void pokey_device::device_start()
*/
/* initialize the poly counters */
poly_init_4_5(m_poly4, 4, 1, 0);
poly_init_4_5(m_poly5, 5, 2, 1);
poly_init_4_5(m_poly4, 4);
poly_init_4_5(m_poly5, 5);
/* initialize 9 / 17 arrays */
poly_init_9_17(m_poly9, 9);
@ -258,7 +266,7 @@ void pokey_device::device_start()
*/
m_KBCODE = 0x09; /* Atari 800 'no key' */
m_SKCTL = SK_RESET; /* let the RNG run after reset */
m_SKCTL = 0;
m_SKSTAT = 0;
/* This bit should probably get set later. Acid5200 pokey_setoc test tests this. */
m_IRQST = IRQ_SEROC;
@ -661,41 +669,6 @@ uint32_t pokey_device::step_one_clock(void)
step_keyboard();
}
if (m_channel[CHAN1].check_borrow())
{
int isJoined = (m_AUDCTL & CH12_JOINED);
if (isJoined)
m_channel[CHAN2].inc_chan(1);
else
m_channel[CHAN1].reset_channel();
process_channel(CHAN1);
// check if some of the requested timer interrupts are enabled
if ((m_IRQST & IRQ_TIMR1) && !m_irq_f.isnull())
m_irq_f(IRQ_TIMR1);
}
if (m_channel[CHAN2].check_borrow())
{
int isJoined = (m_AUDCTL & CH12_JOINED);
if (isJoined)
m_channel[CHAN1].reset_channel();
if (m_SKCTL & SK_TWOTONE)
m_channel[CHAN1].reset_channel();
m_channel[CHAN2].reset_channel();
process_channel(CHAN2);
// check if some of the requested timer interrupts are enabled
if ((m_IRQST & IRQ_TIMR2) && !m_irq_f.isnull())
m_irq_f(IRQ_TIMR2);
}
if (m_channel[CHAN3].check_borrow())
{
int isJoined = (m_AUDCTL & CH34_JOINED);
@ -703,6 +676,7 @@ uint32_t pokey_device::step_one_clock(void)
m_channel[CHAN4].inc_chan(1);
else
m_channel[CHAN3].reset_channel();
process_channel(CHAN3);
/* is this a filtering channel (3/4) and is the filter active? */
if (m_AUDCTL & CH1_FILTER)
@ -728,6 +702,42 @@ uint32_t pokey_device::step_one_clock(void)
m_irq_f(IRQ_TIMR4);
}
if ( (m_SKCTL & SK_TWOTONE) && (m_channel[CHAN2].m_borrow_cnt == 1) )
m_channel[CHAN1].reset_channel();
if (m_channel[CHAN1].check_borrow())
{
int isJoined = (m_AUDCTL & CH12_JOINED);
if (isJoined)
m_channel[CHAN2].inc_chan(1);
else
m_channel[CHAN1].reset_channel();
// TODO: If two-tone is enabled *and* serial output == 1 then reset the channel 2 timer.
process_channel(CHAN1);
// check if some of the requested timer interrupts are enabled
if ((m_IRQST & IRQ_TIMR1) && !m_irq_f.isnull())
m_irq_f(IRQ_TIMR1);
}
if (m_channel[CHAN2].check_borrow())
{
int isJoined = (m_AUDCTL & CH12_JOINED);
if (isJoined)
m_channel[CHAN1].reset_channel();
m_channel[CHAN2].reset_channel();
process_channel(CHAN2);
// check if some of the requested timer interrupts are enabled
if ((m_IRQST & IRQ_TIMR2) && !m_irq_f.isnull())
m_irq_f(IRQ_TIMR2);
}
for (ch = 0; ch < 4; ch++)
{
@ -1230,38 +1240,48 @@ void pokey_device::vol_init()
}
void pokey_device::poly_init_4_5(uint32_t *poly, int size, int xorbit, int invert)
void pokey_device::poly_init_4_5(uint32_t *poly, int size)
{
int mask = (1 << size) - 1;
int i;
uint32_t lfsr = 0;
LOG_POLY(("poly %d\n", size));
for( i = 0; i < mask; i++ )
{
// calculate next bit
int in = !((lfsr >> 0) & 1) ^ ((lfsr >> xorbit) & 1);
lfsr = lfsr >> 1;
lfsr = (in << (size-1)) | lfsr;
*poly = lfsr ^ invert;
LOG_POLY(("%05x: %02x\n", i, *poly));
poly++;
}
if(size==4)
{
for( i = 0; i < mask; i++ )
{
lfsr = (lfsr+lfsr) + (~((lfsr >> 2) ^ (lfsr >> 3)) & 1);
*poly = lfsr & mask;
poly++;
}
}
if(size==5)
{
for( i = 0; i < mask; i++ )
{
lfsr = (lfsr+lfsr) + (~((lfsr >> 2) ^ (lfsr >> 4)) & 1);
*poly = lfsr & mask;
poly++;
}
}
}
void pokey_device::poly_init_9_17(uint32_t *poly, int size)
{
int mask = (1 << size) - 1;
int i;
uint32_t lfsr =mask;
uint32_t lfsr = mask;
LOG_RAND(("rand %d\n", size));
if (size == 17)
{
for( i = 0; i < mask; i++ )
{
// calculate next bit
int in8 = ((lfsr >> 8) & 1) ^ ((lfsr >> 13) & 1);
int in = (lfsr & 1);
lfsr = lfsr >> 1;
@ -1272,7 +1292,7 @@ void pokey_device::poly_init_9_17(uint32_t *poly, int size)
poly++;
}
}
else
else // size == 9
{
for( i = 0; i < mask; i++ )
{

View file

@ -268,7 +268,7 @@ private:
uint8_t m_div2; /* division by 2 */
inline void sample(void) { m_filter_sample = m_output; }
inline void reset_channel(void) { m_counter = m_AUDF ^ 0xff; }
inline void reset_channel(void) { m_counter = m_AUDF ^ 0xff; m_borrow_cnt = 0; }
inline void inc_chan(int cycles)
{
@ -301,7 +301,7 @@ private:
void step_keyboard();
void step_pot();
void poly_init_4_5(uint32_t *poly, int size, int xorbit, int invert);
void poly_init_4_5(uint32_t *poly, int size);
void poly_init_9_17(uint32_t *poly, int size);
void vol_init();

View file

@ -1442,7 +1442,7 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
std::string str = string_format(_("%1$s Brightness"), screen_desc);
sliders.push_back(slider_alloc(machine, SLIDER_ID_BRIGHTNESS + slider_index, str.c_str(), 100, 1000, 2000, 10, param));
str = string_format(_("%1$s Contrast"), screen_desc);
sliders.push_back(slider_alloc(machine, SLIDER_ID_CONTRAST + slider_index, str.c_str(), 100, 1000, 2000, 50, param));
sliders.push_back(slider_alloc(machine, SLIDER_ID_CONTRAST + slider_index, str.c_str(), 100, 1000, 2000, 10, param));
str = string_format(_("%1$s Gamma"), screen_desc);
sliders.push_back(slider_alloc(machine, SLIDER_ID_GAMMA + slider_index, str.c_str(), 100, 1000, 3000, 50, param));
@ -1453,13 +1453,13 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
//str = string_format(_("%1$s Horiz Position"), screen_desc);
str = string_format(_("%1$s Horizontal Position: Shift Left <-> Default <-> Shift Right"), screen_desc);
sliders.push_back(slider_alloc(machine, SLIDER_ID_XOFFSET + slider_index, str.c_str(), -500, defxoffset, 500, 1, param));
//str = string_format(_("%1$s Vert Stretch"), screen_desc);
str = string_format(_("%1$s Height: <-- Crop Less Lines | Crop More Lines -->"), screen_desc);
//sliders.push_back(slider_alloc(machine, SLIDER_ID_YSCALE + slider_index, str.c_str(), 500, defyscale, 1500, 2, param));
sliders.push_back(slider_alloc(machine, SLIDER_ID_YSCALE + slider_index, str.c_str(), 1000, defyscale, 1216, 9, param));
//str = string_format(_("%1$s Vert Position"), screen_desc);
str = string_format(_("%1$s Vertical Position: Shift Up <-> Default <-> Shift Down"), screen_desc);
sliders.push_back(slider_alloc(machine, SLIDER_ID_YOFFSET + slider_index, str.c_str(), -500, defyoffset, 500, 1, param));
//str = string_format(_("%1$s Vert Stretch"), screen_desc);
str = string_format(_("%1$s Height Lines Cropped: 0 <-> 8 <-> 16 <-> 24 <-> 32 <-> 40 <-> 48"), screen_desc);
//sliders.push_back(slider_alloc(machine, SLIDER_ID_YSCALE + slider_index, str.c_str(), 500, defyscale, 1500, 2, param));
sliders.push_back(slider_alloc(machine, SLIDER_ID_YSCALE + slider_index, str.c_str(), 1000, defyscale, 1216, 36, param));
slider_index++;
}

File diff suppressed because it is too large Load diff

View file

@ -257,13 +257,13 @@ a6809 //
a7150 //
@source:a7800.cpp
a7800 // Atari 7800 NTSC Cool
a7800u1 // Atari 7800 NTSC Warm
a7800u2 // Atari 7800 NTSC Hot
a7800dev // Atari 7800 NTSC Hot
a7800 // Atari 7800 NTSC Hot
a7800a1 // Atari 7800 NTSC Warm
a7800a2 // Atari 7800 NTSC Cool
a7800dev // Atari 7800 NTSC Developer Mode
a7800p // Atari 7800 PAL Cool
a7800pu1 // Atari 7800 PAL Warm
a7800pu2 // Atari 7800 PAL Hot
a7800pa1 // Atari 7800 PAL Warm
a7800pa2 // Atari 7800 PAL Hot
a7800pdev // Atari 7800 PAL Developer Mode
@source:aa310.cpp

View file

@ -2,49 +2,57 @@
// copyright-holders:Dan Boris, Fabio Priuli, Mike Saarna, Robert Tuccitto
/***************************************************************************
Atari MARIA video emulation
Atari MARIA video emulation.
Dan Boris
- some history:
History:
2014-12-01 Mike Saarna, Robert Tuccitto Implemented "colorburst kill" bit
of the MARIA CTRL register.
2002/05/12 kubecj
-Added cases for 0x01-160A, 0x05-160B as stated by docs.
2014-10-05 Mike Saarna, Robert Tuccitto Last Line DMA value corrected
to 6. GCC and Atari docs both show a difference between
Other Line and Last Line as +6 at the lowest part of the
range.
Blank scanlines are drawn when DMA is off, like real
hardware.
If MARIA hits the DMA limit, the CPU doesn't run until
the next scanline.
2002/05/13 kubecj
-Fixed 320C mode - displayed 2 pixels instead of one!
-Noticed that Jinks uses 0x02-320D mode, implemented the
mode - completely unsure if good!
-Implemented some Maria CTRL variables.
2014-09-03 Mike Saarna, Robert Tuccitto reorganized DMA penalties to
support new rendering timeout code.
2002/05/14 kubecj
-Vblank dma stop fix.
2014-08-29 Mike Saarna Timeout rendering added.
2003/06/23 ericball
-Kangaroo mode & 320 mode & other stuff.
2014-08-26 Fabio Priuli Converted to device
2013/05/08 huygens
-Rewrite to emulate line ram buffers (mostly fixes Kung-Fu Master).
-Started DMA cycle stealing implementation.
2014-05-06 Mike Saarna Added interrupts to DMA cycle eating. Updates to
LL, OL, and spin accounting for HALT behavior.
2014/03/24 Mike Saarna
-Fixed DMA regarding startup, shutdown and cycle stealing.
2014-03-24 Mike Saarna Fixed DMA regarding startup, shutdown and
cycle stealing.
2014/05/06 Mike Saarna
-Added interrupts to DMA cycle eating.
-Updates to LL, OL, and spin accounting for HALT behavior.
2013-05-08 huygens rewrite to emulate line ram buffers (mostly fixes Kung-Fu Master
Started DMA cycle stealing implementation
2014/08/26 Fabio Priuli
-Converted to device.
2003-06-23 ericball Kangaroo mode & 320 mode & other stuff
2014/08/29 Mike Saarna
-Timeout rendering added.
2002-05-14 kubecj vblank dma stop fix
2014/09/03 Mike Saarna/Robert Tuccitto
-Reorganized DMA penalties to support new rendering timeout code.
2002-05-13 kubecj fixed 320C mode (displayed 2 pixels instead of one!)
noticed that Jinks uses 0x02-320D mode
implemented the mode - completely unsure if good!
implemented some Maria CTRL variables
2014/10/05 Mike Saarna/Robert Tuccitto
-Last Line DMA value corrected to 6. GCC and Atari docs both show
a difference between Other Line and Last Line as +6 at the lowest
part of the range.
-Blank scanlines are drawn when DMA is off, like real hardware.
-If MARIA hits the DMA limit, the CPU doesn't run until the next
scanline.
2002-05-12 kubecj added cases for 0x01-160A, 0x05-160B as stated by docs
2014/12/01 Mike Saarna/Robert Tuccitto
-Implemented "colorburst kill" bit of the MARIA CTRL register.
***************************************************************************/