diff options
Diffstat (limited to 'src/mame/machine/atari.c')
-rw-r--r-- | src/mame/machine/atari.c | 982 |
1 files changed, 982 insertions, 0 deletions
diff --git a/src/mame/machine/atari.c b/src/mame/machine/atari.c new file mode 100644 index 00000000000..47c92e0415f --- /dev/null +++ b/src/mame/machine/atari.c @@ -0,0 +1,982 @@ +/*************************************************************************** + + Atari 400/800 + + Machine driver + + Juergen Buchmueller, June 1998 + +***************************************************************************/ + +#include "driver.h" +#include "cpu/m6502/m6502.h" +#include "includes/atari.h" +#include "sound/pokey.h" +#include "machine/6821pia.h" +#include "sound/dac.h" +#include "video/gtia.h" + +#define VERBOSE_POKEY 0 +#define VERBOSE_SERIAL 0 +#define VERBOSE_TIMERS 0 + +//#define LOG(x) if (errorlog) fprintf x + +static int atari = 0; +#define ATARI_5200 0 +#define ATARI_400 1 +#define ATARI_800 2 +#define ATARI_600XL 3 +#define ATARI_800XL 4 + +#ifdef MESS +static int a800_cart_loaded = 0; +static int a800_cart_is_16k = 0; +#endif + +static void a800xl_mmu(UINT8 new_mmu); +static void a600xl_mmu(UINT8 new_mmu); + +static void pokey_reset(running_machine *machine); + +void atari_interrupt_cb(int mask) +{ + +#if VERBOSE_POKEY + if (mask & 0x80) + logerror("atari interrupt_cb BREAK\n"); + if (mask & 0x40) + logerror("atari interrupt_cb KBCOD\n"); +#endif +#if VERBOSE_SERIAL + if (mask & 0x20) + logerror("atari interrupt_cb SERIN\n"); + if (mask & 0x10) + logerror("atari interrupt_cb SEROR\n"); + if (mask & 0x08) + logerror("atari interrupt_cb SEROC\n"); +#endif +#if VERBOSE_TIMERS + if (mask & 0x04) + logerror("atari interrupt_cb TIMR4\n"); + if (mask & 0x02) + logerror("atari interrupt_cb TIMR2\n"); + if (mask & 0x01) + logerror("atari interrupt_cb TIMR1\n"); +#endif + + cpunum_set_input_line(0, 0, HOLD_LINE); +} + +/************************************************************** + * + * PIA interface + * + **************************************************************/ + +static READ8_HANDLER(atari_pia_pa_r) +{ + return atari_input_disabled() ? 0xFF : readinputportbytag_safe("djoy_0_1", 0); +} + +static READ8_HANDLER(atari_pia_pb_r) +{ + return atari_input_disabled() ? 0xFF : readinputportbytag_safe("djoy_2_3", 0); +} + +static WRITE8_HANDLER(a600xl_pia_pb_w) { a600xl_mmu(data); } +static WRITE8_HANDLER(a800xl_pia_pb_w) { a800xl_mmu(data); } + +#ifdef MESS +extern WRITE8_HANDLER(atari_pia_cb2_w); +#else +#define atari_pia_cb2_w (0) +#endif + +static const pia6821_interface atari_pia_interface = +{ + /*inputs : A/B,CA/B1,CA/B2 */ atari_pia_pa_r, atari_pia_pb_r, 0, 0, 0, 0, + /*outputs: A/B,CA/B2 */ 0, 0, 0, atari_pia_cb2_w, + /*irqs : A/B */ 0, 0 +}; + +static const pia6821_interface a600xl_pia_interface = +{ + /*inputs : A/B,CA/B1,CA/B2 */ atari_pia_pa_r, atari_pia_pb_r, 0, 0, 0, 0, + /*outputs: A/B,CA/B2 */ 0, a600xl_pia_pb_w, 0, atari_pia_cb2_w, + /*irqs : A/B */ 0, 0 +}; + +static const pia6821_interface a800xl_pia_interface = +{ + /*inputs : A/B,CA/B1,CA/B2 */ atari_pia_pa_r, atari_pia_pb_r, 0, 0, 0, 0, + /*outputs: A/B,CA/B2 */ 0, a800xl_pia_pb_w, 0, atari_pia_cb2_w, + /*irqs : A/B */ 0, 0 +}; + + + + +/************************************************************** + * + * Reset hardware + * + **************************************************************/ + +void a600xl_mmu(UINT8 new_mmu) +{ + read8_handler rbank2; + write8_handler wbank2; + + /* check if self-test ROM changed */ + if ( new_mmu & 0x80 ) + { + logerror("%s MMU SELFTEST RAM\n", Machine->gamedrv->name); + rbank2 = MRA8_NOP; + wbank2 = MWA8_NOP; + } + else + { + logerror("%s MMU SELFTEST ROM\n", Machine->gamedrv->name); + rbank2 = MRA8_BANK2; + wbank2 = MWA8_ROM; + } + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x5000, 0x57ff, 0, 0, rbank2); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x5000, 0x57ff, 0, 0, wbank2); + if (rbank2 == MRA8_BANK2) + memory_set_bankptr(2, memory_region(REGION_CPU1)+0x5000); +} + +void a800xl_mmu(UINT8 new_mmu) +{ + read8_handler rbank1, rbank2, rbank3, rbank4; + write8_handler wbank1, wbank2, wbank3, wbank4; + UINT8 *base1, *base2, *base3, *base4; + + /* check if memory C000-FFFF changed */ + if( new_mmu & 0x01 ) + { + logerror("%s MMU BIOS ROM\n", Machine->gamedrv->name); + rbank3 = MRA8_BANK3; + wbank3 = MWA8_ROM; + base3 = memory_region(REGION_CPU1)+0x14000; /* 8K lo BIOS */ + rbank4 = MRA8_BANK4; + wbank4 = MWA8_ROM; + base4 = memory_region(REGION_CPU1)+0x15800; /* 4K FP ROM + 8K hi BIOS */ + } + else + { + logerror("%s MMU BIOS RAM\n", Machine->gamedrv->name); + rbank3 = MRA8_BANK3; + wbank3 = MWA8_BANK3; + base3 = memory_region(REGION_CPU1)+0x0c000; /* 8K RAM */ + rbank4 = MRA8_BANK4; + wbank4 = MWA8_BANK4; + base4 = memory_region(REGION_CPU1)+0x0d800; /* 4K RAM + 8K RAM */ + } + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xcfff, 0, 0, rbank3); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xcfff, 0, 0, wbank3); + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xd800, 0xffff, 0, 0, rbank4); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xd800, 0xffff, 0, 0, wbank4); + memory_set_bankptr(3, base3); + memory_set_bankptr(4, base4); + + /* check if BASIC changed */ + if( new_mmu & 0x02 ) + { + logerror("%s MMU BASIC RAM\n", Machine->gamedrv->name); + rbank1 = MRA8_BANK1; + wbank1 = MWA8_BANK1; + base1 = memory_region(REGION_CPU1)+0x0a000; /* 8K RAM */ + } + else + { + logerror("%s MMU BASIC ROM\n", Machine->gamedrv->name); + rbank1 = MRA8_BANK1; + wbank1 = MWA8_ROM; + base1 = memory_region(REGION_CPU1)+0x10000; /* 8K BASIC */ + } + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xa000, 0xbfff, 0, 0, rbank1); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xa000, 0xbfff, 0, 0, wbank1); + memory_set_bankptr(1, base1); + + /* check if self-test ROM changed */ + if( new_mmu & 0x80 ) + { + logerror("%s MMU SELFTEST RAM\n", Machine->gamedrv->name); + rbank2 = MRA8_BANK2; + wbank2 = MWA8_BANK2; + base2 = memory_region(REGION_CPU1)+0x05000; /* 0x0800 bytes */ + } + else + { + logerror("%s MMU SELFTEST ROM\n", Machine->gamedrv->name); + rbank2 = MRA8_BANK2; + wbank2 = MWA8_ROM; + base2 = memory_region(REGION_CPU1)+0x15000; /* 0x0800 bytes */ + } + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x5000, 0x57ff, 0, 0, rbank2); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x5000, 0x57ff, 0, 0, wbank2); + memory_set_bankptr(2, base2); +} + + + +/************************************************************** + * + * Keyboard + * + **************************************************************/ + +#define AKEY_L 0x00 +#define AKEY_J 0x01 +#define AKEY_SEMICOLON 0x02 +#define AKEY_BREAK 0x03 /* this not really a scancode */ +#define AKEY_K 0x05 +#define AKEY_PLUS 0x06 +#define AKEY_ASTERISK 0x07 +#define AKEY_O 0x08 +#define AKEY_NONE 0x09 +#define AKEY_P 0x0a +#define AKEY_U 0x0b +#define AKEY_ENTER 0x0c +#define AKEY_I 0x0d +#define AKEY_MINUS 0x0e +#define AKEY_EQUALS 0x0f +#define AKEY_V 0x10 +#define AKEY_C 0x12 +#define AKEY_B 0x15 +#define AKEY_X 0x16 +#define AKEY_Z 0x17 +#define AKEY_4 0x18 +#define AKEY_3 0x1a +#define AKEY_6 0x1b +#define AKEY_ESC 0x1c +#define AKEY_5 0x1d +#define AKEY_2 0x1e +#define AKEY_1 0x1f +#define AKEY_COMMA 0x20 +#define AKEY_SPACE 0x21 +#define AKEY_STOP 0x22 +#define AKEY_N 0x23 +#define AKEY_M 0x25 +#define AKEY_SLASH 0x26 +#define AKEY_ATARI 0x27 +#define AKEY_R 0x28 +#define AKEY_E 0x2a +#define AKEY_Y 0x2b +#define AKEY_TAB 0x2c +#define AKEY_T 0x2d +#define AKEY_W 0x2e +#define AKEY_Q 0x2f +#define AKEY_9 0x30 +#define AKEY_0 0x32 +#define AKEY_7 0x33 +#define AKEY_BSP 0x34 +#define AKEY_8 0x35 +#define AKEY_LESSER 0x36 +#define AKEY_GREATER 0x37 +#define AKEY_F 0x38 +#define AKEY_H 0x39 +#define AKEY_D 0x3a +#define AKEY_CAPS 0x3c +#define AKEY_G 0x3d +#define AKEY_S 0x3e +#define AKEY_A 0x3f +#define ASHF_L 0x40 +#define ASHF_J 0x41 +#define ASHF_COLON 0x42 +#define ASHF_BREAK 0x43 /* this not really a scancode */ +#define ASHF_K 0x45 +#define ASHF_BACKSLASH 0x46 +#define ASHF_TILDE 0x47 +#define ASHF_O 0x48 +#define ASHF_SHIFT 0x49 +#define ASHF_P 0x4a +#define ASHF_U 0x4b +#define ASHF_ENTER 0x4c +#define ASHF_I 0x4d +#define ASHF_UNDERSCORE 0x4e +#define ASHF_BAR 0x4f +#define ASHF_V 0x50 +#define ASHF_C 0x52 +#define ASHF_B 0x55 +#define ASHF_X 0x56 +#define ASHF_Z 0x57 +#define ASHF_DOLLAR 0x58 +#define ASHF_HASH 0x5a +#define ASHF_AMPERSAND 0x5b +#define ASHF_ESC 0x5c +#define ASHF_PERCENT 0x5d +#define ASHF_DQUOTE 0x5e +#define ASHF_EXCLAM 0x5f +#define ASHF_LBRACE 0x60 +#define ASHF_SPACE 0x61 +#define ASHF_RBRACE 0x62 +#define ASHF_N 0x63 +#define ASHF_M 0x65 +#define ASHF_QUESTION 0x66 +#define ASHF_ATARI 0x67 +#define ASHF_R 0x68 +#define ASHF_E 0x6a +#define ASHF_Y 0x6b +#define ASHF_TAB 0x6c +#define ASHF_T 0x6d +#define ASHF_W 0x6e +#define ASHF_Q 0x6f +#define ASHF_LPAREN 0x70 +#define ASHF_RPAREN 0x72 +#define ASHF_QUOTE 0x73 +#define ASHF_BSP 0x74 +#define ASHF_AT 0x75 +#define ASHF_CLEAR 0x76 +#define ASHF_INSERT 0x77 +#define ASHF_F 0x78 +#define ASHF_H 0x79 +#define ASHF_D 0x7a +#define ASHF_CAPS 0x7c +#define ASHF_G 0x7d +#define ASHF_S 0x7e +#define ASHF_A 0x7f +#define ACTL_L 0x80 +#define ACTL_J 0x81 +#define ACTL_SEMICOLON 0x82 +#define ACTL_BREAK 0x83 /* this not really a scancode */ +#define ACTL_K 0x85 +#define ACTL_PLUS 0x86 +#define ACTL_ASTERISK 0x87 +#define ACTL_O 0x88 +#define ACTL_CONTROL 0x89 +#define ACTL_P 0x8a +#define ACTL_U 0x8b +#define ACTL_ENTER 0x8c +#define ACTL_I 0x8d +#define ACTL_MINUS 0x8e +#define ACTL_EQUALS 0x8f +#define ACTL_V 0x90 +#define ACTL_C 0x92 +#define ACTL_B 0x95 +#define ACTL_X 0x96 +#define ACTL_Z 0x97 +#define ACTL_4 0x98 +#define ACTL_3 0x9a +#define ACTL_6 0x9b +#define ACTL_ESC 0x9c +#define ACTL_5 0x9d +#define ACTL_2 0x9e +#define ACTL_1 0x9f +#define ACTL_COMMA 0xa0 +#define ACTL_SPACE 0xa1 +#define ACTL_STOP 0xa2 +#define ACTL_N 0xa3 +#define ACTL_M 0xa5 +#define ACTL_SLASH 0xa6 +#define ACTL_ATARI 0xa7 +#define ACTL_R 0xa8 +#define ACTL_E 0xaa +#define ACTL_Y 0xab +#define ACTL_TAB 0xac +#define ACTL_T 0xad +#define ACTL_W 0xae +#define ACTL_Q 0xaf +#define ACTL_9 0xb0 +#define ACTL_0 0xb2 +#define ACTL_7 0xb3 +#define ACTL_BSP 0xb4 +#define ACTL_8 0xb5 +#define ACTL_LESSER 0xb6 +#define ACTL_GREATER 0xb7 +#define ACTL_F 0xb8 +#define ACTL_H 0xb9 +#define ACTL_D 0xba +#define ACTL_CAPS 0xbc +#define ACTL_G 0xbd +#define ACTL_S 0xbe +#define ACTL_A 0xbf +#define ACSH_L 0xc0 +#define ACSH_J 0xc1 +#define ACSH_COLON 0xc2 +#define ACSH_BREAK 0xc3 /* this not really a scancode */ +#define ACSH_K 0xc5 +#define ACSH_BACKSLASH 0xc6 +#define ACSH_TILDE 0xc7 +#define ACSH_O 0xc8 +#define ACSH_CTRLSHIFT 0xc9 +#define ACSH_P 0xca +#define ACSH_U 0xcb +#define ACSH_ENTER 0xcc +#define ACSH_I 0xcd +#define ACSH_UNDERSCORE 0xce +#define ACSH_BAR 0xcf +#define ACSH_V 0xd0 +#define ACSH_C 0xd2 +#define ACSH_B 0xd5 +#define ACSH_X 0xd6 +#define ACSH_Z 0xd7 +#define ACSH_DOLLAR 0xd8 +#define ACSH_HASH 0xda +#define ACSH_AMPERSAND 0xdb +#define ACSH_ESC 0xdc +#define ACSH_PERCENT 0xdd +#define ACSH_DQUOTE 0xde +#define ACSH_EXCLAM 0xdf +#define ACSH_LBRACE 0xe0 +#define ACSH_SPACE 0xe1 +#define ACSH_RBRACE 0xe2 +#define ACSH_N 0xe3 +#define ACSH_M 0xe5 +#define ACSH_QUESTION 0xe6 +#define ACSH_ATARI 0xe7 +#define ACSH_R 0xe8 +#define ACSH_E 0xea +#define ACSH_Y 0xeb +#define ACSH_TAB 0xec +#define ACSH_T 0xed +#define ACSH_W 0xee +#define ACSH_Q 0xef +#define ACSH_LPAREN 0xf0 +#define ACSH_RPAREN 0xf2 +#define ACSH_QUOTE 0xf3 +#define ACSH_BSP 0xf4 +#define ACSH_AT 0xf5 +#define ACSH_CLEAR 0xf6 +#define ACSH_INSERT 0xf7 +#define ACSH_F 0xf8 +#define ACSH_H 0xf9 +#define ACSH_D 0xfa +#define ACSH_CAPS 0xfc +#define ACSH_G 0xfd +#define ACSH_S 0xfe +#define ACSH_A 0xff + +static const UINT8 keys[64][4] = { +{AKEY_NONE ,AKEY_NONE ,AKEY_NONE ,AKEY_NONE }, /* "" CODE_NONE */ +{AKEY_ESC ,ASHF_ESC ,ACTL_ESC ,ACSH_ESC }, /*"Escape" KEYCODE_ESC */ +{AKEY_1 ,ASHF_EXCLAM ,ACTL_1 ,ACSH_EXCLAM }, /* "1 !" KEYCODE_1 */ +{AKEY_2 ,ASHF_DQUOTE ,ACTL_2 ,ACSH_DQUOTE }, /* "2 \"" KEYCODE_2 */ +{AKEY_3 ,ASHF_HASH ,ACTL_3 ,ACSH_HASH }, /* "3 #" KEYCODE_3 */ +{AKEY_4 ,ASHF_DOLLAR ,ACTL_4 ,ACSH_DOLLAR }, /* "4 $" KEYCODE_4 */ +{AKEY_5 ,ASHF_PERCENT ,ACTL_5 ,ACSH_PERCENT }, /* "5 %" KEYCODE_5 */ +{AKEY_6 ,ASHF_TILDE ,ACTL_6 ,ACSH_AMPERSAND }, /* "6 ^" KEYCODE_6 */ +{AKEY_7 ,ASHF_AMPERSAND ,ACTL_7 ,ACSH_N }, /* "7 &" KEYCODE_7 */ +{AKEY_8 ,AKEY_ASTERISK ,ACTL_8 ,ACSH_M }, /* "8 *" KEYCODE_8 */ +{AKEY_9 ,ASHF_LPAREN ,ACTL_9 ,ACSH_LBRACE }, /* "9 (" KEYCODE_9 */ +{AKEY_0 ,ASHF_RPAREN ,ACTL_0 ,ACSH_RBRACE }, /* "0 )" KEYCODE_0 */ +{AKEY_MINUS ,ASHF_UNDERSCORE ,ACTL_MINUS ,ACSH_UNDERSCORE }, /* "- _" KEYCODE_MINUS */ +{AKEY_EQUALS ,AKEY_PLUS ,ACTL_EQUALS ,ACTL_PLUS }, /* "= +" KEYCODE_EQUALS */ +{AKEY_BSP ,ASHF_BSP ,ACTL_BSP ,ACSH_BSP }, /* "Backsp" KEYCODE_BACKSPACE */ +{AKEY_TAB ,ASHF_TAB ,ACTL_TAB ,ACSH_TAB }, /* "Tab" KEYCODE_TAB */ +{AKEY_Q ,ASHF_Q ,ACTL_Q ,ACSH_Q }, /* "q Q" KEYCODE_Q */ +{AKEY_W ,ASHF_W ,ACTL_W ,ACSH_W }, /* "w W" KEYCODE_W */ +{AKEY_E ,ASHF_E ,ACTL_E ,ACSH_E }, /* "e E" KEYCODE_E */ +{AKEY_R ,ASHF_R ,ACTL_R ,ACSH_R }, /* "r R" KEYCODE_R */ +{AKEY_T ,ASHF_T ,ACTL_T ,ACSH_T }, /* "t T" KEYCODE_T */ +{AKEY_Y ,ASHF_Y ,ACTL_Y ,ACSH_Y }, /* "y Y" KEYCODE_Y */ +{AKEY_U ,ASHF_U ,ACTL_U ,ACTL_U }, /* "u U" KEYCODE_U */ +{AKEY_I ,ASHF_I ,ACTL_I ,ACTL_I }, /* "i I" KEYCODE_I */ +{AKEY_O ,ASHF_O ,ACTL_O ,ACTL_O }, /* "o O" KEYCODE_O */ +{AKEY_P ,ASHF_P ,ACTL_P ,ACTL_P }, /* "p P" KEYCODE_P */ +{ASHF_LBRACE ,ACTL_COMMA ,ACTL_COMMA ,ACSH_LBRACE }, /* "[ {" KEYCODE_LBRACE */ +{ASHF_RBRACE ,ACTL_STOP ,ACTL_STOP ,ACSH_RBRACE }, /* "] }" KEYCODE_RBRACE */ +{AKEY_ENTER ,ASHF_ENTER ,ACTL_ENTER ,ACSH_ENTER }, /* "Enter" KEYCODE_ENTER */ +{AKEY_A ,ASHF_A ,ACTL_A ,ACSH_A }, /* "a A" KEYCODE_A */ +{AKEY_S ,ASHF_S ,ACTL_S ,ACSH_S }, /* "s S" KEYCODE_S */ +{AKEY_D ,ASHF_D ,ACTL_D ,ACSH_D }, /* "d D" KEYCODE_D */ +{AKEY_F ,ASHF_F ,ACTL_F ,ACSH_F }, /* "f F" KEYCODE_F */ +{AKEY_G ,ASHF_G ,ACTL_G ,ACSH_G }, /* "g G" KEYCODE_G */ +{AKEY_H ,ASHF_H ,ACTL_H ,ACSH_H }, /* "h H" KEYCODE_H */ +{AKEY_J ,ASHF_J ,ACTL_J ,ACSH_J }, /* "j J" KEYCODE_J */ +{AKEY_K ,ASHF_K ,ACTL_K ,ACSH_K }, /* "k K" KEYCODE_K */ +{AKEY_L ,ASHF_L ,ACTL_L ,ACSH_L }, /* "l L" KEYCODE_L */ +{AKEY_SEMICOLON ,ASHF_COLON ,ACTL_SEMICOLON ,ACSH_COLON }, /* "; :" KEYCODE_COLON */ +{ASHF_QUOTE ,ACSH_QUOTE ,ASHF_DQUOTE ,ACSH_DQUOTE }, /* "+ \\" KEYCODE_QUOTE */ +{ASHF_QUOTE ,ACSH_QUOTE ,ACTL_ASTERISK ,ACSH_TILDE }, /* "* ^" KEYCODE_TILDE */ +{ASHF_BACKSLASH ,ASHF_BAR ,ACSH_BACKSLASH ,ACSH_BAR }, /* "\ |" KEYCODE_BACKSLASH */ +{AKEY_Z ,ASHF_Z ,ACTL_Z ,ACSH_Z }, /* "z Z" KEYCODE_Z */ +{AKEY_X ,ASHF_X ,ACTL_X ,ACTL_X }, /* "x X" KEYCODE_X */ +{AKEY_C ,ASHF_C ,ACTL_C ,ACTL_C }, /* "c C" KEYCODE_C */ +{AKEY_V ,ASHF_V ,ACTL_V ,ACTL_V }, /* "v V" KEYCODE_V */ +{AKEY_B ,ASHF_B ,ACTL_B ,ACTL_B }, /* "b B" KEYCODE_B */ +{AKEY_N ,ASHF_N ,ACTL_N ,ACTL_N }, /* "n N" KEYCODE_N */ +{AKEY_M ,ASHF_M ,ACTL_M ,ACTL_M }, /* "m M" KEYCODE_M */ +{AKEY_COMMA ,AKEY_LESSER ,ACTL_COMMA ,ACTL_LESSER }, /* ", [" KEYCODE_COMMA */ +{AKEY_STOP ,AKEY_GREATER ,ACTL_STOP ,ACTL_GREATER }, /* ". ]" KEYCODE_STOP */ +{AKEY_SLASH ,ASHF_QUESTION ,ACTL_SLASH ,ACSH_QUESTION }, /* "/ ?" KEYCODE_SLASH */ +{ASHF_BACKSLASH ,ASHF_BAR ,ACSH_BACKSLASH ,ACSH_BAR }, /* "\ |" KEYCODE_BACKSLASH2 */ +{AKEY_ATARI ,ASHF_ATARI ,ACTL_ATARI ,ACSH_ATARI }, /* "Atari" KEYCODE_LALT */ +{AKEY_SPACE ,ASHF_SPACE ,ACTL_SPACE ,ACSH_SPACE }, /* "Space" KEYCODE_SPACE */ +{AKEY_CAPS ,ASHF_CAPS ,ACTL_CAPS ,ACSH_CAPS }, /* "Caps" KEYCODE_CAPSLOCK */ +{ASHF_CLEAR ,ASHF_CLEAR ,ACSH_CLEAR ,ACSH_CLEAR }, /* "Clear" KEYCODE_HOME */ +{ASHF_INSERT ,ASHF_INSERT ,ASHF_INSERT ,ASHF_INSERT }, /* "Insert" KEYCODE_INSERT */ +{AKEY_BSP ,AKEY_BSP ,AKEY_BSP ,AKEY_BSP }, /* "Delete" KEYCODE_DEL */ +{AKEY_BREAK ,ASHF_BREAK ,ACTL_BREAK ,ACSH_BREAK }, /* "Break" KEYCODE_PGUP */ +{ACTL_PLUS ,ACTL_PLUS ,ACTL_PLUS ,ACTL_PLUS }, /* "(Left)" KEYCODE_LEFT */ +{ACTL_ASTERISK ,ACTL_ASTERISK ,ACTL_ASTERISK ,ACTL_ASTERISK }, /* "(Right)"KEYCODE_RIGHT */ +{ACTL_MINUS ,ACTL_MINUS ,ACTL_MINUS ,ACTL_MINUS }, /* "(Up)" KEYCODE_UP */ +{ACTL_EQUALS ,ACTL_EQUALS ,ACTL_EQUALS ,ACTL_EQUALS } /* "(Down)" KEYCODE_DOWN */ +}; + + +void a800_handle_keyboard(void) +{ + static int atari_last = 0xff; + int i, modifiers, atari_code; + char tag[64]; + + modifiers = 0; + + /* with shift ? */ + if( input_code_pressed(KEYCODE_LSHIFT) || input_code_pressed(KEYCODE_RSHIFT) ) + modifiers |= 1; + + /* with control ? */ + if( input_code_pressed(KEYCODE_LCONTROL) || input_code_pressed(KEYCODE_RCONTROL) ) + modifiers |= 2; + + for( i = 0; i < 64; i++ ) + { + sprintf(tag, "keyboard_%d", i / 16); + if( readinputportbytag_safe(tag, 0) & (1 << (i&15)) ) + { + atari_code = keys[i][modifiers]; + if( atari_code != AKEY_NONE ) + { + if( atari_code == atari_last ) + return; + atari_last = atari_code; + if( (atari_code & 0x3f) == AKEY_BREAK ) + { + pokey1_break_w(atari_code & 0x40); + return; + } + pokey1_kbcode_w(atari_code, 1); + return; + } + } + } + /* remove key pressed status bit from skstat */ + pokey1_kbcode_w(AKEY_NONE, 0); + atari_last = AKEY_NONE; +} + +#define VKEY_BREAK 0x10 + +/* absolutely no clue what to do here :((( */ +void a5200_handle_keypads(void) +{ + int i, modifiers; + static int atari_last = 0xff; + + modifiers = 0; + + /* with shift ? */ + if (input_code_pressed(KEYCODE_LSHIFT) || input_code_pressed(KEYCODE_RSHIFT)) + modifiers |= 1; + + /* with control ? */ + if (input_code_pressed(KEYCODE_LCONTROL) || input_code_pressed(KEYCODE_RCONTROL)) + modifiers |= 2; + + /* check keypad */ + for (i = 0; i < 16; i++) + { + if( readinputportbytag("keypad") & (1 << i) ) + { + if( i == atari_last ) + return; + atari_last = i; + if( i == 0 ) + { + pokey1_break_w(i & 0x40); + return; + } + pokey1_kbcode_w((i << 1) | 0x21, 1); + return; + } + } + + /* check top button */ + if ((readinputportbytag("djoy_b") & 0x10) == 0) + { + if (atari_last == 0xFE) + return; + pokey1_kbcode_w(0x61, 1); + //pokey1_break_w(0x40); + atari_last = 0xFE; + return; + } + else if (atari_last == 0xFE) + pokey1_kbcode_w(0x21, 1); + + /* remove key pressed status bit from skstat */ + pokey1_kbcode_w(0xFF, 0); + atari_last = 0xff; +} + +#ifdef MESS +DRIVER_INIT( atari ) +{ + offs_t ram_top; + offs_t ram_size; + + if (!strcmp(machine->gamedrv->name, "a400") + || !strcmp(machine->gamedrv->name, "a400pal") + || !strcmp(machine->gamedrv->name, "a800") + || !strcmp(machine->gamedrv->name, "a800pal") + || !strcmp(machine->gamedrv->name, "a800xl")) + { + ram_size = 0xA000; + } + else + { + ram_size = 0x8000; + } + + /* install RAM */ + ram_top = MIN(mess_ram_size, ram_size) - 1; + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, + 0x0000, ram_top, 0, 0, MRA8_BANK2); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, + 0x0000, ram_top, 0, 0, MWA8_BANK2); + memory_set_bankptr(2, mess_ram); +} +#endif + + + +/************************************* + * + * Generic Atari Code + * + *************************************/ + +#ifdef MESS +static void a800_setbank(int n) +{ + void *read_addr; + void *write_addr; + UINT8 *mem = memory_region(REGION_CPU1); + + switch (n) + { + case 1: + read_addr = &mem[0x10000]; + write_addr = NULL; + break; + default: + if( atari <= ATARI_400 ) + { + /* Atari 400 has no RAM here, so install the NOP handler */ + read_addr = NULL; + write_addr = NULL; + } + else + { + read_addr = &mess_ram[0x08000]; + write_addr = &mess_ram[0x08000]; + } + break; + } + + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xbfff, 0, 0, + read_addr ? MRA8_BANK1 : MRA8_NOP); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xbfff, 0, 0, + write_addr ? MWA8_BANK1 : MWA8_NOP); + if (read_addr) + memory_set_bankptr(1, read_addr); + if (write_addr) + memory_set_bankptr(1, write_addr); +} +#endif + + + +static void pokey_reset(running_machine *machine) +{ + pokey1_w(15,0); +} + + + +static void cart_reset(running_machine *machine) +{ +#ifdef MESS + if (a800_cart_loaded) + a800_setbank(1); +#endif /* MESS */ +} + + + +static UINT8 console_read(void) +{ + return readinputportbytag("console"); +} + + + +static void console_write(UINT8 data) +{ + if (data & 0x08) + DAC_data_w(0, -120); + else + DAC_data_w(0, +120); +} + + +static void _pia_reset(running_machine *machine) +{ + pia_reset(); +} + +static void _antic_reset(running_machine *machine) +{ + antic_reset(); +} + + +static void atari_machine_start(int type, const pia6821_interface *pia_intf, int has_cart) +{ + gtia_interface gtia_intf; + + atari = type; + + /* GTIA */ + memset(>ia_intf, 0, sizeof(gtia_intf)); + if (port_tag_to_index("console") >= 0) + gtia_intf.console_read = console_read; + if (sndti_exists(SOUND_DAC, 0)) + gtia_intf.console_write = console_write; + gtia_init(>ia_intf); + + /* pokey */ + add_reset_callback(Machine, pokey_reset); + + /* PIA */ + if (pia_intf) + { + pia_config(0, pia_intf); + add_reset_callback(Machine, _pia_reset); + } + + /* ANTIC */ + add_reset_callback(Machine, _antic_reset); + + /* cartridge */ + if (has_cart) + add_reset_callback(Machine, cart_reset); + +#ifdef MESS + { + offs_t ram_top; + offs_t ram_size; + + if (!strcmp(Machine->gamedrv->name, "a400") + || !strcmp(Machine->gamedrv->name, "a400pal") + || !strcmp(Machine->gamedrv->name, "a800") + || !strcmp(Machine->gamedrv->name, "a800pal") + || !strcmp(Machine->gamedrv->name, "a800xl")) + { + ram_size = 0xA000; + } + else + { + ram_size = 0x8000; + } + + /* install RAM */ + ram_top = MIN(mess_ram_size, ram_size) - 1; + memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, + 0x0000, ram_top, 0, 0, MRA8_BANK2); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, + 0x0000, ram_top, 0, 0, MWA8_BANK2); + memory_set_bankptr(2, mess_ram); + } +#endif /* MESS */ + + /* save states */ + state_save_register_global_pointer(((UINT8 *) &antic.r), sizeof(antic.r)); + state_save_register_global_pointer(((UINT8 *) &antic.w), sizeof(antic.w)); +} + + + +/************************************* + * + * Atari 400 + * Atari 600XL + * + *************************************/ + +MACHINE_START( a400 ) +{ + atari_machine_start(ATARI_400, &atari_pia_interface, TRUE); +} + +MACHINE_START( a600xl ) +{ + atari_machine_start(ATARI_600XL, &a600xl_pia_interface, TRUE); +} + + + +/************************************* + * + * Atari 800 + * + *************************************/ + +MACHINE_START( a800 ) +{ + atari_machine_start(ATARI_800, &atari_pia_interface, TRUE); +} + + + +#ifdef MESS +DEVICE_LOAD( a800_cart ) +{ + UINT8 *mem = memory_region(REGION_CPU1); + int size; + + /* load an optional (dual) cartridge (e.g. basic.rom) */ + if( image_index_in_device(image) > 0 ) + { + size = image_fread(image, &mem[0x12000], 0x2000); + a800_cart_is_16k = (size == 0x2000); + logerror("%s loaded right cartridge '%s' size 16K\n", Machine->gamedrv->name, image_filename(image) ); + } + else + { + size = image_fread(image, &mem[0x10000], 0x2000); + a800_cart_loaded = size > 0x0000; + size = image_fread(image, &mem[0x12000], 0x2000); + a800_cart_is_16k = size > 0x2000; + logerror("%s loaded left cartridge '%s' size %s\n", Machine->gamedrv->name, image_filename(image) , (a800_cart_is_16k) ? "16K":"8K"); + } + return INIT_PASS; +} + +DEVICE_UNLOAD( a800_cart ) +{ + if( image_index_in_device(image) > 0 ) + { + a800_cart_is_16k = 0; + a800_setbank(1); + } + else + { + a800_cart_loaded = 0; + a800_setbank(0); + } +} +#endif + + + +/************************************* + * + * Atari 800XL + * + *************************************/ + +MACHINE_START( a800xl ) +{ + atari_machine_start(ATARI_800XL, &a800xl_pia_interface, TRUE); +} + + + +#ifdef MESS +DEVICE_LOAD( a800xl_cart ) +{ + UINT8 *mem = memory_region(REGION_CPU1); + astring *fname; + mame_file *basic_fp; + file_error filerr; + unsigned size; + + fname = astring_assemble_3(astring_alloc(), Machine->gamedrv->name, PATH_SEPARATOR, "basic.rom"); + filerr = mame_fopen(SEARCHPATH_ROM, astring_c(fname), OPEN_FLAG_READ, &basic_fp); + astring_free(fname); + + if (filerr != FILERR_NONE) + { + size = mame_fread(basic_fp, &mem[0x14000], 0x2000); + if( size < 0x2000 ) + { + logerror("%s image '%s' load failed (less than 8K)\n", Machine->gamedrv->name, astring_c(fname)); + mame_fclose(basic_fp); + return 2; + } + } + + /* load an optional (dual) cartidge (e.g. basic.rom) */ + if (filerr != FILERR_NONE) + { + { + size = image_fread(image, &mem[0x14000], 0x2000); + a800_cart_loaded = size / 0x2000; + size = image_fread(image, &mem[0x16000], 0x2000); + a800_cart_is_16k = size / 0x2000; + logerror("%s loaded cartridge '%s' size %s\n", + Machine->gamedrv->name, image_filename(image), (a800_cart_is_16k) ? "16K":"8K"); + } + mame_fclose(basic_fp); + } + + return INIT_PASS; +} +#endif + + + +/************************************* + * + * Atari 5200 console + * + *************************************/ + +MACHINE_START( a5200 ) +{ + atari_machine_start(ATARI_800XL, NULL, FALSE); +} + + + +#ifdef MESS +DEVICE_LOAD( a5200_cart ) +{ + UINT8 *mem = memory_region(REGION_CPU1); + int size; + + /* load an optional (dual) cartidge */ + size = image_fread(image, &mem[0x4000], 0x8000); + if (size<0x8000) memmove(mem+0x4000+0x8000-size, mem+0x4000, size); + // mirroring of smaller cartridges + if (size <= 0x1000) memcpy(mem+0xa000, mem+0xb000, 0x1000); + if (size <= 0x2000) memcpy(mem+0x8000, mem+0xa000, 0x2000); + if (size <= 0x4000) + { + const char *info; + memcpy(&mem[0x4000], &mem[0x8000], 0x4000); + info = image_extrainfo(image); + if (info!=NULL && strcmp(info, "A13MIRRORING")==0) + { + memcpy(&mem[0x8000], &mem[0xa000], 0x2000); + memcpy(&mem[0x6000], &mem[0x4000], 0x2000); + } + } + logerror("%s loaded cartridge '%s' size %dK\n", + Machine->gamedrv->name, image_filename(image) , size/1024); + return INIT_PASS; +} + +DEVICE_UNLOAD( a5200_cart ) +{ + UINT8 *mem = memory_region(REGION_CPU1); + /* zap the cartridge memory (again) */ + memset(&mem[0x4000], 0x00, 0x8000); +} +#endif + |