diff options
author | arbee <rb6502@users.noreply.github.com> | 2018-07-03 21:15:50 -0400 |
---|---|---|
committer | arbee <rb6502@users.noreply.github.com> | 2018-07-03 21:15:50 -0400 |
commit | e019d58dfeb770c18c97a03275498bca9424d580 (patch) | |
tree | 6739c4c12563d0a9a0d3afd0595f003ac17b95d3 | |
parent | 927623bb1811e029ff8666d8db447f2d9dbed6ae (diff) |
apple2gs: rewritten driver using bankdev. [R. Belmont]
-rw-r--r-- | src/mame/drivers/apple2gs.cpp | 5039 | ||||
-rw-r--r-- | src/mame/includes/apple2.h | 395 | ||||
-rw-r--r-- | src/mame/includes/apple2gs.h | 278 | ||||
-rw-r--r-- | src/mame/machine/apple2.cpp | 2537 | ||||
-rw-r--r-- | src/mame/machine/apple2gs.cpp | 2248 | ||||
-rw-r--r-- | src/mame/video/apple2.cpp | 301 | ||||
-rw-r--r-- | src/mame/video/apple2.h | 14 | ||||
-rw-r--r-- | src/mame/video/apple2gs.cpp | 168 |
8 files changed, 5103 insertions, 5877 deletions
diff --git a/src/mame/drivers/apple2gs.cpp b/src/mame/drivers/apple2gs.cpp index 5596e9fd4d3..41f949db46f 100644 --- a/src/mame/drivers/apple2gs.cpp +++ b/src/mame/drivers/apple2gs.cpp @@ -1,189 +1,3645 @@ // license:BSD-3-Clause -// copyright-holders:Nathan Woods,R. Belmont +// copyright-holders:R. Belmont /*************************************************************************** - drivers/apple2gs.c - Apple IIgs - Driver by Nathan Woods and R. Belmont - - TODO: - - Fix spurious interrupt problem (caused by ADB HLE; switching to emulation of the M50740 + GLU should solve this) - - Fix 5.25" disks - - Optimize video code - - More RAM configurations - - NOTES: - - Video timing and the h/vcount registers: - VCounts - HCounts go like this: 0xfa (start of frame, still in vblank) - 0 0x40 0x41 0x58 (first visible pixel) 0x7f - ____________________________________ 0x100 (first visible scan line) - | | - | | - | | - | | - | | - HBL region | | - | | - | | - | | - | | - | | 0x1c0 (first line of Vblank, c019 and heartbeat trigger here, only true VBL if in A2 classic modes) - | | - ____________________________________ 0x1c8 (actual start of vblank in IIgs modes) - - 0x1ff (end of frame, in vblank) - - There are 64 HCounts total, and 704 pixels total, so HCounts do not map to the pixel clock. - VCounts do map directly to scanlines however, and count 262 of them. - -================================================================= + apple2gs.cpp - Apple IIgs + Next generation driver written June 2018 by R. Belmont. + Thanks to the original Apple IIgs driver's authors: Nathan Woods, and R. Belmont + Thanks also to the Apple II Documentation Project/Antoine Vignau, Peter Ferrie, and Olivier Galibert. + + Unique hardware configurations: + - ROM 00/01: original motherboard, 256K of RAM (banks 00/01/E0/E1 only), FPI chip manages fast/slow side + - ROM 03: revised motherboard, 1M of RAM (banks 00/01/->0F/E0/E1), CYA chip replaces FPI + - Expanded IIe: ROM 00/01 motherboard in a IIe case with a IIe keyboard rather than ADB + ***************************************************************************/ +#define RUN_ADB_MICRO (0) +#define LOG_ADB (0) #include "emu.h" -#include "includes/apple2.h" -#include "includes/apple2e.h" -#include "includes/apple2gs.h" +#include "video/apple2.h" + +#include "screen.h" +#include "softlist.h" +#include "speaker.h" #include "cpu/g65816/g65816.h" -#include "imagedev/flopdrv.h" -#include "machine/appldriv.h" +#include "cpu/m6502/m5074x.h" +#include "sound/spkrdev.h" +#include "sound/es5503.h" +#include "machine/bankdev.h" +#include "machine/timer.h" +#include "machine/z80scc.h" +#include "machine/ram.h" +#include "machine/kb3600.h" + #include "machine/applefdc.h" #include "machine/sonydriv.h" -#include "machine/z80scc.h" -#include "sound/es5503.h" +#include "machine/appldriv.h" +#include "imagedev/flopdrv.h" +#include "formats/ap2_dsk.h" +#include "formats/ap_dsk35.h" + +#include "bus/rs232/rs232.h" + +#include "emu.h" +#include "video/apple2.h" -#include "bus/a2bus/a2diskii.h" +#include "bus/a2bus/a2bus.h" +#include "bus/a2bus/ramcard16k.h" +#include "bus/a2bus/a2diskiing.h" #include "bus/a2bus/a2mockingboard.h" #include "bus/a2bus/a2cffa.h" #include "bus/a2bus/a2memexp.h" #include "bus/a2bus/a2scsi.h" #include "bus/a2bus/a2thunderclock.h" -#include "bus/a2bus/a2ssc.h" #include "bus/a2bus/a2softcard.h" +#include "bus/a2bus/a2videoterm.h" +#include "bus/a2bus/a2ssc.h" +#include "bus/a2bus/a2swyft.h" +#include "bus/a2bus/a2themill.h" #include "bus/a2bus/a2sam.h" #include "bus/a2bus/a2alfam2.h" +#include "bus/a2bus/laser128.h" #include "bus/a2bus/a2echoii.h" #include "bus/a2bus/a2arcadebd.h" #include "bus/a2bus/a2midi.h" -#include "bus/a2bus/a2vulcan.h" #include "bus/a2bus/a2zipdrive.h" -//#include "bus/a2bus/a2udrive.h" -#include "bus/a2bus/a2hsscsi.h" +#include "bus/a2bus/a2applicard.h" +#include "bus/a2bus/a2ultraterm.h" +#include "bus/a2bus/a2pic.h" +#include "bus/a2bus/a2corvus.h" +#include "bus/a2bus/a2mcms.h" +#include "bus/a2bus/a2dx1.h" +#include "bus/a2bus/timemasterho.h" +#include "bus/a2bus/mouse.h" +#include "bus/a2bus/ezcgi.h" +//#include "bus/a2bus/pc_xporter.h" -#include "softlist.h" -#include "speaker.h" +// various timing standards +#define A2GS_MASTER_CLOCK (XTAL(28'636'363)) +#define A2GS_14M (A2GS_MASTER_CLOCK/2) +#define A2GS_7M (A2GS_MASTER_CLOCK/4) +#define A2GS_1M (A2GS_MASTER_CLOCK/28) -#include "formats/ap_dsk35.h" -#include "formats/ap2_dsk.h" +#define A2GS_CPU_TAG "maincpu" +#define A2GS_ADBMCU_TAG "adbmicro" +#define A2GS_KBDC_TAG "ay3600" +#define A2GS_BUS_TAG "a2bus" +#define A2GS_SPEAKER_TAG "speaker" +#define A2GS_CASSETTE_TAG "tape" +#define A2GS_UPPERBANK_TAG "inhbank" +#define A2GS_AUXUPPER_TAG "inhaux" +#define A2GS_00UPPER_TAG "inh00" +#define A2GS_01UPPER_TAG "inh01" +#define A2GS_IWM_TAG "fdc" // must be "fdc" or sonydriv pukes +#define A2GS_DOC_TAG "doc" +#define A2GS_VIDEO_TAG "a2video" +#define SCC_TAG "scc" +#define RS232A_TAG "printer" +#define RS232B_TAG "modem" + +#define A2GS_0000_TAG "r00bank" +#define A2GS_0200_TAG "r02bank" +#define A2GS_0400_TAG "r04bank" +#define A2GS_0800_TAG "r08bank" +#define A2GS_2000_TAG "r20bank" +#define A2GS_4000_TAG "r40bank" +#define A2GS_C100_TAG "c1bank" +#define A2GS_C300_TAG "c3bank" +#define A2GS_C400_TAG "c4bank" +#define A2GS_C800_TAG "c8bank" +#define A2GS_LCBANK_TAG "lcbank" +#define A2GS_LCAUX_TAG "lcaux" +#define A2GS_LC00_TAG "lc00" +#define A2GS_LC01_TAG "lc01" +#define A2GS_B0CXXX_TAG "bnk0atc" +#define A2GS_B01_TAG "bnk1at0" +#define A2GS_B1CXXX_TAG "bnk1atc" +#define A2GS_B00000_TAG "b0r00bank" +#define A2GS_B00200_TAG "b0r02bank" +#define A2GS_B00400_TAG "b0r04bank" +#define A2GS_B00800_TAG "b0r08bank" +#define A2GS_B02000_TAG "b0r20bank" +#define A2GS_B04000_TAG "b0r40bank" + +#define A2GS_KBD_Y0_TAG "Y0" +#define A2GS_KBD_Y1_TAG "Y1" +#define A2GS_KBD_Y2_TAG "Y2" +#define A2GS_KBD_Y3_TAG "Y3" +#define A2GS_KBD_Y4_TAG "Y4" +#define A2GS_KBD_Y5_TAG "Y5" +#define A2GS_KBD_Y6_TAG "Y6" +#define A2GS_KBD_Y7_TAG "Y7" +#define A2GS_KBD_Y8_TAG "Y8" +#define A2GS_KBD_Y9_TAG "Y9" +#define A2GS_KBD_SPEC_TAG "keyb_special" +#define CNXX_UNCLAIMED -1 +#define CNXX_INTROM -2 -static const gfx_layout apple2gs_text_layout = +enum glu_reg_names { - 14,8, /* 14*8 characters */ - 512, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes; 1 bit per pixel */ - { 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 }, /* x offsets */ - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 bytes */ + // these are the MCU-visible registers + GLU_KEY_DATA = 0, // MCU W + GLU_COMMAND, // MCU R + GLU_MOUSEX, // MCU W + GLU_MOUSEY, // MCU W + GLU_KG_STATUS, // MCU R + GLU_ANY_KEY_DOWN, // MCU W + GLU_KEYMOD, // MCU W + GLU_DATA, // MCU W + + GLU_C000, // 816 R + GLU_C010, // 816 RW + GLU_SYSSTAT // 816 R/(limited) W }; -static const gfx_layout apple2gs_dbltext_layout = +enum glu_kg_status { - 7,8, /* 7*8 characters */ - 512, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes; 1 bit per pixel */ - { 7, 6, 5, 4, 3, 2, 1 }, /* x offsets */ - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 bytes */ + KGS_ANY_KEY_DOWN = 0x01, + KGS_KEYSTROBE = 0x10, + KGS_DATA_FULL = 0x20, + KGS_COMMAND_FULL = 0x40, + KGS_MOUSEX_FULL = 0x80 }; -static GFXDECODE_START( gfx_apple2gs ) - GFXDECODE_ENTRY( "gfx1", 0x0000, apple2gs_text_layout, 0, 2 ) - GFXDECODE_ENTRY( "gfx1", 0x0000, apple2gs_dbltext_layout, 0, 2 ) -GFXDECODE_END - -static const unsigned char apple2gs_palette[] = -{ - 0x0, 0x0, 0x0, /* Black $0 $0000 */ - 0xD, 0x0, 0x3, /* Deep Red $1 $0D03 */ - 0x0, 0x0, 0x9, /* Dark Blue $2 $0009 */ - 0xD, 0x2, 0xD, /* Purple $3 $0D2D */ - 0x0, 0x7, 0x2, /* Dark Green $4 $0072 */ - 0x5, 0x5, 0x5, /* Dark Gray $5 $0555 */ - 0x2, 0x2, 0xF, /* Medium Blue $6 $022F */ - 0x6, 0xA, 0xF, /* Light Blue $7 $06AF */ - 0x8, 0x5, 0x0, /* Brown $8 $0850 */ - 0xF, 0x6, 0x0, /* Orange $9 $0F60 */ - 0xA, 0xA, 0xA, /* Light Gray $A $0AAA */ - 0xF, 0x9, 0x8, /* Pink $B $0F98 */ - 0x1, 0xD, 0x0, /* Light Green $C $01D0 */ - 0xF, 0xF, 0x0, /* Yellow $D $0FF0 */ - 0x4, 0xF, 0x9, /* Aquamarine $E $04F9 */ - 0xF, 0xF, 0xF /* White $F $0FFF */ +enum glu_sys_status +{ + GLU_STATUS_CMDFULL = 0x01, + GLU_STATUS_MOUSEXY = 0x02, + GLU_STATUS_KEYDATIRQEN = 0x04, + GLU_STATUS_KEYDATIRQ = 0x08, + GLU_STATUS_DATAIRQEN = 0x10, + GLU_STATUS_DATAIRQ = 0x20, + GLU_STATUS_MOUSEIRQEN = 0x40, + GLU_STATUS_MOUSEIRQ = 0x080 }; -static INPUT_PORTS_START( apple2gs ) - PORT_INCLUDE( apple2ep ) +enum shadow_reg_bits +{ + SHAD_IOLC = 0x40, // I/O and language card inhibit for banks 00/01 + SHAD_TXTPG2 = 0x20, // inhibits text-page 2 shadowing in both banks (ROM 03 h/w only) + SHAD_AUXHIRES = 0x10, // inhibits bank 01 hi-res region shadowing + SHAD_SUPERHIRES = 0x08, // inhibits bank 01 super-hi-res region shadowing + SHAD_HIRESPG2 = 0x04, // inhibits hi-res page 2 shadowing in both banks + SHAD_HIRESPG1 = 0x02, // inhibits hi-res page 1 shadowing in both banks + SHAD_TXTPG1 = 0x01 // inhibits text-page 1 shadowing in both banks +}; - PORT_START("adb_mouse_x") - PORT_BIT( 0x7f, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Mouse Button 1") +enum speed_reg_bits +{ + SPEED_HIGH = 0x80, // full 2.8 MHz speed when set, Apple II 1 MHz when clear + SPEED_POWERON = 0x40, // ROM 03 only; indicates machine turned on by power switch (as opposed to ?) + SPEED_ALLBANKS = 0x10, // enables bank 0/1 shadowing in all banks (not supported) + SPEED_DISKIISL7 = 0x08, // enable Disk II motor on detect for slot 7 + SPEED_DISKIISL6 = 0x04, // enable Disk II motor on detect for slot 6 + SPEED_DISKIISL5 = 0x02, // enable Disk II motor on detect for slot 5 + SPEED_DISKIISL4 = 0x01 // enable Disk II motor on detect for slot 4 +}; - PORT_START("adb_mouse_y") - PORT_BIT( 0x7f, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Mouse Button 0") +enum disk_reg_bits +{ + DISKREG_35HEADSEL = 0x80, // head select for 3.5" "dumb" Sony drives + DISKREG_35ENABLE = 0x40 // 1 to enable 3.5" drives, 0 to chain through to 5.25" +}; -INPUT_PORTS_END +enum irq_sources +{ + IRQS_DOC = 0, + IRQS_SCAN = 1, + IRQS_ADB = 2, + IRQS_VBL = 3, + IRQS_SECOND = 4, + IRQS_QTRSEC = 5, + IRQS_SLOT = 6 +}; + +enum intflag_bits +{ + INTFLAG_IRQASSERTED = 0x01, + INTFLAG_M2MOUSEMOVE = 0x02, + INTFLAG_M2MOUSESW = 0x04, + INTFLAG_VBL = 0x08, + INTFLAG_QUARTER = 0x10, + INTFLAG_AN3 = 0x20, + INTFLAG_MOUSEDOWNLAST = 0x40, + INTFLAG_MOUSEDOWN = 0x80 +}; + +enum vgcint_bits +{ + VGCINT_EXTERNALEN = 0x01, + VGCINT_SCANLINEEN = 0x02, + VGCINT_SECONDENABLE = 0x04, + VGCINT_EXTERNAL = 0x10, + VGCINT_SCANLINE = 0x20, + VGCINT_SECOND = 0x40, + VGCINT_ANYVGCINT = 0x80 +}; + +enum apple2gs_clock_mode +{ + CLOCKMODE_IDLE, + CLOCKMODE_TIME, + CLOCKMODE_INTERNALREGS, + CLOCKMODE_BRAM1, + CLOCKMODE_BRAM2 +}; + +enum adbstate_t +{ + ADBSTATE_IDLE, + ADBSTATE_INCOMMAND, + ADBSTATE_INRESPONSE +}; + +class apple2gs_state : public driver_device +{ +public: + apple2gs_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, A2GS_CPU_TAG), + m_screen(*this, "screen"), + m_adbmicro(*this, A2GS_ADBMCU_TAG), + m_ram(*this, RAM_TAG), + m_rom(*this, "maincpu"), + m_docram(*this, A2GS_DOC_TAG), + m_video(*this, A2GS_VIDEO_TAG), + m_a2bus(*this, A2GS_BUS_TAG), + m_joy1x(*this, "joystick_1_x"), + m_joy1y(*this, "joystick_1_y"), + m_joy2x(*this, "joystick_2_x"), + m_joy2y(*this, "joystick_2_y"), + m_joybuttons(*this, "joystick_buttons"), + m_speaker(*this, A2GS_SPEAKER_TAG), + m_upperbank(*this, A2GS_UPPERBANK_TAG), + m_upperaux(*this, A2GS_AUXUPPER_TAG), + m_upper00(*this, A2GS_00UPPER_TAG), + m_upper01(*this, A2GS_01UPPER_TAG), + m_0000bank(*this, A2GS_0000_TAG), + m_0200bank(*this, A2GS_0200_TAG), + m_0400bank(*this, A2GS_0400_TAG), + m_0800bank(*this, A2GS_0800_TAG), + m_2000bank(*this, A2GS_2000_TAG), + m_4000bank(*this, A2GS_4000_TAG), + m_c100bank(*this, A2GS_C100_TAG), + m_c300bank(*this, A2GS_C300_TAG), + m_c400bank(*this, A2GS_C400_TAG), + m_c800bank(*this, A2GS_C800_TAG), + m_b0_0000bank(*this, A2GS_B00000_TAG), + m_b0_0200bank(*this, A2GS_B00200_TAG), + m_b0_0400bank(*this, A2GS_B00400_TAG), + m_b0_0800bank(*this, A2GS_B00800_TAG), + m_b0_2000bank(*this, A2GS_B02000_TAG), + m_b0_4000bank(*this, A2GS_B04000_TAG), + m_lcbank(*this, A2GS_LCBANK_TAG), + m_lcaux(*this, A2GS_LCAUX_TAG), + m_lc00(*this, A2GS_LC00_TAG), + m_lc01(*this, A2GS_LC01_TAG), + m_bank0_atc(*this, A2GS_B0CXXX_TAG), + m_bank1_at0(*this, A2GS_B01_TAG), + m_bank1_atc(*this, A2GS_B1CXXX_TAG), + m_scc(*this, SCC_TAG), + m_doc(*this, A2GS_DOC_TAG), + m_iwm(*this, A2GS_IWM_TAG), + m_ky0(*this, A2GS_KBD_Y0_TAG), + m_ky1(*this, A2GS_KBD_Y1_TAG), + m_ky2(*this, A2GS_KBD_Y2_TAG), + m_ky3(*this, A2GS_KBD_Y3_TAG), + m_ky4(*this, A2GS_KBD_Y4_TAG), + m_ky5(*this, A2GS_KBD_Y5_TAG), + m_ky6(*this, A2GS_KBD_Y6_TAG), + m_ky7(*this, A2GS_KBD_Y7_TAG), + m_ky8(*this, A2GS_KBD_Y8_TAG), + m_ky9(*this, A2GS_KBD_Y9_TAG), + m_kbspecial(*this, A2GS_KBD_SPEC_TAG), + m_ay3600(*this, "ay3600"), + m_kbdrom(*this, "keyboard"), + m_adb_mousex(*this, "adb_mouse_x"), + m_adb_mousey(*this, "adb_mouse_y") + { } + + required_device<g65816_device> m_maincpu; + required_device<screen_device> m_screen; + required_device<m5074x_device> m_adbmicro; + required_device<ram_device> m_ram; + required_memory_region m_rom, m_docram; + required_device<a2_video_device> m_video; + required_device<a2bus_device> m_a2bus; + required_ioport m_joy1x, m_joy1y, m_joy2x, m_joy2y, m_joybuttons; + required_device<speaker_sound_device> m_speaker; + required_device<address_map_bank_device> m_upperbank, m_upperaux, m_upper00, m_upper01; + required_device<address_map_bank_device> m_0000bank, m_0200bank, m_0400bank, m_0800bank, m_2000bank, m_4000bank, m_c100bank, m_c300bank, m_c400bank, m_c800bank; + required_device<address_map_bank_device> m_b0_0000bank, m_b0_0200bank, m_b0_0400bank, m_b0_0800bank, m_b0_2000bank, m_b0_4000bank; + required_device<address_map_bank_device> m_lcbank, m_lcaux, m_lc00, m_lc01, m_bank0_atc, m_bank1_at0, m_bank1_atc; + required_device<z80scc_device> m_scc; + required_device<es5503_device> m_doc; + required_device<applefdc_base_device> m_iwm; + optional_ioport m_ky0, m_ky1, m_ky2, m_ky3, m_ky4, m_ky5, m_ky6, m_ky7, m_ky8, m_ky9; + required_ioport m_kbspecial; + optional_device<ay3600_device> m_ay3600; + required_memory_region m_kbdrom; + required_ioport m_adb_mousex, m_adb_mousey; + + uint64_t m_last_adb_time; + int m_adb_dtime; + bool m_adb_line; + + address_space *m_maincpu_space; + + TIMER_DEVICE_CALLBACK_MEMBER(apple2_interrupt); + + virtual void machine_start() override; + virtual void machine_reset() override; + + DECLARE_PALETTE_INIT(apple2gs); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + DECLARE_READ8_MEMBER(ram0000_r); + DECLARE_WRITE8_MEMBER(ram0000_w); + DECLARE_READ8_MEMBER(ram0200_r); + DECLARE_WRITE8_MEMBER(ram0200_w); + DECLARE_READ8_MEMBER(ram0400_r); + DECLARE_WRITE8_MEMBER(ram0400_w); + DECLARE_READ8_MEMBER(ram0800_r); + DECLARE_WRITE8_MEMBER(ram0800_w); + DECLARE_READ8_MEMBER(ram2000_r); + DECLARE_WRITE8_MEMBER(ram2000_w); + DECLARE_READ8_MEMBER(ram4000_r); + DECLARE_WRITE8_MEMBER(ram4000_w); + DECLARE_READ8_MEMBER(auxram0000_r); + DECLARE_WRITE8_MEMBER(auxram0000_w); + DECLARE_READ8_MEMBER(auxram0200_r); + DECLARE_WRITE8_MEMBER(auxram0200_w); + DECLARE_READ8_MEMBER(auxram0400_r); + DECLARE_WRITE8_MEMBER(auxram0400_w); + DECLARE_READ8_MEMBER(auxram0800_r); + DECLARE_WRITE8_MEMBER(auxram0800_w); + DECLARE_READ8_MEMBER(auxram2000_r); + DECLARE_WRITE8_MEMBER(auxram2000_w); + DECLARE_READ8_MEMBER(auxram4000_r); + DECLARE_WRITE8_MEMBER(auxram4000_w); + DECLARE_READ8_MEMBER(b0ram0000_r); + DECLARE_WRITE8_MEMBER(b0ram0000_w); + DECLARE_READ8_MEMBER(b0ram0200_r); + DECLARE_WRITE8_MEMBER(b0ram0200_w); + DECLARE_READ8_MEMBER(b0ram0400_r); + DECLARE_WRITE8_MEMBER(b0ram0400_w); + DECLARE_READ8_MEMBER(b0ram0800_r); + DECLARE_WRITE8_MEMBER(b0ram0800_w); + DECLARE_READ8_MEMBER(b0ram2000_r); + DECLARE_WRITE8_MEMBER(b0ram2000_w); + DECLARE_READ8_MEMBER(b0ram4000_r); + DECLARE_WRITE8_MEMBER(b0ram4000_w); + DECLARE_READ8_MEMBER(b1ram0000_r); + DECLARE_WRITE8_MEMBER(b1ram0000_w); + DECLARE_READ8_MEMBER(b1ram0200_r); + DECLARE_WRITE8_MEMBER(b1ram0200_w); + DECLARE_READ8_MEMBER(b1ram0400_r); + DECLARE_WRITE8_MEMBER(b1ram0400_w); + DECLARE_READ8_MEMBER(b1ram0800_r); + DECLARE_WRITE8_MEMBER(b1ram0800_w); + DECLARE_READ8_MEMBER(b1ram2000_r); + DECLARE_WRITE8_MEMBER(b1ram2000_w); + DECLARE_READ8_MEMBER(b1ram4000_r); + DECLARE_WRITE8_MEMBER(b1ram4000_w); + DECLARE_READ8_MEMBER(c000_r); + DECLARE_WRITE8_MEMBER(c000_w); + DECLARE_READ8_MEMBER(c080_r); + DECLARE_WRITE8_MEMBER(c080_w); + DECLARE_READ8_MEMBER(c100_r); + DECLARE_READ8_MEMBER(c100_int_r); + DECLARE_WRITE8_MEMBER(c100_w); + DECLARE_READ8_MEMBER(c300_r); + DECLARE_READ8_MEMBER(c300_int_r); + DECLARE_WRITE8_MEMBER(c300_w); + DECLARE_READ8_MEMBER(c400_r); + DECLARE_READ8_MEMBER(c400_int_r); + DECLARE_WRITE8_MEMBER(c400_w); + DECLARE_READ8_MEMBER(c800_r); + DECLARE_READ8_MEMBER(c800_int_r); + DECLARE_WRITE8_MEMBER(c800_w); + DECLARE_READ8_MEMBER(inh_r); + DECLARE_WRITE8_MEMBER(inh_w); + DECLARE_READ8_MEMBER(lc_r); + DECLARE_WRITE8_MEMBER(lc_w); + DECLARE_READ8_MEMBER(lc_aux_r); + DECLARE_WRITE8_MEMBER(lc_aux_w); + DECLARE_READ8_MEMBER(lc_00_r); + DECLARE_WRITE8_MEMBER(lc_00_w); + DECLARE_READ8_MEMBER(lc_01_r); + DECLARE_WRITE8_MEMBER(lc_01_w); + DECLARE_READ8_MEMBER(bank0_0000_r); + DECLARE_WRITE8_MEMBER(bank0_0000_w); + DECLARE_READ8_MEMBER(bank0_c000_r); + DECLARE_WRITE8_MEMBER(bank0_c000_w); + DECLARE_READ8_MEMBER(bank1_0000_r); + DECLARE_WRITE8_MEMBER(bank1_0000_w); + DECLARE_WRITE8_MEMBER(bank1_0000_sh_w); + DECLARE_READ8_MEMBER(bank1_c000_r); + DECLARE_WRITE8_MEMBER(bank1_c000_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_irq_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_nmi_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_inh_w); + DECLARE_WRITE_LINE_MEMBER(doc_irq); + DECLARE_READ8_MEMBER(doc_adc_read); + DECLARE_READ8_MEMBER(apple2gs_read_vector); + +#if !RUN_ADB_MICRO + DECLARE_READ_LINE_MEMBER(ay3600_shift_r); + DECLARE_READ_LINE_MEMBER(ay3600_control_r); + DECLARE_WRITE_LINE_MEMBER(ay3600_data_ready_w); + DECLARE_WRITE_LINE_MEMBER(ay3600_ako_w); + TIMER_DEVICE_CALLBACK_MEMBER(ay3600_repeat); +#endif + + void apple2gs(machine_config &config); + void apple2gsr1(machine_config &config); + + void apple2gs_map(address_map &map); + void vectors_map(address_map &map); + void c100bank_map(address_map &map); + void c300bank_map(address_map &map); + void c400bank_map(address_map &map); + void c800bank_map(address_map &map); + void inhbank_map(address_map &map); + void inhaux_map(address_map &map); + void inh00_map(address_map &map); + void inh01_map(address_map &map); + void lcbank_map(address_map &map); + void lcaux_map(address_map &map); + void lc00_map(address_map &map); + void lc01_map(address_map &map); + void r0000bank_map(address_map &map); + void r0200bank_map(address_map &map); + void r0400bank_map(address_map &map); + void r0800bank_map(address_map &map); + void r2000bank_map(address_map &map); + void r4000bank_map(address_map &map); + void bank0_iolc_map(address_map &map); + void bank1_lower48_map(address_map &map); + void bank1_iolc_map(address_map &map); + void rb0000bank_map(address_map &map); + void rb0200bank_map(address_map &map); + void rb0400bank_map(address_map &map); + void rb0800bank_map(address_map &map); + void rb2000bank_map(address_map &map); + void rb4000bank_map(address_map &map); + + uint8_t keyglu_mcu_read(uint8_t offset); + void keyglu_mcu_write(uint8_t offset, uint8_t data); + uint8_t keyglu_816_read(uint8_t offset); + void keyglu_816_write(uint8_t offset, uint8_t data); + void keyglu_regen_irqs(); + + DECLARE_READ8_MEMBER(adbmicro_p0_in); + DECLARE_READ8_MEMBER(adbmicro_p1_in); + DECLARE_READ8_MEMBER(adbmicro_p2_in); + DECLARE_READ8_MEMBER(adbmicro_p3_in); + DECLARE_WRITE8_MEMBER(adbmicro_p0_out); + DECLARE_WRITE8_MEMBER(adbmicro_p1_out); + DECLARE_WRITE8_MEMBER(adbmicro_p2_out); + DECLARE_WRITE8_MEMBER(adbmicro_p3_out); + + // temp old IWM hookup + int apple2_fdc_has_35(); + int apple2_fdc_has_525(); + void apple2_iwm_setdiskreg(uint8_t data); + + uint8_t m_diskreg; // move into private when we can + + void rom1_init() { m_is_rom3 = false; } + void rom3_init() { m_is_rom3 = true; } + +private: + bool m_is_rom3; + int m_speaker_state; + + double m_joystick_x1_time; + double m_joystick_y1_time; + double m_joystick_x2_time; + double m_joystick_y2_time; + + int m_inh_slot; + int m_cnxx_slot; + + bool m_page2; + bool m_an0, m_an1, m_an2, m_an3; + + bool m_vbl; + + int m_irqmask; + + bool m_intcxrom; + bool m_80store; + bool m_slotc3rom; + bool m_altzp; + bool m_ramrd, m_ramwrt; + bool m_lcram, m_lcram2, m_lcprewrite, m_lcwriteenable; + bool m_ioudis; + + uint8_t m_shadow, m_speed, m_textcol; + uint8_t m_motors_active, m_slotromsel, m_intflag, m_vgcint, m_inten; + + bool m_last_speed; + + // Sound GLU variables + uint8_t m_sndglu_ctrl; + int m_sndglu_addr; + int m_sndglu_dummy_read; + + // Key GLU variables + uint8_t m_glu_regs[8], m_glu_bus, m_glu_sysstat; + bool m_glu_mcu_read_kgs, m_glu_816_read_dstat, m_glu_mouse_read_stat; + int m_glu_kbd_y; + + uint8_t *m_ram_ptr, *m_rom_ptr, *m_docram_ptr; + int m_ram_size; + + int m_inh_bank; + + double m_x_calibration, m_y_calibration; + + device_a2bus_card_interface *m_slotdevice[8]; + + uint32_t m_slow_counter; + + // clock/BRAM + uint8_t m_clkdata, m_clock_control, m_clock_read, m_clock_reg1; + apple2gs_clock_mode m_clock_mode; + uint32_t m_clock_curtime; + seconds_t m_clock_curtime_interval; + uint8_t m_clock_bram[256]; + int m_clock_frame; + + // ADB simulation + #if !RUN_ADB_MICRO + adbstate_t m_adb_state; + uint8_t m_adb_command; + uint8_t m_adb_mode; + uint8_t m_adb_kmstatus; + uint8_t m_adb_latent_result; + int32_t m_adb_command_length; + int32_t m_adb_command_pos; + uint8_t m_adb_response_length; + int32_t m_adb_response_pos; + uint8_t m_adb_command_bytes[8]; + uint8_t m_adb_response_bytes[8]; + uint8_t m_adb_memory[0x100]; + int m_adb_address_keyboard; + int m_adb_address_mouse; + + uint16_t m_lastchar, m_strobe; + uint8_t m_transchar; + bool m_anykeydown; + int m_repeatdelay; + + uint8_t adb_read_datareg(); + uint8_t adb_read_kmstatus(); + uint8_t adb_read_memory(uint32_t address); + void adb_write_memory(uint32_t address, uint8_t data); + void adb_set_mode(uint8_t mode); + void adb_set_config(uint8_t b1, uint8_t b2, uint8_t b3); + void adb_post_response(const uint8_t *bytes, size_t length); + void adb_post_response_1(uint8_t b); + void adb_post_response_2(uint8_t b1, uint8_t b2); + void adb_do_command(); + void adb_write_datareg(uint8_t data); + void adb_write_kmstatus(uint8_t data); + uint8_t adb_read_mousedata(); + int8_t seven_bit_diff(uint8_t v1, uint8_t v2); + void adb_check_mouse(); + #endif + + uint8_t m_mouse_x; + uint8_t m_mouse_y; + int8_t m_mouse_dx; + int8_t m_mouse_dy; + + void do_io(address_space &space, int offset); + uint8_t read_floatingbus(); + void update_slotrom_banks(); + void lc_update(int offset, bool writing); + uint8_t read_slot_rom(address_space &space, int slotbias, int offset); + void write_slot_rom(address_space &space, int slotbias, int offset, uint8_t data); + uint8_t read_int_rom(address_space &space, int slotbias, int offset); + void auxbank_update(); + void raise_irq(int irq); + void lower_irq(int irq); + void update_speed(); + int get_vpos(); + void process_clock(); +}; + +#define slow_cycle() \ +{ \ + if (!m_last_speed) \ + {\ + m_slow_counter += 0x0002cccc; \ + int cycles = (m_slow_counter >> 16) & 0xffff; \ + m_slow_counter &= 0xffff; \ + m_maincpu->adjust_icount(-cycles); \ + } \ +} + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +#define JOYSTICK_DELTA 80 +#define JOYSTICK_SENSITIVITY 50 +#define JOYSTICK_AUTOCENTER 80 + +WRITE_LINE_MEMBER(apple2gs_state::a2bus_irq_w) +{ + if (state == ASSERT_LINE) + { + raise_irq(IRQS_SLOT); + } + else + { + lower_irq(IRQS_SLOT); + } +} + +WRITE_LINE_MEMBER(apple2gs_state::a2bus_nmi_w) +{ + m_maincpu->set_input_line(INPUT_LINE_NMI, state); +} + +// TODO: this assumes /INH only on ROM, needs expansion to support e.g. phantom-slotting cards and etc. +WRITE_LINE_MEMBER(apple2gs_state::a2bus_inh_w) +{ + if (state == ASSERT_LINE) + { + // assume no cards are pulling /INH + m_inh_slot = -1; + + // scan the slots to figure out which card(s) are INHibiting stuff + for (int i = 0; i <= 7; i++) + { + if (m_slotdevice[i]) + { + // this driver only can inhibit from 0xd000-0xffff + if ((m_slotdevice[i]->inh_start() == 0xd000) && + (m_slotdevice[i]->inh_end() == 0xffff)) + { + if ((m_slotdevice[i]->inh_type() & INH_READ) == INH_READ) + { + if (m_inh_bank != 1) + { + m_upperbank->set_bank(1); + m_upperaux->set_bank(1); + m_upper00->set_bank(1); + m_upper01->set_bank(1); + m_inh_bank = 1; + } + } + else + { + if (m_inh_bank != 0) + { + m_upperbank->set_bank(0); + m_upperaux->set_bank(0); + m_upper00->set_bank(0); + m_upper01->set_bank(0); + m_inh_bank = 0; + } + } + + m_inh_slot = i; + break; + } + } + } + + // if no slots are inhibiting, make sure ROM is fully switched in + if ((m_inh_slot == -1) && (m_inh_bank != 0)) + { + m_upperbank->set_bank(0); + m_upperaux->set_bank(0); + m_upper00->set_bank(0); + m_upper01->set_bank(0); + m_inh_bank = 0; + } + } +} + +// FPI/CYA chip is connected to the VPB output of the 65816. +// this facilitates the documented behavior from the Firmware Reference. +READ8_MEMBER(apple2gs_state::apple2gs_read_vector) +{ + // when IOLC shadowing is enabled, vector fetches always go to ROM, + // regardless of the language card config. + if (!(m_shadow & SHAD_IOLC)) + { + return m_maincpu->space(AS_PROGRAM).read_byte(offset | 0xFFFFE0); + } + else // else vector fetches from bank 0 RAM + { + return m_maincpu->space(AS_PROGRAM).read_byte((offset & 0xffff) | 0xFFE0); + } +} + +/*************************************************************************** + ADB MCU simulation +***************************************************************************/ +#if !RUN_ADB_MICRO +READ_LINE_MEMBER(apple2gs_state::ay3600_shift_r) +{ + // either shift key + if (m_kbspecial->read() & 0x06) + { + return ASSERT_LINE; + } + + return CLEAR_LINE; +} + +READ_LINE_MEMBER(apple2gs_state::ay3600_control_r) +{ + if (m_kbspecial->read() & 0x08) + { + return ASSERT_LINE; + } + + return CLEAR_LINE; +} + +WRITE_LINE_MEMBER(apple2gs_state::ay3600_data_ready_w) +{ + if (state == ASSERT_LINE) + { + uint8_t *decode = m_kbdrom->base(); + uint16_t trans; + + m_lastchar = m_ay3600->b_r(); + + trans = m_lastchar & ~(0x1c0); // clear the 3600's control/shift stuff + trans |= (m_lastchar & 0x100)>>2; // bring the 0x100 bit down to the 0x40 place + trans <<= 2; // 4 entries per key + trans |= (m_kbspecial->read() & 0x06) ? 0x00 : 0x01; // shift is bit 1 (active low) + trans |= (m_kbspecial->read() & 0x08) ? 0x00 : 0x02; // control is bit 2 (active low) + trans |= (m_kbspecial->read() & 0x01) ? 0x0000 : 0x0200; // caps lock is bit 9 (active low) + + m_transchar = decode[trans]; + m_strobe = 0x80; + + //printf("new char = %04x (%02x)\n", m_lastchar, m_transchar); + } +} + +WRITE_LINE_MEMBER(apple2gs_state::ay3600_ako_w) +{ + m_anykeydown = (state == ASSERT_LINE) ? true : false; + + if (m_anykeydown) + { + m_repeatdelay = 10; + } +} + +TIMER_DEVICE_CALLBACK_MEMBER(apple2gs_state::ay3600_repeat) +{ + // is the key still down? + if (m_anykeydown) + { + if (m_repeatdelay) + { + m_repeatdelay--; + } + else + { + m_strobe = 0x80; + } + } +} + +uint8_t apple2gs_state::adb_read_memory(uint32_t address) +{ + if (address < ARRAY_LENGTH(m_adb_memory)) + return m_adb_memory[address]; + else + return 0x00; +} + +void apple2gs_state::adb_write_memory(uint32_t address, uint8_t data) +{ + if (address < ARRAY_LENGTH(m_adb_memory)) + m_adb_memory[address] = data; +} + +void apple2gs_state::adb_set_mode(uint8_t mode) +{ + m_adb_mode = mode; +} + +void apple2gs_state::adb_set_config(uint8_t b1, uint8_t b2, uint8_t b3) +{ + /* ignore for now */ +} + +void apple2gs_state::adb_post_response(const uint8_t *bytes, size_t length) +{ + assert(length < ARRAY_LENGTH(m_adb_response_bytes)); + memcpy(m_adb_response_bytes, bytes, length); + m_adb_state = ADBSTATE_INRESPONSE; + m_adb_response_length = length; + m_adb_response_pos = 0; +} + +void apple2gs_state::adb_post_response_1(uint8_t b) +{ + adb_post_response(&b, 1); +} + +void apple2gs_state::adb_post_response_2(uint8_t b1, uint8_t b2) +{ + uint8_t b[2]; + b[0] = b1; + b[1] = b2; + adb_post_response(b, 2); +} + +void apple2gs_state::adb_do_command() +{ + int device; + uint32_t address; + uint8_t val; + + m_adb_state = ADBSTATE_IDLE; + if (LOG_ADB) + logerror("adb_do_command(): adb_command=0x%02x\n", m_adb_command); + + switch(m_adb_command) + { + case 0x00: /* ??? */ + break; + + case 0x03: /* flush keyboard buffer */ + break; + + case 0x04: /* set modes */ + adb_set_mode(m_adb_mode | m_adb_command_bytes[0]); + break; + + case 0x05: /* clear modes */ + adb_set_mode(m_adb_mode & ~m_adb_command_bytes[0]); + break; + + case 0x06: /* set config */ + adb_set_config(m_adb_command_bytes[0], m_adb_command_bytes[1], m_adb_command_bytes[2]); + break; + + case 0x07: /* synchronize */ + adb_set_mode(m_adb_command_bytes[0]); + adb_set_config(m_adb_command_bytes[1], m_adb_command_bytes[2], m_adb_command_bytes[3]); + break; + + case 0x08: /* write memory */ + address = m_adb_command_bytes[0]; + val = m_adb_command_bytes[1]; + adb_write_memory(address, val); + break; + + case 0x09: /* read memory */ + address = (m_adb_command_bytes[1] << 8) | m_adb_command_bytes[0]; + adb_post_response_1(adb_read_memory(address)); + break; + + case 0x0a: /* ??? */ + case 0x0b: /* ??? */ + break; + + case 0x0d: /* get version */ + adb_post_response_1(0x06); + break; + + case 0x0e: /* read available charsets */ + adb_post_response_2(0x01, 0x00); + break; + + case 0x0f: /* read available layouts */ + adb_post_response_2(0x01, 0x00); + break; + case 0x12: /* mystery command 0x12 */ + case 0x13: /* mystery command 0x13 */ + break; -/* Initialize the palette */ -PALETTE_INIT_MEMBER(apple2gs_state,apple2gs) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + /* send data to device */ + device = m_adb_command & 0x0f; + if (device == m_adb_address_keyboard) + { + } + else if (device == m_adb_address_mouse) + { + } + break; + + case 0xf2: + break; + + default: + fatalerror("ADB command 0x%02x unimplemented\n", m_adb_command); + } + m_adb_kmstatus |= 0x20; +} + +uint8_t apple2gs_state::adb_read_datareg() { - int i; + uint8_t result; -// PALETTE_INIT_NAME(apple2)(palette); + switch(m_adb_state) + { + case ADBSTATE_INRESPONSE: + result = m_adb_response_bytes[m_adb_response_pos++]; + if (m_adb_response_pos >= m_adb_response_length) + { + m_adb_state = ADBSTATE_IDLE; + m_adb_latent_result = result; + m_adb_kmstatus &= ~0x20; + } + break; - for (i = 0; i < 16; i++) + default: + result = 0; //m_adb_latent_result & 0x7f; + break; + } + + if (LOG_ADB) + logerror("adb_read_datareg(): result=0x%02x\n", result); + + return result; +} + +void apple2gs_state::adb_write_datareg(uint8_t data) +{ + if (LOG_ADB) + logerror("adb_write_datareg(): data=0x%02x\n", data); + + switch(m_adb_state) + { + case ADBSTATE_IDLE: + m_adb_command = data; + m_adb_command_length = 0; + m_adb_command_pos = 0; + +// printf("ADB command %02x\n", data); + switch(data) + { + case 0x00: /* ??? */ + case 0x01: /* abort */ + /* do nothing for now */ + break; + + case 0x03: /* flush keyboard buffer */ + m_adb_command_length = 0; + break; + + case 0x04: /* set modes */ + case 0x05: /* clear modes */ + m_adb_command_length = 1; + break; + + case 0x06: /* set config */ + m_adb_command_length = 3; + break; + + case 0x07: /* synchronize */ + if (m_is_rom3) + m_adb_command_length = 8; // ROM 3 has 8 bytes: mode byte, 3 config bytes, kbd/mouse params, disk eject options + else + m_adb_command_length = 4; // ROM 0/1 has 4 bytes sync + break; + + case 0x08: /* write memory */ + case 0x09: /* read memory */ + m_adb_command_length = 2; + break; + + case 0x0a: /* ??? */ + case 0x0b: /* ??? */ + m_adb_command_length = 0; + break; + + case 0x0d: /* get version */ + m_adb_command_length = 0; + break; + + case 0x0e: /* read available charsets */ + m_adb_command_length = 0; + m_adb_state = ADBSTATE_INCOMMAND; /* HACK */ + break; + + case 0x0f: /* read available layouts */ + m_adb_command_length = 0; + m_adb_state = ADBSTATE_INCOMMAND; /* HACK */ + break; + + case 0x12: /* mystery command 0x12 */ + case 0x13: /* mystery command 0x13 */ + m_adb_command_length = 2; + break; + + case 0x70: /* disable SRQ device 0 */ + case 0x71: /* disable SRQ device 1 */ + case 0x72: /* disable SRQ device 2 */ + case 0x73: /* disable SRQ device 3 */ + /* ignore for now */ + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + /* send data to device */ + m_adb_command_length = 2; + break; + + case 0xf2: + break; + + default: + fatalerror("ADB command 0x%02x unimplemented\n", data); + } + + if (m_adb_command_length > 0) + { + m_adb_state = ADBSTATE_INCOMMAND; + if (LOG_ADB) + logerror("adb_write_datareg(): in command length %u\n", (unsigned) m_adb_command_length); + } + break; + + case ADBSTATE_INCOMMAND: + assert(m_adb_command_pos < ARRAY_LENGTH(m_adb_command_bytes)); +// printf("ADB param %02x\n", data); + m_adb_command_bytes[m_adb_command_pos++] = data; + break; + + case ADBSTATE_INRESPONSE: + m_adb_state = ADBSTATE_IDLE; + break; + } + + /* do command if necessary */ + if ((m_adb_state == ADBSTATE_INCOMMAND) && (m_adb_command_pos >= m_adb_command_length)) + adb_do_command(); +} + +// real rom 3 h/w reads 0x90 when idle, 0x98 when key pressed +// current MESS reads back 0xb0 when idle +uint8_t apple2gs_state::adb_read_kmstatus() +{ + return m_adb_kmstatus; +} + + +void apple2gs_state::adb_write_kmstatus(uint8_t data) +{ + m_adb_kmstatus &= ~0x54; + m_adb_kmstatus |= data & 0x54; +} + + + +uint8_t apple2gs_state::adb_read_mousedata() +{ + uint8_t result = 0x00; + uint8_t absolute; + int8_t delta; + + if (m_adb_kmstatus & 0x80) // mouse register full + { + if (m_adb_kmstatus & 0x02) // H/V mouse data select + { + absolute = m_mouse_y; + delta = m_mouse_dy; + m_adb_kmstatus &= ~0x82; + lower_irq(IRQS_ADB); + } + else + { + absolute = m_mouse_x; + delta = m_mouse_dx; + m_adb_kmstatus |= 0x02; + } + + if (delta > 63) + delta = 63; + else if (delta < -64) + delta = -64; + + result = (absolute & 0x80) | (delta & 0x7F); + } + return result; +} + + +int8_t apple2gs_state::seven_bit_diff(uint8_t v1, uint8_t v2) +{ + v1 -= v2; + if (v1 & 0x40) + v1 |= 0x80; + else + v1 &= ~0x80; + return v1; +} + + + +void apple2gs_state::adb_check_mouse() +{ + uint8_t new_mouse_x, new_mouse_y; + + /* read mouse values */ + if ((m_adb_kmstatus & 0x80) == 0x00) + { + new_mouse_x = m_adb_mousex->read(); + new_mouse_y = m_adb_mousey->read(); + + if ((m_mouse_x != new_mouse_x) || (m_mouse_y != new_mouse_y)) + { + m_mouse_dx = seven_bit_diff(new_mouse_x, m_mouse_x); + m_mouse_dy = seven_bit_diff(new_mouse_y, m_mouse_y); + m_mouse_x = new_mouse_x; + m_mouse_y = new_mouse_y; + + m_adb_kmstatus |= 0x80; + m_adb_kmstatus &= ~0x02; + if (m_adb_kmstatus & 0x40) + { + raise_irq(IRQS_ADB); + } + } + } +} +#endif + +/*************************************************************************** + START/RESET +***************************************************************************/ + +void apple2gs_state::machine_start() +{ + m_ram_ptr = m_ram->pointer(); + m_ram_size = m_ram->size(); + m_rom_ptr = m_rom->base(); + m_docram_ptr = m_docram->base(); + m_speaker_state = 0; + m_speaker->level_w(m_speaker_state); + m_upperbank->set_bank(0); + m_upperaux->set_bank(0); + m_upper00->set_bank(0); + m_upper01->set_bank(0); + m_lcbank->set_bank(0); + m_lcaux->set_bank(0); + m_lc00->set_bank(0); + m_lc01->set_bank(0); + m_0000bank->set_bank(0); + m_0200bank->set_bank(0); + m_0400bank->set_bank(0); + m_0800bank->set_bank(0); + m_2000bank->set_bank(0); + m_4000bank->set_bank(0); + m_b0_0000bank->set_bank(0); + m_b0_0200bank->set_bank(0); + m_b0_0400bank->set_bank(0); + m_b0_0800bank->set_bank(0); + m_b0_2000bank->set_bank(0); + m_b0_4000bank->set_bank(0); + m_inh_bank = 0; + + // precalculate joystick time constants + m_x_calibration = attotime::from_usec(12).as_double(); + m_y_calibration = attotime::from_usec(13).as_double(); + + // cache slot devices + for (int i = 0; i <= 7; i++) + { + m_slotdevice[i] = m_a2bus->get_a2bus_card(i); + } + + // setup video pointers + m_video->m_ram_ptr = m_ram_ptr; + m_video->m_aux_ptr = &m_ram_ptr[0x10000]; + m_video->m_char_ptr = memregion("gfx1")->base(); + m_video->m_char_size = memregion("gfx1")->bytes(); + m_video->m_8bit_graphics = std::make_unique<bitmap_ind16>(560, 192); + + m_inh_slot = -1; + m_cnxx_slot = CNXX_UNCLAIMED; + + // install memory beyond 256K/1M + address_space& space = m_maincpu->space(AS_PROGRAM); + int ramsize = m_ram_size - 0x40000; + + // ROM 00/01 hardware: the quoted "256K" for a base machine *does* include banks e0/e1. + space.install_readwrite_bank(0x020000, ramsize - 1 + 0x20000, "bank1"); + membank("bank1")->set_base(m_ram_ptr + 0x040000); + + // setup save states + save_item(NAME(m_speaker_state)); + save_item(NAME(m_joystick_x1_time)); + save_item(NAME(m_joystick_y1_time)); + save_item(NAME(m_joystick_x2_time)); + save_item(NAME(m_joystick_y2_time)); + save_item(NAME(m_inh_slot)); + save_item(NAME(m_inh_bank)); + save_item(NAME(m_cnxx_slot)); + save_item(NAME(m_page2)); + save_item(NAME(m_an0)); + save_item(NAME(m_an1)); + save_item(NAME(m_an2)); + save_item(NAME(m_an3)); + save_item(NAME(m_intcxrom)); + save_item(NAME(m_80store)); + save_item(NAME(m_slotc3rom)); + save_item(NAME(m_altzp)); + save_item(NAME(m_ramrd)); + save_item(NAME(m_ramwrt)); + save_item(NAME(m_ioudis)); + save_item(NAME(m_vbl)); + save_item(NAME(m_irqmask)); + save_item(NAME(m_lcram)); + save_item(NAME(m_lcram2)); + save_item(NAME(m_lcprewrite)); + save_item(NAME(m_lcwriteenable)); + save_item(NAME(m_shadow)); + save_item(NAME(m_speed)); + save_item(NAME(m_textcol)); + save_item(NAME(m_clock_control)); + save_item(NAME(m_clkdata)); + save_item(NAME(m_motors_active)); + save_item(NAME(m_slotromsel)); + save_item(NAME(m_diskreg)); + save_item(NAME(m_sndglu_ctrl)); + save_item(NAME(m_sndglu_addr)); + save_item(NAME(m_sndglu_dummy_read)); + save_item(NAME(m_last_speed)); + save_item(NAME(m_glu_regs)); + save_item(NAME(m_glu_bus)); + save_item(NAME(m_glu_sysstat)); + save_item(NAME(m_glu_mcu_read_kgs)); + save_item(NAME(m_glu_816_read_dstat)); + save_item(NAME(m_glu_mouse_read_stat)); + save_item(NAME(m_glu_kbd_y)); + save_item(NAME(m_intflag)); + save_item(NAME(m_vgcint)); + save_item(NAME(m_inten)); + save_item(m_clkdata, "CLKDATA"); + save_item(m_clock_control, "CLKCTRL"); + save_item(m_clock_read, "CLKRD"); + save_item(m_clock_reg1, "CLKREG1"); + save_item(m_clock_curtime, "CLKCURTIME"); + save_item(m_clock_curtime_interval, "CLKCURTIMEINT"); +// save_item(m_clock_mode, "CLKMODE"); + save_item(NAME(m_clock_bram)); + save_item(NAME(m_clock_frame)); +#if !RUN_ADB_MICRO + save_item(NAME(m_adb_memory)); + save_item(NAME(m_adb_command_bytes)); + save_item(NAME(m_adb_response_bytes)); +// save_item(m_adb_state, "ADB/m_adb_state"); + save_item(m_adb_command, "ADB/m_adb_command"); + save_item(m_adb_mode, "ADB/m_adb_mode"); + save_item(m_adb_kmstatus, "ADB/m_adb_kmstatus"); + save_item(m_adb_latent_result, "ADB/m_adb_latent_result"); + save_item(m_adb_command_length, "ADB/m_adb_command_length"); + save_item(m_adb_command_pos, "ADB/m_adb_command_pos"); + save_item(m_adb_response_length, "ADB/m_adb_response_length"); + save_item(m_adb_response_pos, "ADB/m_adb_response_pos"); + save_item(m_adb_address_keyboard, "ADB/m_adb_address_keyboard"); + save_item(m_adb_address_mouse, "ADB/m_adb_address_mouse"); + save_item(NAME(m_lastchar)); + save_item(NAME(m_strobe)); + save_item(NAME(m_transchar)); +#endif + save_item(m_mouse_x, "MX"); + save_item(m_mouse_y, "MY"); + save_item(m_mouse_dx, "MDX"); + save_item(m_mouse_dy, "MDY"); +} + +void apple2gs_state::machine_reset() +{ + m_page2 = false; + m_video->m_page2 = false; + m_an0 = m_an1 = m_an2 = m_an3 = false; + m_vbl = false; + m_slotc3rom = false; + m_irqmask = 0; + m_intcxrom = false; + m_80store = false; + m_video->m_80store = false; + m_altzp = false; + m_ramrd = false; + m_ramwrt = false; + m_ioudis = true; + m_clock_frame = 0; + m_mouse_x = 0x00; + m_mouse_y = 0x00; + m_mouse_dx = 0x00; + m_mouse_dy = 0x00; + + #if !RUN_ADB_MICRO + m_adb_state = ADBSTATE_IDLE; + m_adb_kmstatus = 0x00; + m_adb_command = 0; + m_adb_mode = 0; + m_adb_latent_result = 0; + m_adb_command_length = 0; + m_adb_command_pos = 0; + m_adb_response_length = 0; + m_adb_response_pos = 0; + memset(m_adb_command_bytes, 0, sizeof(m_adb_command_bytes)); + memset(m_adb_response_bytes, 0, sizeof(m_adb_response_bytes)); + memset(m_adb_memory, 0, sizeof(m_adb_memory)); + m_adb_address_keyboard = 2; + m_adb_address_mouse = 3; + #endif + + /* init time */ + m_clkdata = 0; + m_clock_control =0; + m_clock_read = 0; + m_clock_reg1 = 0; + m_clock_mode = CLOCKMODE_IDLE; + m_clock_curtime = 0; + m_clock_curtime_interval = 0; + + m_shadow = 0x00; + m_speed = 0x80; + m_motors_active = 0; + m_diskreg = 0; + m_intflag = 0; + m_vgcint = 0; + m_inten = 0; + + m_slow_counter = 0; + + // always assert full speed on reset + m_maincpu->set_unscaled_clock(A2GS_14M/5); + m_last_speed = true; + + m_sndglu_ctrl = 0; + m_sndglu_addr = 0; + m_sndglu_dummy_read = 0; + + m_maincpu_space = &m_maincpu->space(AS_PROGRAM); + + m_0000bank->set_bank(0); + m_0200bank->set_bank(0); + m_0400bank->set_bank(0); + m_0800bank->set_bank(0); + m_2000bank->set_bank(0); + m_4000bank->set_bank(0); + m_b0_0000bank->set_bank(0); + m_b0_0200bank->set_bank(0); + m_b0_0400bank->set_bank(0); + m_b0_0800bank->set_bank(0); + m_b0_2000bank->set_bank(0); + m_b0_4000bank->set_bank(0); + m_bank0_atc->set_bank(1); + m_bank1_at0->set_bank(1); + m_bank1_atc->set_bank(1); + + // LC default state: read ROM, write enabled, Dxxx bank 2 + m_lcram = false; + m_lcram2 = true; + m_lcprewrite = false; + m_lcwriteenable = true; + + // sync up the banking with the variables. + // RESEARCH: how does RESET affect LC state and aux banking states? + auxbank_update(); + update_slotrom_banks(); + + // with all the banking reset, now reset the CPU + m_maincpu->reset(); +} + +void apple2gs_state::raise_irq(int irq) +{ + m_irqmask |= (1 << irq); + + if (m_irqmask) + { + m_intflag |= INTFLAG_IRQASSERTED; + m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE); + } +} + + +void apple2gs_state::lower_irq(int irq) +{ + m_irqmask &= ~(1 << irq); + + if (!m_irqmask) + { + m_intflag &= ~INTFLAG_IRQASSERTED; + m_maincpu->set_input_line(G65816_LINE_IRQ, CLEAR_LINE); + } +} + +void apple2gs_state::update_speed() +{ + bool isfast = false; + + if (m_speed & SPEED_HIGH) + { + isfast = true; + } + + if ((m_motors_active & (m_speed & 0x0f)) != 0) + { + isfast = false; + } + + // prevent unnecessary reschedules by only setting this if it changed + if (isfast != m_last_speed) + { + m_maincpu->set_unscaled_clock(isfast ? A2GS_14M/5 : A2GS_1M); + m_last_speed = isfast; + } +} + +/*************************************************************************** + VIDEO +***************************************************************************/ + +TIMER_DEVICE_CALLBACK_MEMBER(apple2gs_state::apple2_interrupt) +{ + int scanline = m_screen->vpos(); + m_screen->update_partial(scanline); + + if ((scanline % 8) == 0) + { + #if !RUN_ADB_MICRO + adb_check_mouse(); + #endif + } + + /* check scanline interrupt bits if we're in super hi-res and the current scanline is within the active display area */ + if ((m_video->m_newvideo & 0x80) && (scanline >= (BORDER_TOP-1)) && (scanline < (200+BORDER_TOP-1))) + { + uint8_t scb; + + scb = m_ram_ptr[0x19d00 + scanline - BORDER_TOP + 1]; + + if (scb & 0x40) + { + // scanline int flag is set even when the actual interrupt is disabled + m_vgcint |= VGCINT_SCANLINE; + + // see if the interrupt is also enabled and trigger it if so + if (m_vgcint & VGCINT_SCANLINEEN) + { + m_vgcint |= VGCINT_ANYVGCINT; + raise_irq(IRQS_SCAN); + } + } + } + + if (scanline == (192+BORDER_TOP)) + { + m_vbl = true; + + /* VBL interrupt */ + if ((m_inten & 0x08) && !(m_intflag & INTFLAG_VBL)) + { + m_intflag |= INTFLAG_VBL; + raise_irq(IRQS_VBL); + } + + m_adbmicro->set_input_line(0, ASSERT_LINE); + m_video->m_sysconfig = 0; + + m_clock_frame++; + + // quarter second? + if ((m_clock_frame % 15) == 0) + { + if ((m_inten & 0x10) && !(m_intflag & INTFLAG_QUARTER)) + { + m_intflag |= INTFLAG_QUARTER; + raise_irq(IRQS_QTRSEC); + } + } + + // one second + if (m_clock_frame >= 60) + { + m_clock_frame = 0; + if ((m_vgcint & VGCINT_SECONDENABLE) && !(m_vgcint & VGCINT_SECOND)) + { + m_vgcint |= (VGCINT_SECOND|VGCINT_ANYVGCINT); + raise_irq(IRQS_SECOND); + } + } + } + else if (scanline == (192+BORDER_TOP+1)) + { + m_adbmicro->set_input_line(1, ASSERT_LINE); + } +} + +PALETTE_INIT_MEMBER(apple2gs_state, apple2gs) +{ + static const unsigned char apple2gs_palette[] = + { + 0x0, 0x0, 0x0, /* Black $0 $0000 */ + 0xD, 0x0, 0x3, /* Deep Red $1 $0D03 */ + 0x0, 0x0, 0x9, /* Dark Blue $2 $0009 */ + 0xD, 0x2, 0xD, /* Purple $3 $0D2D */ + 0x0, 0x7, 0x2, /* Dark Green $4 $0072 */ + 0x5, 0x5, 0x5, /* Dark Gray $5 $0555 */ + 0x2, 0x2, 0xF, /* Medium Blue $6 $022F */ + 0x6, 0xA, 0xF, /* Light Blue $7 $06AF */ + 0x8, 0x5, 0x0, /* Brown $8 $0850 */ + 0xF, 0x6, 0x0, /* Orange $9 $0F60 */ + 0xA, 0xA, 0xA, /* Light Gray $A $0AAA */ + 0xF, 0x9, 0x8, /* Pink $B $0F98 */ + 0x1, 0xD, 0x0, /* Light Green $C $01D0 */ + 0xF, 0xF, 0x0, /* Yellow $D $0FF0 */ + 0x4, 0xF, 0x9, /* Aquamarine $E $04F9 */ + 0xF, 0xF, 0xF /* White $F $0FFF */ + }; + + for (int i = 0; i < 16; i++) { palette.set_pen_color(i, apple2gs_palette[(3*i)]*17, apple2gs_palette[(3*i)+1]*17, apple2gs_palette[(3*i)+2]*17); - m_a2_palette[i] = rgb_t(apple2gs_palette[(3*i)]*17, apple2gs_palette[(3*i)+1]*17, apple2gs_palette[(3*i)+2]*17); + m_video->m_GSborder_colors[i] = rgb_t(apple2gs_palette[(3*i)]*17, apple2gs_palette[(3*i)+1]*17, apple2gs_palette[(3*i)+2]*17); } } -READ8_MEMBER(apple2gs_state::apple2gs_adc_read) +uint32_t apple2gs_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - return 0x80; + return m_video->screen_update_GS(screen, bitmap, cliprect); +} + +/*************************************************************************** + I/O +***************************************************************************/ +void apple2gs_state::auxbank_update() +{ + int ramwr = (m_ramrd ? 1 : 0) | (m_ramwrt ? 2 : 0); + + m_0000bank->set_bank(m_altzp ? 1 : 0); + m_b0_0000bank->set_bank(m_altzp ? 1 : 0); + m_0200bank->set_bank(ramwr); + m_b0_0200bank->set_bank(ramwr); + + if (m_80store) + { + if (m_page2) + { + m_0400bank->set_bank(3); + m_b0_0400bank->set_bank(3); + } + else + { + m_0400bank->set_bank(0); + m_b0_0400bank->set_bank(0); + } + } + else + { + m_0400bank->set_bank(ramwr); + m_b0_0400bank->set_bank(ramwr); + } + + m_0800bank->set_bank(ramwr); + m_b0_0800bank->set_bank(ramwr); + + if ((m_80store) && (m_video->m_hires)) + { + if (m_page2) + { + m_2000bank->set_bank(3); + m_b0_2000bank->set_bank(3); + } + else + { + m_2000bank->set_bank(0); + m_b0_2000bank->set_bank(0); + } + } + else + { + m_2000bank->set_bank(ramwr); + m_b0_2000bank->set_bank(ramwr); + } + + m_4000bank->set_bank(ramwr); + m_b0_4000bank->set_bank(ramwr); } -static const floppy_interface apple2gs_floppy35_floppy_interface = +void apple2gs_state::update_slotrom_banks() { - FLOPPY_STANDARD_5_25_DSHD, - LEGACY_FLOPPY_OPTIONS_NAME(apple35_iigs), - "floppy_3_5" -}; + int cxswitch = 0; -static const floppy_interface apple2gs_floppy525_floppy_interface = + if (m_intcxrom) + { + cxswitch = 1; + } + + m_c100bank->set_bank(cxswitch); + m_c400bank->set_bank(cxswitch); + + //printf("update_slotrom_banks: intcxrom %d cnxx_slot %d SLOT %02x\n", m_intcxrom, m_cnxx_slot, m_slotromsel); + if ((m_intcxrom) || (m_cnxx_slot < 0)) + { + m_c800bank->set_bank(1); + } + else + { + m_c800bank->set_bank(0); + } + + // slot 3 ROM is controlled exclusively by SLOTC3ROM + if (!m_slotc3rom) + { + m_c300bank->set_bank(1); + } + else + { + m_c300bank->set_bank(0); + } +} + +void apple2gs_state::lc_update(int offset, bool writing) { - FLOPPY_STANDARD_5_25_DSHD, - LEGACY_FLOPPY_OPTIONS_NAME(apple2), - "floppy_5_25" -}; + bool old_lcram = m_lcram; + + //any even access disables pre-write and writing + if ((offset & 1) == 0) + { + m_lcprewrite = false; + m_lcwriteenable = false; + } + + //any write disables pre-write + //has no effect on write-enable if writing was enabled already + if (writing == true) + { + m_lcprewrite = false; + } + //first odd read enables pre-write, second one enables writing + else if ((offset & 1) == 1) + { + if (m_lcprewrite == false) + { + m_lcprewrite = true; + } + else + { + m_lcwriteenable = true; + } + } + + switch (offset & 3) + { + case 0: + case 3: + { + m_lcram = true; + break; + } + + case 1: + case 2: + { + m_lcram = false; + break; + } + } + + m_lcram2 = false; + + if (!(offset & 8)) + { + m_lcram2 = true; + } + + if (m_lcram != old_lcram) + { + if (m_lcram) + { + m_lcbank->set_bank(1); + m_lcaux->set_bank(1); + m_lc00->set_bank(1); + m_lc01->set_bank(1); + } + else + { + m_lcbank->set_bank(0); + m_lcaux->set_bank(0); + m_lc00->set_bank(0); + m_lc01->set_bank(0); + } + } + + #if 0 + printf("LC: new state %c%c dxxx=%04x altzp=%d\n", + m_lcram ? 'R' : 'x', + m_lcwriteenable ? 'W' : 'x', + m_lcram2 ? 0x1000 : 0x0000, + m_altzp); + #endif +} + +// most softswitches don't care about read vs write, so handle them here +void apple2gs_state::do_io(address_space &space, int offset) +{ + if(machine().side_effects_disabled()) return; + + if (m_ioudis) + { + switch (offset) + { + case 0x5e: // SETDHIRES + m_video->m_dhires = true; + return; + + case 0x5f: // CLRDHIRES + m_video->m_dhires = false; + return; + } + } + + switch (offset) + { + case 0x20: + break; + + case 0x28: + break; + + case 0x30: + m_speaker_state ^= 1; + m_speaker->level_w(m_speaker_state); + break; + + case 0x50: // graphics mode + m_video->m_graphics = true; + break; + + case 0x51: // text mode + m_video->m_graphics = false; + break; + + case 0x52: // no mix + m_video->m_mix = false; + break; + + case 0x53: // mixed mode + m_video->m_mix = true; + break; + + case 0x54: // set page 1 + m_page2 = false; + m_video->m_page2 = false; + auxbank_update(); + break; + + case 0x55: // set page 2 + m_page2 = true; + m_video->m_page2 = true; + auxbank_update(); + break; + + case 0x56: // select lo-res + m_video->m_hires = false; + auxbank_update(); + break; + + case 0x57: // select hi-res + m_video->m_hires = true; + auxbank_update(); + break; + + case 0x58: // AN0 off + m_an0 = false; break; + + case 0x59: // AN0 on + m_an0 = true; break; + + case 0x5a: // AN1 off + m_an1 = false; break; + + case 0x5b: // AN1 on + m_an1 = true; break; + + case 0x5c: // AN2 off + m_an2 = false; break; + + case 0x5d: // AN2 on + m_an2 = true; break; + + case 0x5e: // AN3 off + m_an3 = false; break; + + case 0x5f: // AN3 on + m_an3 = true; break; + + case 0x68: // STATE + break; + + // trigger joypad read + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: + m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_joy1x->read(); + m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_joy1y->read(); + m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_joy2x->read(); + m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_joy2y->read(); + break; + + default: + logerror("do_io: unknown switch $C0%02X\n", offset); + break; + } +} + +// apple2gs_get_vpos - return the correct vertical counter value for the current scanline, +// keeping borders in mind. + +int apple2gs_state::get_vpos() +{ + int result, scan; + static const uint8_t top_border_vert[BORDER_TOP] = + { + 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, + 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, + + }; + + scan = m_screen->vpos(); + + if (scan < BORDER_TOP) + { + result = top_border_vert[scan]; + } + else + { + result = scan - BORDER_TOP + 0x100 + 1; + } + + return result; +} + +void apple2gs_state::process_clock() +{ + uint8_t operation; + seconds_t current_interval; + + /* update clock_curtime */ + current_interval = machine().time().seconds(); + m_clock_curtime += current_interval - m_clock_curtime_interval; + m_clock_curtime_interval = current_interval; + + switch(m_clock_mode) + { + case CLOCKMODE_IDLE: + m_clock_read = (m_clkdata >> 7); + m_clock_reg1 = (m_clkdata >> 2) & 0x03; + operation = (m_clkdata >> 4) & 0x07; + + if ((m_clkdata & 0x40) == 0x00) + { + switch(operation) + { + case 0x00: + /* read/write seconds register */ + m_clock_mode = CLOCKMODE_TIME; + break; + + case 0x03: + /* internal registers */ + if (m_clock_reg1 & 0x02) + { + m_clock_mode = CLOCKMODE_BRAM2; + m_clock_reg1 = (m_clkdata & 0x07) << 5; + } + else + { + m_clock_mode = CLOCKMODE_INTERNALREGS; + } + break; + + default: + //fatalerror("NYI\n"); + break; + } + } + break; + + case CLOCKMODE_BRAM1: + if (m_clock_read) + m_clkdata = m_clock_bram[m_clock_reg1]; + else + m_clock_bram[m_clock_reg1] = m_clkdata; + m_clock_mode = CLOCKMODE_IDLE; + break; + + case CLOCKMODE_BRAM2: + m_clock_reg1 |= (m_clkdata >> 2) & 0x1F; + m_clock_mode = CLOCKMODE_BRAM1; + break; + + case CLOCKMODE_INTERNALREGS: + switch (m_clock_reg1) + { + case 0x00: + /* test register */ + break; + + case 0x01: + /* write protect register */ + break; + } + m_clock_mode = CLOCKMODE_IDLE; + break; + + case CLOCKMODE_TIME: + if (m_clkdata & 0x40) + { + m_clkdata = m_clock_curtime >> (m_clock_reg1 * 8); + } + else + { + m_clock_curtime &= ~(0xFF << (m_clock_reg1 * 8)); + m_clock_curtime |= m_clkdata << (m_clock_reg1 * 8); + } + m_clock_mode = CLOCKMODE_IDLE; + break; + + default: + //fatalerror("NYI\n"); + break; + } +} + +READ8_MEMBER(apple2gs_state::c000_r) +{ + uint8_t ret; + + if(machine().side_effects_disabled()) return read_floatingbus(); + + slow_cycle(); + + switch (offset) + { + case 0x00: // keyboard latch + #if RUN_ADB_MICRO + return keyglu_816_read(GLU_C000); + #else + return m_transchar | m_strobe; + #endif + + case 0x02: // RAMRDOFF + m_ramrd = false; + auxbank_update(); + break; + + case 0x03: // RAMRDON + m_ramrd = true; + auxbank_update(); + break; + + case 0x04: // RAMWRTOFF + m_ramwrt = false; + auxbank_update(); + break; + + case 0x05: // RAMWRTON + m_ramwrt = true; + auxbank_update(); + break; + + case 0x10: // read any key down, reset keyboard strobe + #if RUN_ADB_MICRO + return keyglu_816_read(GLU_C010); + #else + ret = m_transchar | (m_anykeydown ? 0x80 : 0x00); + m_strobe = 0; + return ret; + #endif + + case 0x11: // read LCRAM2 (LC Dxxx bank) + return m_lcram2 ? 0x80 : 0x00; + + case 0x12: // read LCRAM (is LC readable?) + return m_lcram ? 0x80 : 0x00; + + case 0x13: // read RAMRD + return m_ramrd ? 0x80 : 0x00; + + case 0x14: // read RAMWRT + return m_ramwrt ? 0x80 : 0x00; + + case 0x15: // read INTCXROM + return m_intcxrom ? 0x80 : 0x00; + + case 0x16: // read ALTZP + return m_altzp ? 0x80 : 0x00; + + case 0x17: // read SLOTC3ROM + return m_slotc3rom ? 0x80 : 0x00; + + case 0x18: // read 80STORE + return m_80store ? 0x80 : 0x00; + + case 0x19: // read VBLBAR + return m_screen->vblank() ? 0x00 : 0x80; + + case 0x1a: // read TEXT + return m_video->m_graphics ? 0x00 : 0x80; + + case 0x1b: // read MIXED + return m_video->m_mix ? 0x80 : 0x00; + + case 0x1c: // read PAGE2 + return m_page2 ? 0x80 : 0x00; + + case 0x1d: // read HIRES + return m_video->m_hires ? 0x80 : 0x00; + + case 0x1e: // read ALTCHARSET + return m_video->m_altcharset ? 0x80 : 0x00; + + case 0x1f: // read 80COL + return m_video->m_80col ? 0x80 : 0x00; + + case 0x22: // TEXTCOL + return m_textcol; + + case 0x23: // VGCINT + return m_vgcint; +#if RUN_ADB_MICRO + case 0x24: // MOUSEDATA */ + return keyglu_816_read(GLU_MOUSEX); + + case 0x25: // KEYMODREG + return keyglu_816_read(GLU_KEYMOD); + + case 0x26: // DATAREG + return keyglu_816_read(GLU_DATA); + + case 0x27: // KMSTATUS + return keyglu_816_read(GLU_SYSSTAT); +#else + case 0x24: // MOUSEDATA */ + return adb_read_mousedata(); + + case 0x25: // KEYMODREG + ret = 0; + { + uint8_t temp = m_kbspecial->read(); + if (temp & 1) // capslock + { + ret |= 4; + } + if (temp & 6) // shift + { + ret |= 1; + } + if (temp & 8) // control + { + ret |= 2; + } + if (temp & 0x10) // open apple/command + { + ret |= 0x40; + } + if (temp & 0x20) // option + { + ret |= 0x80; + } + // keypad is a little rough right now + if (m_lastchar >= 0x28 && m_lastchar <= 0x2d) + { + ret |= 0x10; + } + else if (m_lastchar >= 0x32 && m_lastchar <= 0x3f) + { + ret |= 0x10; + } + else if (m_lastchar >= 0x100 && m_lastchar <= 0x101) + { + ret |= 0x10; + } + else if (m_lastchar >= 0x109 && m_lastchar <= 0x10a) + { + ret |= 0x10; + } + } + return ret; + + case 0x26: // DATAREG + return adb_read_datareg(); + + case 0x27: // KMSTATUS + return adb_read_kmstatus(); +#endif + + case 0x29: // NEWVIDEO + return m_video->m_newvideo; + + case 0x2d: // SLOTROMSEL + return m_slotromsel; + + case 0x2e: // VERTCNT + return get_vpos() >> 1; + + case 0x2f: // HORIZCNT + ret = m_screen->hpos() / 11; + if (ret > 0) + { + ret += 0x40; + } + + if (get_vpos() & 1) + { + ret |= 0x80; + } + return ret; + + case 0x31: // DISKREG + return m_diskreg; + + case 0x33: // CLOCKDATA + return m_clkdata; + + case 0x34: // BORDERCOL + return m_clock_control; + + case 0x35: // SHADOW + return m_shadow; + + case 0x36: // SPEED/CYAREG + return m_speed; + + case 0x38: // SCCBREG + return m_scc->cb_r(space, 0); + + case 0x39: // SCCAREG + return m_scc->ca_r(space, 0); + + case 0x3a: // SCCBDATA + return m_scc->db_r(space, 0); + + case 0x3b: // SCCADATA + return m_scc->da_r(space, 0); + + case 0x3c: // SOUNDCTL + return m_sndglu_ctrl; + + case 0x3d: // SOUNDDATA + ret = m_sndglu_dummy_read; + + if (m_sndglu_ctrl & 0x40) // docram access + { + m_sndglu_dummy_read = m_docram_ptr[m_sndglu_addr]; + } + else + { + m_sndglu_dummy_read = m_doc->read(space, m_sndglu_addr); + } + + if (m_sndglu_ctrl & 0x20) // auto-increment + { + m_sndglu_addr++; + } + return ret; + + case 0x3e: // SOUNDADRL + return m_sndglu_addr & 0xff; + + case 0x3f: // SOUNDADRH + return (m_sndglu_addr >> 8) & 0xff; + + case 0x41: // INTEN + return m_inten; + + case 0x46: // INTFLAG + return (m_an3 ? INTFLAG_AN3 : 0x00) | m_intflag; + + case 0x60: // button 3 on IIgs + return (m_joybuttons->read() & 0x80); + + case 0x61: // button 0 or Open Apple + return ((m_joybuttons->read() & 0x10) || (m_kbspecial->read() & 0x10)) ? 0x80 : 0; + + case 0x62: // button 1 or Solid Apple + return ((m_joybuttons->read() & 0x20) || (m_kbspecial->read() & 0x20)) ? 0x80 : 0; + + case 0x63: // button 2 or SHIFT key + return ((m_joybuttons->read() & 0x40) || (m_kbspecial->read() & 0x06)) ? 0x80 : 0; + + case 0x64: // joy 1 X axis + return (machine().time().as_double() < m_joystick_x1_time) ? 0x80 : 0; + + case 0x65: // joy 1 Y axis + return (machine().time().as_double() < m_joystick_y1_time) ? 0x80 : 0; + + case 0x66: // joy 2 X axis + return (machine().time().as_double() < m_joystick_x2_time) ? 0x80 : 0; + + case 0x67: // joy 2 Y axis + return (machine().time().as_double() < m_joystick_y2_time) ? 0x80 : 0; + + case 0x68: // STATEREG, synthesizes all the IIe state regs + return (m_altzp ? 0x80 : 0x00) | + (m_page2 ? 0x40 : 0x00) | + (m_ramrd ? 0x20 : 0x00) | + (m_ramwrt ? 0x10 : 0x00) | + (m_lcram ? 0x00 : 0x08) | + (m_lcram2 ? 0x04 : 0x00) | + (m_intcxrom ? 0x01 : 0x00); + + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: + // todo: does reading these on the IIgs also trigger the joysticks? + m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_joy1x->read(); + m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_joy1y->read(); + m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_joy2x->read(); + m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_joy2y->read(); + + return m_rom_ptr[offset + 0x3c000]; + break; + + default: + do_io(space, offset); + break; + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(apple2gs_state::c000_w) +{ + if(machine().side_effects_disabled()) return; + + slow_cycle(); + + switch (offset) + { + case 0x00: // 80STOREOFF + m_80store = false; + m_video->m_80store = false; + auxbank_update(); + break; + + case 0x01: // 80STOREON + m_80store = true; + m_video->m_80store = true; + auxbank_update(); + break; + + case 0x02: // RAMRDOFF + m_ramrd = false; + auxbank_update(); + break; + + case 0x03: // RAMRDON + m_ramrd = true; + auxbank_update(); + break; + + case 0x04: // RAMWRTOFF + m_ramwrt = false; + auxbank_update(); + break; + + case 0x05: // RAMWRTON + m_ramwrt = true; + auxbank_update(); + break; + + case 0x06: // INTCXROMOFF + m_intcxrom = false; + update_slotrom_banks(); + break; + + case 0x07: // INTCXROMON + m_intcxrom = true; + update_slotrom_banks(); + break; + + case 0x08: // ALTZPOFF + m_altzp = false; + auxbank_update(); + break; + + case 0x09: // ALTZPON + m_altzp = true; + auxbank_update(); + break; + + case 0x0a: // SETINTC3ROM + m_slotc3rom = false; + update_slotrom_banks(); + break; + + case 0x0b: // SETSLOTC3ROM + m_slotc3rom = true; + update_slotrom_banks(); + break; + + case 0x0c: // 80COLOFF + m_video->m_80col = false; + break; + + case 0x0d: // 80COLON + m_video->m_80col = true; + break; + + case 0x0e: // ALTCHARSETOFF + m_video->m_altcharset = false; + break; + + case 0x0f: // ALTCHARSETON + m_video->m_altcharset = true; + break; + + case 0x10: // clear keyboard latch + #if RUN_ADB_MICRO + keyglu_816_write(GLU_C010, data); + break; + #else + m_strobe = 0; + break; + #endif + + case 0x20: + break; + + case 0x21: // MONOCHROME + m_video->m_monochrome = data; + break; + + case 0x22: // TEXTCOL + m_textcol = data; + m_video->m_GSfg = (data >> 4) & 0xf; + m_video->m_GSbg = data & 0xf; + break; + + case 0x23: // VGCINT + m_vgcint &= 0xf0; + m_vgcint |= (data & 0x0f); + printf("%02x to VGCINT, now %02x\n", data, m_vgcint); + break; + +#if RUN_ADB_MICRO + case 0x26: // DATAREG + keyglu_816_write(GLU_COMMAND, data); + break; + + case 0x27: // KMSTATUS + keyglu_816_write(GLU_SYSSTAT, data); + break; +#else + case 0x26: // DATAREG + adb_write_datareg(data); + break; + + case 0x27: // KMSTATUS + adb_write_kmstatus(data); + break; +#endif + + case 0x29: // NEWVIDEO + m_video->m_newvideo = data; + break; + + case 0x2d: // SLOTROMSEL + m_slotromsel = data; + break; + + case 0x31: // DISKREG + m_diskreg = data; + apple2_iwm_setdiskreg(m_diskreg); + break; + + case 0x32: // VGCINTCLEAR + // one second + if ((m_vgcint & VGCINT_SECOND) && !(data & VGCINT_SECOND)) + { + lower_irq(IRQS_SECOND); + m_vgcint &= ~(VGCINT_SECOND|VGCINT_ANYVGCINT); + } + + // scanline + if ((m_vgcint & VGCINT_SCANLINE) && !(data & VGCINT_SCANLINE)) + { + lower_irq(IRQS_SCAN); + m_vgcint &= ~(VGCINT_SCANLINE|VGCINT_ANYVGCINT); + } + + if (m_irqmask & ((1<<IRQS_SECOND) | (1<<IRQS_SCAN))) + { + m_vgcint |= VGCINT_ANYVGCINT; + } + break; + + case 0x33: // CLOCKDATA + m_clkdata = data; + break; + + case 0x34: // CLOCKCTL + m_clock_control = data & 0x7f; + m_video->m_GSborder = data & 0xf; + + if (data & 0x80) + { + process_clock(); + } + break; + + case 0x35: // SHADOW + m_shadow = data; + + // handle I/O and language card inhibit bits here + if (m_shadow & SHAD_IOLC) + { + m_bank0_atc->set_bank(0); + m_bank1_atc->set_bank(0); + } + else + { + m_bank0_atc->set_bank(1); + m_bank1_atc->set_bank(1); + } + break; + + case 0x36: // SPEED + m_speed = data; + update_speed(); + + if (m_speed & SPEED_ALLBANKS) + { + logerror("apple2gs: Driver does not support shadowing in all banks\n"); + } + break; + + case 0x38: // SCCBREG + m_scc->cb_w(space, 0, data); + break; + + case 0x39: // SCCAREG + m_scc->ca_w(space, 0, data); + break; + + case 0x3a: // SCCBDATA + m_scc->db_w(space, 0, data); + break; + + case 0x3b: // SCCADATA + m_scc->da_w(space, 0, data); + break; + + case 0x3c: // SOUNDCTL + m_sndglu_ctrl = data & 0x7f; // make sure DOC is never busy + if (!(m_sndglu_ctrl & 0x40)) // clear hi byte of address pointer on DOC access + { + m_sndglu_addr &= 0xff; + } + break; + + case 0x3d: // SOUNDDATA + if (m_sndglu_ctrl & 0x40) // docram access + { + m_docram_ptr[m_sndglu_addr] = data; + } + else + { + m_doc->write(space, m_sndglu_addr, data); + } + + if (m_sndglu_ctrl & 0x20) // auto-increment + { + m_sndglu_addr++; + } + break; + + case 0x3e: // SOUNDADRL + m_sndglu_addr &= 0xff00; + m_sndglu_addr |= data; + break; + + case 0x3f: // SOUNDADRH + m_sndglu_addr &= 0x00ff; + m_sndglu_addr |= data<<8; + break; + + case 0x41: // INTEN + m_inten = data & 0x1f; + if (!(data & 0x10)) + { + lower_irq(IRQS_QTRSEC); + } + if (!(data & 0x08)) + { + lower_irq(IRQS_VBL); + } + printf("%02x to INTEN, now %02x\n", data, m_vgcint); + break; + + case 0x47: // CLRVBLINT + m_intflag &= ~INTFLAG_VBL; + lower_irq(IRQS_VBL); + break; + + case 0x68: // STATEREG + m_altzp = (data & 0x80); + m_page2 = (data & 0x40); + m_ramrd = (data & 0x20); + m_ramwrt = (data & 0x10); + m_lcram = (data & 0x08) ? false : true; + m_lcram2 = (data & 0x04); + m_intcxrom = (data & 0x01); + + // update the aux state + auxbank_update(); + + // update LC state + if (m_lcram) + { + m_lcbank->set_bank(1); + m_lcaux->set_bank(1); + m_lc00->set_bank(1); + m_lc01->set_bank(1); + } + else + { + m_lcbank->set_bank(0); + m_lcaux->set_bank(0); + m_lc00->set_bank(0); + m_lc01->set_bank(0); + } + break; + + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: + do_io(space, offset); // make sure it also side-effect resets the paddles as documented + break; + + case 0x7e: // SETIOUDIS + m_ioudis = true; break; + + case 0x7f: // CLRIOUDIS + m_ioudis = false; break; + + default: + do_io(space, offset); + break; + } +} + +READ8_MEMBER(apple2gs_state::c080_r) +{ + if (!machine().side_effects_disabled()) + { + int slot; + + slow_cycle(); + + offset &= 0x7F; + slot = offset / 0x10; + + if (slot == 0) + { + lc_update(offset & 0xf, false); + } + else + { + if (slot >= 4) + { + if ((offset & 0xf) == 0x9) + { + m_motors_active |= (1 << (slot - 4)); + } + else if ((offset & 0xf) == 8) + { + m_motors_active &= ~(1 << (slot - 4)); + } + + update_speed(); + } + + // slot 3 always has I/O go to the external card + if ((slot != 3) && ((m_slotromsel & (1 << slot)) == 0)) + { + if (slot == 6) + { + return m_iwm->read(offset & 0xf); + } + } + else + { + if (m_slotdevice[slot] != nullptr) + { + return m_slotdevice[slot]->read_c0nx(offset % 0x10); + } + } + } + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(apple2gs_state::c080_w) +{ + int slot; + + slow_cycle(); + + offset &= 0x7F; + slot = offset / 0x10; + + if (slot == 0) + { + lc_update(offset & 0xf, true); + } + else + { + if (slot >= 4) + { + if ((offset & 0xf) == 0x9) + { + m_motors_active |= (1 << (slot - 4)); + } + else if ((offset & 0xf) == 8) + { + m_motors_active &= ~(1 << (slot - 4)); + } + + update_speed(); + } + + // slot 3 always has I/O go to the external card + if ((slot != 3) && ((m_slotromsel & (1 << slot)) == 0)) + { + if (slot == 6) + { + m_iwm->write(offset & 0xf, data); + } + } + else + { + if (m_slotdevice[slot] != nullptr) + { + m_slotdevice[slot]->write_c0nx(offset % 0x10, data); + } + } + } +} + +uint8_t apple2gs_state::read_slot_rom(address_space &space, int slotbias, int offset) +{ + int slotnum = ((offset>>8) & 0xf) + slotbias; + +// printf("read_slot_rom: sl %d offs %x, cnxx_slot %d\n", slotnum, offset, m_cnxx_slot); + + if (m_slotdevice[slotnum] != nullptr) + { +// printf("slotdevice is not null\n"); + if ((m_cnxx_slot == CNXX_UNCLAIMED) && (m_slotdevice[slotnum]->take_c800()) && (!machine().side_effects_disabled())) + { + m_cnxx_slot = slotnum; + update_slotrom_banks(); + } + + return m_slotdevice[slotnum]->read_cnxx(offset&0xff); + } + + return read_floatingbus(); +} + +void apple2gs_state::write_slot_rom(address_space &space, int slotbias, int offset, uint8_t data) +{ + int slotnum = ((offset>>8) & 0xf) + slotbias; + + slow_cycle(); + + if (m_slotdevice[slotnum] != nullptr) + { + if ((m_cnxx_slot == CNXX_UNCLAIMED) && (m_slotdevice[slotnum]->take_c800()) && (!machine().side_effects_disabled())) + { + m_cnxx_slot = slotnum; + update_slotrom_banks(); + } + + m_slotdevice[slotnum]->write_cnxx(offset&0xff, data); + } +} + +uint8_t apple2gs_state::read_int_rom(address_space &space, int slotbias, int offset) +{ + if ((m_cnxx_slot == CNXX_UNCLAIMED) && (!machine().side_effects_disabled())) + { + m_cnxx_slot = CNXX_INTROM; + update_slotrom_banks(); + } + + return m_rom_ptr[slotbias + offset]; +} + +READ8_MEMBER(apple2gs_state::c100_r) +{ + int slot = ((offset>>8) & 0xf) + 1; + + slow_cycle(); + + // SETSLOTCXROM is disabled, so the $C02D SLOT register controls what's in each slot + if (!(m_slotromsel & (1 << slot))) + { + return read_int_rom(space, 0x3c100, offset); + } + + return read_slot_rom(space, 1, offset); +} + +WRITE8_MEMBER(apple2gs_state::c100_w) +{ + int slot = ((offset>>8) & 0xf) + 1; + + slow_cycle(); + + if ((m_slotromsel & (1 << slot))) + { + write_slot_rom(space, 1, offset, data); + } +} + +READ8_MEMBER(apple2gs_state::c100_int_r) { slow_cycle(); return read_int_rom(space, 0x3c100, offset); } +READ8_MEMBER(apple2gs_state::c300_int_r) { slow_cycle(); return read_int_rom(space, 0x3c300, offset); } +READ8_MEMBER(apple2gs_state::c400_int_r) { slow_cycle(); return read_int_rom(space, 0x3c400, offset); } +READ8_MEMBER(apple2gs_state::c300_r) { slow_cycle(); return read_slot_rom(space, 3, offset); } +WRITE8_MEMBER(apple2gs_state::c300_w) { slow_cycle(); write_slot_rom(space, 3, offset, data); } + +READ8_MEMBER(apple2gs_state::c400_r) +{ + int slot = ((offset>>8) & 0xf) + 4; + + slow_cycle(); + + if (!(m_slotromsel & (1 << slot))) + { + return read_int_rom(space, 0x3c400, offset); + } + + return read_slot_rom(space, 4, offset); +} + +WRITE8_MEMBER(apple2gs_state::c400_w) +{ + int slot = ((offset>>8) & 0xf) + 1; + + slow_cycle(); + + if ((m_slotromsel & (1 << slot))) + { + write_slot_rom(space, 4, offset, data); + } +} + +READ8_MEMBER(apple2gs_state::c800_r) +{ + slow_cycle(); + + if ((offset == 0x7ff) && !machine().side_effects_disabled()) + { + m_cnxx_slot = CNXX_UNCLAIMED; + update_slotrom_banks(); + return 0xff; + } + + if ((m_cnxx_slot > 0) && (m_slotdevice[m_cnxx_slot] != nullptr)) + { + return m_slotdevice[m_cnxx_slot]->read_c800(offset&0xfff); + } + + return read_floatingbus(); +} + +READ8_MEMBER(apple2gs_state::c800_int_r) +{ + slow_cycle(); + + if ((offset == 0x7ff) && !machine().side_effects_disabled()) + { + m_cnxx_slot = CNXX_UNCLAIMED; + update_slotrom_banks(); + return m_rom_ptr[offset + 0x3c800]; + } + + if (m_cnxx_slot == CNXX_INTROM) + { + return m_rom_ptr[offset + 0x3c800]; + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(apple2gs_state::c800_w) +{ + slow_cycle(); + + if (offset == 0x7ff) + { + m_cnxx_slot = CNXX_UNCLAIMED; + update_slotrom_banks(); + return; + } + + if ((m_cnxx_slot > 0) && (m_slotdevice[m_cnxx_slot] != nullptr)) + { + m_slotdevice[m_cnxx_slot]->write_c800(offset&0xfff, data); + } +} + +READ8_MEMBER(apple2gs_state::inh_r) +{ + if (m_inh_slot != -1) + { + return m_slotdevice[m_inh_slot]->read_inh_rom(offset + 0xd000); + } + + assert(0); // hitting inh_r with invalid m_inh_slot should not be possible + return read_floatingbus(); +} + +WRITE8_MEMBER(apple2gs_state::inh_w) +{ + if (m_inh_slot != -1) + { + m_slotdevice[m_inh_slot]->write_inh_rom(offset + 0xd000, data); + } +} + +READ8_MEMBER(apple2gs_state::lc_r) +{ + slow_cycle(); + if (m_altzp) + { + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0x1d000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0x1c000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0x1e000]; + } + else + { + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0xd000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0xc000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0xe000]; + } +} + +WRITE8_MEMBER(apple2gs_state::lc_w) +{ + slow_cycle(); + if (!m_lcwriteenable) + { + return; + } + + if (m_altzp) + { + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0x1d000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0x1c000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0x1e000] = data; + } + else + { + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0xd000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0xc000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0xe000] = data; + } +} + +READ8_MEMBER(apple2gs_state::lc_aux_r) +{ + slow_cycle(); + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0x1d000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0x1c000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0x1e000]; +} + +WRITE8_MEMBER(apple2gs_state::lc_aux_w) +{ + slow_cycle(); + if (!m_lcwriteenable) + { + return; + } + + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0x1d000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0x1c000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0x1e000] = data; +} + +READ8_MEMBER(apple2gs_state::lc_00_r) +{ + if (m_altzp) + { + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0x3d000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0x3c000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0x3e000]; + } + else + { + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0x2d000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0x2c000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0x2e000]; + } +} + +WRITE8_MEMBER(apple2gs_state::lc_00_w) +{ + if (!m_lcwriteenable) + { + return; + } + + if (m_altzp) + { + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0x3d000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0x3c000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0x3e000] = data; + } + else + { + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0x2d000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0x2c000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0x2e000] = data; + } +} + +READ8_MEMBER(apple2gs_state::lc_01_r) +{ + if (offset < 0x1000) + { + if (m_lcram2) + { + return m_ram_ptr[(offset & 0xfff) + 0x3d000]; + } + else + { + return m_ram_ptr[(offset & 0xfff) + 0x3c000]; + } + } + + return m_ram_ptr[(offset & 0x1fff) + 0x3e000]; +} + +WRITE8_MEMBER(apple2gs_state::lc_01_w) +{ + if (!m_lcwriteenable) + { + return; + } + + if (offset < 0x1000) + { + if (m_lcram2) + { + m_ram_ptr[(offset & 0xfff) + 0x3d000] = data; + } + else + { + m_ram_ptr[(offset & 0xfff) + 0x3c000] = data; + } + return; + } + + m_ram_ptr[(offset & 0x1fff) + 0x3e000] = data; +} + +// floating bus code from old machine/apple2: needs to be reworked based on real beam position to enable e.g. Bob Bishop's screen splitter +uint8_t apple2gs_state::read_floatingbus() +{ + enum + { + // scanner types + kScannerNone = 0, kScannerApple2, kScannerApple2e, + + // scanner constants + kHBurstClock = 53, // clock when Color Burst starts + kHBurstClocks = 4, // clocks per Color Burst duration + kHClock0State = 0x18, // H[543210] = 011000 + kHClocks = 65, // clocks per horizontal scan (including HBL) + kHPEClock = 40, // clock when HPE (horizontal preset enable) goes low + kHPresetClock = 41, // clock when H state presets + kHSyncClock = 49, // clock when HSync starts + kHSyncClocks = 4, // clocks per HSync duration + kNTSCScanLines = 262, // total scan lines including VBL (NTSC) + kNTSCVSyncLine = 224, // line when VSync starts (NTSC) + kPALScanLines = 312, // total scan lines including VBL (PAL) + kPALVSyncLine = 264, // line when VSync starts (PAL) + kVLine0State = 0x100, // V[543210CBA] = 100000000 + kVPresetLine = 256, // line when V state presets + kVSyncLines = 4, // lines per VSync duration + kClocksPerVSync = kHClocks * kNTSCScanLines // FIX: NTSC only? + }; + + // vars + // + int i, Hires, Mixed, Page2, _80Store, ScanLines, /* VSyncLine, ScanCycles,*/ + h_clock, h_state, h_0, h_1, h_2, h_3, h_4, h_5, + v_line, v_state, v_A, v_B, v_C, v_0, v_1, v_2, v_3, v_4, /* v_5, */ + _hires, addend0, addend1, addend2, sum, address; + + // video scanner data + // + i = m_maincpu->total_cycles() % kClocksPerVSync; // cycles into this VSync + + // machine state switches + // + Hires = (m_video->m_hires && m_video->m_graphics) ? 1 : 0; + Mixed = m_video->m_mix ? 1 : 0; + Page2 = m_page2 ? 1 : 0; + _80Store = m_80store ? 1 : 0; + + // calculate video parameters according to display standard + // + ScanLines = 1 ? kNTSCScanLines : kPALScanLines; // FIX: NTSC only? + // VSyncLine = 1 ? kNTSCVSyncLine : kPALVSyncLine; // FIX: NTSC only? + // ScanCycles = ScanLines * kHClocks; + + // calculate horizontal scanning state + // + h_clock = (i + kHPEClock) % kHClocks; // which horizontal scanning clock + h_state = kHClock0State + h_clock; // H state bits + if (h_clock >= kHPresetClock) // check for horizontal preset + { + h_state -= 1; // correct for state preset (two 0 states) + } + h_0 = (h_state >> 0) & 1; // get horizontal state bits + h_1 = (h_state >> 1) & 1; + h_2 = (h_state >> 2) & 1; + h_3 = (h_state >> 3) & 1; + h_4 = (h_state >> 4) & 1; + h_5 = (h_state >> 5) & 1; + + // calculate vertical scanning state + // + v_line = i / kHClocks; // which vertical scanning line + v_state = kVLine0State + v_line; // V state bits + if ((v_line >= kVPresetLine)) // check for previous vertical state preset + { + v_state -= ScanLines; // compensate for preset + } + v_A = (v_state >> 0) & 1; // get vertical state bits + v_B = (v_state >> 1) & 1; + v_C = (v_state >> 2) & 1; + v_0 = (v_state >> 3) & 1; + v_1 = (v_state >> 4) & 1; + v_2 = (v_state >> 5) & 1; + v_3 = (v_state >> 6) & 1; + v_4 = (v_state >> 7) & 1; + //v_5 = (v_state >> 8) & 1; + // calculate scanning memory address + // + _hires = Hires; + if (Hires && Mixed && (v_4 & v_2)) + { + _hires = 0; // (address is in text memory) + } + + addend0 = 0x68; // 1 1 0 1 + addend1 = (h_5 << 5) | (h_4 << 4) | (h_3 << 3); + addend2 = (v_4 << 6) | (v_3 << 5) | (v_4 << 4) | (v_3 << 3); + sum = (addend0 + addend1 + addend2) & (0x0F << 3); + + address = 0; + address |= h_0 << 0; // a0 + address |= h_1 << 1; // a1 + address |= h_2 << 2; // a2 + address |= sum; // a3 - aa6 + address |= v_0 << 7; // a7 + address |= v_1 << 8; // a8 + address |= v_2 << 9; // a9 + address |= ((_hires) ? v_A : (1 ^ (Page2 & (1 ^ _80Store)))) << 10; // a10 + address |= ((_hires) ? v_B : (Page2 & (1 ^ _80Store))) << 11; // a11 + if (_hires) // hires? + { + // Y: insert hires only address bits + // + address |= v_C << 12; // a12 + address |= (1 ^ (Page2 & (1 ^ _80Store))) << 13; // a13 + address |= (Page2 & (1 ^ _80Store)) << 14; // a14 + } + else + { + // N: text, so no higher address bits unless Apple ][, not Apple //e + // + if ((1) && // Apple ][? // FIX: check for Apple ][? (FB is most useful in old games) + (kHPEClock <= h_clock) && // Y: HBL? + (h_clock <= (kHClocks - 1))) + { + address |= 1 << 12; // Y: a12 (add $1000 to address!) + } + } + + return m_ram_ptr[address % m_ram_size]; // FIX: this seems to work, but is it right!? +} + +/*************************************************************************** + ADDRESS MAP +***************************************************************************/ + +READ8_MEMBER(apple2gs_state::ram0000_r) { slow_cycle(); return m_ram_ptr[offset]; } +WRITE8_MEMBER(apple2gs_state::ram0000_w) { slow_cycle(); m_ram_ptr[offset] = data; } +READ8_MEMBER(apple2gs_state::ram0200_r) { slow_cycle(); return m_ram_ptr[offset+0x200]; } +WRITE8_MEMBER(apple2gs_state::ram0200_w) { slow_cycle(); m_ram_ptr[offset+0x200] = data; } +READ8_MEMBER(apple2gs_state::ram0400_r) { slow_cycle(); return m_ram_ptr[offset+0x400]; } +WRITE8_MEMBER(apple2gs_state::ram0400_w) { slow_cycle(); m_ram_ptr[offset+0x400] = data; } +READ8_MEMBER(apple2gs_state::ram0800_r) { slow_cycle(); return m_ram_ptr[offset+0x800]; } +WRITE8_MEMBER(apple2gs_state::ram0800_w) { slow_cycle(); m_ram_ptr[offset+0x800] = data; } +READ8_MEMBER(apple2gs_state::ram2000_r) { slow_cycle(); return m_ram_ptr[offset+0x2000]; } +WRITE8_MEMBER(apple2gs_state::ram2000_w) { slow_cycle(); m_ram_ptr[offset+0x2000] = data; } +READ8_MEMBER(apple2gs_state::ram4000_r) { slow_cycle(); return m_ram_ptr[offset+0x4000]; } +WRITE8_MEMBER(apple2gs_state::ram4000_w) { slow_cycle(); m_ram_ptr[offset+0x4000] = data; } + +READ8_MEMBER(apple2gs_state::auxram0000_r) { slow_cycle(); return m_ram_ptr[offset+0x10000]; } +WRITE8_MEMBER(apple2gs_state::auxram0000_w) { slow_cycle(); m_ram_ptr[offset+0x10000] = data; } +READ8_MEMBER(apple2gs_state::auxram0200_r) { slow_cycle(); return m_ram_ptr[offset+0x10200]; } +WRITE8_MEMBER(apple2gs_state::auxram0200_w) { slow_cycle(); m_ram_ptr[offset+0x10200] = data; } +READ8_MEMBER(apple2gs_state::auxram0400_r) { slow_cycle(); return m_ram_ptr[offset+0x10400]; } +WRITE8_MEMBER(apple2gs_state::auxram0400_w) { slow_cycle(); m_ram_ptr[offset+0x10400] = data; } +READ8_MEMBER(apple2gs_state::auxram0800_r) { slow_cycle(); return m_ram_ptr[offset+0x10800]; } +WRITE8_MEMBER(apple2gs_state::auxram0800_w) { slow_cycle(); m_ram_ptr[offset+0x10800] = data; } +READ8_MEMBER(apple2gs_state::auxram2000_r) { slow_cycle(); return m_ram_ptr[offset+0x12000]; } +WRITE8_MEMBER(apple2gs_state::auxram2000_w) { slow_cycle(); m_ram_ptr[offset+0x12000] = data; } +READ8_MEMBER(apple2gs_state::auxram4000_r) { slow_cycle(); return m_ram_ptr[offset+0x14000]; } +WRITE8_MEMBER(apple2gs_state::auxram4000_w) +{ + m_ram_ptr[offset+0x14000] = data; + + slow_cycle(); + + if ((offset >= (0x9e00-0x4000)) && (offset <= (0x9fff-0x4000))) + { + int color = (offset - (0x9e00-0x4000)) >> 1; + + m_video->m_shr_palette[color] = rgb_t( + ((m_ram_ptr[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17, + ((m_ram_ptr[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17, + ((m_ram_ptr[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17); + } + +} + +READ8_MEMBER( apple2gs_state::b0ram0000_r) { return m_ram_ptr[offset+0x20000]; } +WRITE8_MEMBER(apple2gs_state::b0ram0000_w) { m_ram_ptr[offset+0x20000] = data; } +READ8_MEMBER( apple2gs_state::b0ram0200_r) { return m_ram_ptr[offset+0x20200]; } +WRITE8_MEMBER(apple2gs_state::b0ram0200_w) { m_ram_ptr[offset+0x20200] = data; } +READ8_MEMBER( apple2gs_state::b0ram0400_r) { return m_ram_ptr[offset+0x20400]; } +WRITE8_MEMBER(apple2gs_state::b0ram0400_w) +{ + m_ram_ptr[offset+0x20400] = data; + if (!(m_shadow & SHAD_TXTPG1)) + { + m_maincpu_space->write_byte(offset + 0xe00400, data); + } +} +READ8_MEMBER( apple2gs_state::b0ram0800_r) { return m_ram_ptr[offset+0x20800]; } +WRITE8_MEMBER(apple2gs_state::b0ram0800_w) +{ + m_ram_ptr[offset+0x20800] = data; + + if (offset < 0x400) // TODO: ROM 03 + { + if (!(m_shadow & SHAD_TXTPG2)) m_maincpu_space->write_byte(offset + 0xe00800, data); + } +} +READ8_MEMBER( apple2gs_state::b0ram2000_r) { return m_ram_ptr[offset+0x22000]; } +WRITE8_MEMBER(apple2gs_state::b0ram2000_w) +{ + m_ram_ptr[offset+0x22000] = data; + if (!(m_shadow & SHAD_HIRESPG1)) m_maincpu_space->write_byte(offset + 0xe02000, data); +} +READ8_MEMBER( apple2gs_state::b0ram4000_r) { return m_ram_ptr[offset+0x24000]; } +WRITE8_MEMBER(apple2gs_state::b0ram4000_w) +{ + m_ram_ptr[offset+0x24000] = data; + if (offset < 0x2000) + { + if (!(m_shadow & SHAD_HIRESPG2)) m_maincpu_space->write_byte(offset + 0xe04000, data); + } +} + +READ8_MEMBER( apple2gs_state::b1ram0000_r) { return m_ram_ptr[offset+0x30000]; } +WRITE8_MEMBER(apple2gs_state::b1ram0000_w) { m_ram_ptr[offset+0x30000] = data; } +READ8_MEMBER( apple2gs_state::b1ram0200_r) { return m_ram_ptr[offset+0x30200]; } +WRITE8_MEMBER(apple2gs_state::b1ram0200_w) { m_ram_ptr[offset+0x30200] = data; } +READ8_MEMBER( apple2gs_state::b1ram0400_r) { return m_ram_ptr[offset+0x30400]; } +WRITE8_MEMBER(apple2gs_state::b1ram0400_w) +{ + m_ram_ptr[offset+0x30400] = data; + if (!(m_shadow & SHAD_TXTPG1)) m_maincpu_space->write_byte(offset + 0xe10400, data); +} +READ8_MEMBER( apple2gs_state::b1ram0800_r) { return m_ram_ptr[offset+0x30800]; } +WRITE8_MEMBER(apple2gs_state::b1ram0800_w) +{ + m_ram_ptr[offset+0x30800] = data; + if (offset < 0x400) + { + if (!(m_shadow & SHAD_TXTPG2)) m_maincpu_space->write_byte(offset + 0xe10800, data); + } +} +READ8_MEMBER( apple2gs_state::b1ram2000_r) { return m_ram_ptr[offset+0x32000]; } +WRITE8_MEMBER(apple2gs_state::b1ram2000_w) +{ + m_ram_ptr[offset+0x32000] = data; + if (!(m_shadow & SHAD_HIRESPG1) && !(m_shadow & SHAD_AUXHIRES)) m_maincpu_space->write_byte(offset + 0xe12000, data); + else if (!(m_shadow & SHAD_SUPERHIRES)) m_maincpu_space->write_byte(offset + 0xe12000, data); +} +READ8_MEMBER( apple2gs_state::b1ram4000_r) { return m_ram_ptr[offset+0x34000]; } +WRITE8_MEMBER(apple2gs_state::b1ram4000_w) +{ + m_ram_ptr[offset+0x34000] = data; + if (offset < 0x2000) + { + if (!(m_shadow & SHAD_HIRESPG2) && !(m_shadow & SHAD_AUXHIRES)) m_maincpu_space->write_byte(offset + 0xe14000, data); + } + + if (offset < 0x6000) + { + if (!(m_shadow & SHAD_SUPERHIRES)) m_maincpu_space->write_byte(offset + 0xe14000, data); + } +} + +READ8_MEMBER(apple2gs_state::bank0_0000_r) +{ + if ((offset < 0x200) && (m_altzp)) + { + return m_ram_ptr[offset + 0x30000]; + } + else if ((offset < 0x400) && (m_ramrd)) + { + return m_ram_ptr[offset + 0x30000]; + } + else if (offset < 0x800) + { + if (m_80store) + { + if (m_page2) + { + return m_ram_ptr[offset + 0x30000]; + } + } + else if (m_ramrd) + { + return m_ram_ptr[offset + 0x30000]; + } + } + else if ((offset < 0x2000) && (m_ramrd)) + { + return m_ram_ptr[offset + 0x30000]; + } + else if (offset < 0x4000) + { + if ((m_80store) && (m_video->m_hires)) + { + if (m_page2) + { + return m_ram_ptr[offset + 0x30000]; + } + } + else if (m_ramrd) + { + return m_ram_ptr[offset + 0x30000]; + } + } + else if (m_ramrd) + { + return m_ram_ptr[offset + 0x30000]; + } + + return m_ram_ptr[offset + 0x20000]; +} + +WRITE8_MEMBER(apple2gs_state::bank0_0000_w) +{ + if ((offset < 0x200) && (m_altzp)) + { + bank1_0000_w(space, offset, data); + return; + } + else if ((offset < 0x400) && (m_ramwrt)) + { + bank1_0000_w(space, offset, data); + return; + } + else if (offset < 0x800) + { + if (m_80store) + { + if (m_page2) + { + bank1_0000_w(space, offset, data); + return; + } + } + else if (m_ramwrt) + { + bank1_0000_w(space, offset, data); + return; + } + } + else if ((offset < 0x2000) && (m_ramwrt)) + { + bank1_0000_w(space, offset, data); + } + else if (offset < 0x4000) + { + if ((m_80store) && (m_video->m_hires)) + { + if (m_page2) + { + bank1_0000_w(space, offset, data); + return; + } + } + else if (m_ramwrt) + { + bank1_0000_w(space, offset, data); + return; + } + + } + else if (m_ramwrt) + { + bank1_0000_w(space, offset, data); + return; + } + + m_ram_ptr[offset + 0x20000] = data; +} + +READ8_MEMBER(apple2gs_state::bank0_c000_r) { return m_ram_ptr[offset + 0x2c000]; } +WRITE8_MEMBER(apple2gs_state::bank0_c000_w) { m_ram_ptr[offset + 0x2c000] = data; } +#if 0 +WRITE8_MEMBER(apple2gs_state::bank0_0000_sh_w) +{ + m_ram_ptr[offset + 0x20000] = data; + + switch (offset>>8) + { + case 0x04: // text page 1 + case 0x05: + case 0x06: + case 0x07: + if (!(m_shadow & SHAD_TXTPG1)) m_maincpu_space->write_byte(offset + 0xe00000, data); + break; + + case 0x08: // text page 2 (only shadowable on ROM 03) + case 0x09: + case 0x0a: + case 0x0b: + if (!(m_shadow & SHAD_TXTPG2)) m_maincpu_space->write_byte(offset + 0xe00000, data); + break; + + // hi-res page 1 + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: + if (!(m_shadow & SHAD_HIRESPG1)) m_maincpu_space->write_byte(offset + 0xe00000, data); + break; + + // hi-res page 2 + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: + if (!(m_shadow & SHAD_HIRESPG2)) m_maincpu_space->write_byte(offset + 0xe00000, data); + break; + + default: + break; + } +} +#endif + +READ8_MEMBER(apple2gs_state::bank1_0000_r) { return m_ram_ptr[offset + 0x30000]; } +WRITE8_MEMBER(apple2gs_state::bank1_0000_w) { m_ram_ptr[offset + 0x30000] = data; } +READ8_MEMBER(apple2gs_state::bank1_c000_r) { return m_ram_ptr[offset + 0x3c000]; } +WRITE8_MEMBER(apple2gs_state::bank1_c000_w) { m_ram_ptr[offset + 0x3c000] = data; } +WRITE8_MEMBER(apple2gs_state::bank1_0000_sh_w) +{ + m_ram_ptr[offset + 0x30000] = data; + + switch (offset>>8) + { + case 0x04: // text page 1 + case 0x05: + case 0x06: + case 0x07: + if (!(m_shadow & SHAD_TXTPG1)) m_maincpu_space->write_byte(offset + 0xe10000, data); + break; + + case 0x08: // text page 2 (only shadowable on ROM 03) + case 0x09: + case 0x0a: + case 0x0b: + if (!(m_shadow & SHAD_TXTPG2)) m_maincpu_space->write_byte(offset + 0xe10000, data); + break; + + // hi-res page 1 + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: + if (!(m_shadow & SHAD_HIRESPG1) && !(m_shadow & SHAD_AUXHIRES)) m_maincpu_space->write_byte(offset + 0xe10000, data); + else if (!(m_shadow & SHAD_SUPERHIRES)) m_maincpu_space->write_byte(offset + 0xe10000, data); + break; + + // hi-res page 2 + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: + if (!(m_shadow & SHAD_HIRESPG2) && !(m_shadow & SHAD_AUXHIRES)) m_maincpu_space->write_byte(offset + 0xe10000, data); + else if (!(m_shadow & SHAD_SUPERHIRES)) m_maincpu_space->write_byte(offset + 0xe10000, data); + break; + + default: + if ((offset >= 0x6000) && (offset <= 0x9fff)) + { + if (!(m_shadow & SHAD_SUPERHIRES)) m_maincpu_space->write_byte(offset + 0xe10000, data); + } + break; + } +} void apple2gs_state::apple2gs_map(address_map &map) { - /* nothing in the address map - everything is added dynamically */ + /* "fast side" - runs 2.8 MHz minus RAM refresh, banks 00 and 01 usually have writes shadowed to E0/E1 where I/O lives */ + /* Banks 00 and 01 also have their own independent language cards if shadowing is disabled */ + map(0x000000, 0x0001ff).m(m_b0_0000bank, FUNC(address_map_bank_device::amap8)); + map(0x000200, 0x0003ff).m(m_b0_0200bank, FUNC(address_map_bank_device::amap8)); + map(0x000400, 0x0007ff).m(m_b0_0400bank, FUNC(address_map_bank_device::amap8)); + map(0x000800, 0x001fff).m(m_b0_0800bank, FUNC(address_map_bank_device::amap8)); + map(0x002000, 0x003fff).m(m_b0_2000bank, FUNC(address_map_bank_device::amap8)); + map(0x004000, 0x00bfff).m(m_b0_4000bank, FUNC(address_map_bank_device::amap8)); + map(0x00c000, 0x00ffff).m(m_bank0_atc, FUNC(address_map_bank_device::amap8)); + map(0x010000, 0x01bfff).m(m_bank1_at0, FUNC(address_map_bank_device::amap8)); + map(0x01c000, 0x01ffff).m(m_bank1_atc, FUNC(address_map_bank_device::amap8)); + + /* "Mega II side" - this is basically a 128K IIe on a chip that runs merrily at 1 MHz */ + /* Unfortunately all I/O happens here, including new IIgs-specific stuff */ + map(0xe00000, 0xe001ff).m(m_0000bank, FUNC(address_map_bank_device::amap8)); + map(0xe00200, 0xe003ff).m(m_0200bank, FUNC(address_map_bank_device::amap8)); + map(0xe00400, 0xe007ff).m(m_0400bank, FUNC(address_map_bank_device::amap8)); + map(0xe00800, 0xe01fff).m(m_0800bank, FUNC(address_map_bank_device::amap8)); + map(0xe02000, 0xe03fff).m(m_2000bank, FUNC(address_map_bank_device::amap8)); + map(0xe04000, 0xe0bfff).m(m_4000bank, FUNC(address_map_bank_device::amap8)); + map(0xe0c000, 0xe0c07f).rw(FUNC(apple2gs_state::c000_r), FUNC(apple2gs_state::c000_w)); + map(0xe0c080, 0xe0c0ff).rw(FUNC(apple2gs_state::c080_r), FUNC(apple2gs_state::c080_w)); + map(0xe0c100, 0xe0c2ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); + map(0xe0c300, 0xe0c3ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); + map(0xe0c400, 0xe0c7ff).m(m_c400bank, FUNC(address_map_bank_device::amap8)); + map(0xe0c800, 0xe0cfff).m(m_c800bank, FUNC(address_map_bank_device::amap8)); + map(0xe0d000, 0xe0ffff).m(A2GS_UPPERBANK_TAG, FUNC(address_map_bank_device::amap8)); + + map(0xe10000, 0xe101ff).rw(FUNC(apple2gs_state::auxram0000_r), FUNC(apple2gs_state::auxram0000_w)); + map(0xe10200, 0xe103ff).rw(FUNC(apple2gs_state::auxram0200_r), FUNC(apple2gs_state::auxram0200_w)); + map(0xe10400, 0xe107ff).rw(FUNC(apple2gs_state::auxram0400_r), FUNC(apple2gs_state::auxram0400_w)); + map(0xe10800, 0xe11fff).rw(FUNC(apple2gs_state::auxram0800_r), FUNC(apple2gs_state::auxram0800_w)); + map(0xe12000, 0xe13fff).rw(FUNC(apple2gs_state::auxram2000_r), FUNC(apple2gs_state::auxram2000_w)); + map(0xe14000, 0xe1bfff).rw(FUNC(apple2gs_state::auxram4000_r), FUNC(apple2gs_state::auxram4000_w)); + map(0xe1c000, 0xe1c07f).rw(FUNC(apple2gs_state::c000_r), FUNC(apple2gs_state::c000_w)); + map(0xe1c080, 0xe1c0ff).rw(FUNC(apple2gs_state::c080_r), FUNC(apple2gs_state::c080_w)); + map(0xe1c100, 0xe1c2ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); + map(0xe1c300, 0xe1c3ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); + map(0xe1c400, 0xe1c7ff).m(m_c400bank, FUNC(address_map_bank_device::amap8)); + map(0xe1c800, 0xe1cfff).m(m_c800bank, FUNC(address_map_bank_device::amap8)); + map(0xe1d000, 0xe1ffff).m(m_upperaux, FUNC(address_map_bank_device::amap8)); + + map(0xfc0000, 0xffffff).rom().region("maincpu", 0x00000); } void apple2gs_state::vectors_map(address_map &map) @@ -191,12 +3647,207 @@ void apple2gs_state::vectors_map(address_map &map) map(0x00, 0x1f).r(FUNC(apple2gs_state::apple2gs_read_vector)); } -// ADB microcontroller emulation -// -// Huge thanks to Neil Parker's writeup on the ADB microcontroller! -// http://www.llx.com/~nparker/a2/adb.html +void apple2gs_state::r0000bank_map(address_map &map) +{ + map(0x0000, 0x01ff).rw(FUNC(apple2gs_state::ram0000_r), FUNC(apple2gs_state::ram0000_w)); + map(0x0200, 0x03ff).rw(FUNC(apple2gs_state::auxram0000_r), FUNC(apple2gs_state::auxram0000_w)); +} + +void apple2gs_state::r0200bank_map(address_map &map) +{ + map(0x0000, 0x01ff).rw(FUNC(apple2gs_state::ram0200_r), FUNC(apple2gs_state::ram0200_w)); // wr 0 rd 0 + map(0x0200, 0x03ff).rw(FUNC(apple2gs_state::auxram0200_r), FUNC(apple2gs_state::ram0200_w)); // wr 0 rd 1 + map(0x0400, 0x05ff).rw(FUNC(apple2gs_state::ram0200_r), FUNC(apple2gs_state::auxram0200_w)); // wr 1 rd 0 + map(0x0600, 0x07ff).rw(FUNC(apple2gs_state::auxram0200_r), FUNC(apple2gs_state::auxram0200_w)); // wr 1 rd 1 +} + +void apple2gs_state::r0400bank_map(address_map &map) +{ + map(0x0000, 0x03ff).rw(FUNC(apple2gs_state::ram0400_r), FUNC(apple2gs_state::ram0400_w)); // wr 0 rd 0 + map(0x0400, 0x07ff).rw(FUNC(apple2gs_state::auxram0400_r), FUNC(apple2gs_state::ram0400_w)); // wr 0 rd 1 + map(0x0800, 0x0bff).rw(FUNC(apple2gs_state::ram0400_r), FUNC(apple2gs_state::auxram0400_w)); // wr 1 rd 0 + map(0x0c00, 0x0fff).rw(FUNC(apple2gs_state::auxram0400_r), FUNC(apple2gs_state::auxram0400_w)); // wr 1 rd 1 +} + +void apple2gs_state::r0800bank_map(address_map &map) +{ + map(0x0000, 0x17ff).rw(FUNC(apple2gs_state::ram0800_r), FUNC(apple2gs_state::ram0800_w)); + map(0x2000, 0x37ff).rw(FUNC(apple2gs_state::auxram0800_r), FUNC(apple2gs_state::ram0800_w)); + map(0x4000, 0x57ff).rw(FUNC(apple2gs_state::ram0800_r), FUNC(apple2gs_state::auxram0800_w)); + map(0x6000, 0x77ff).rw(FUNC(apple2gs_state::auxram0800_r), FUNC(apple2gs_state::auxram0800_w)); +} + +void apple2gs_state::r2000bank_map(address_map &map) +{ + map(0x0000, 0x1fff).rw(FUNC(apple2gs_state::ram2000_r), FUNC(apple2gs_state::ram2000_w)); + map(0x2000, 0x3fff).rw(FUNC(apple2gs_state::auxram2000_r), FUNC(apple2gs_state::ram2000_w)); + map(0x4000, 0x5fff).rw(FUNC(apple2gs_state::ram2000_r), FUNC(apple2gs_state::auxram2000_w)); + map(0x6000, 0x7fff).rw(FUNC(apple2gs_state::auxram2000_r), FUNC(apple2gs_state::auxram2000_w)); +} + +void apple2gs_state::r4000bank_map(address_map &map) +{ + map(0x00000, 0x07fff).rw(FUNC(apple2gs_state::ram4000_r), FUNC(apple2gs_state::ram4000_w)); + map(0x08000, 0x0ffff).rw(FUNC(apple2gs_state::auxram4000_r), FUNC(apple2gs_state::ram4000_w)); + map(0x10000, 0x17fff).rw(FUNC(apple2gs_state::ram4000_r), FUNC(apple2gs_state::auxram4000_w)); + map(0x18000, 0x1ffff).rw(FUNC(apple2gs_state::auxram4000_r), FUNC(apple2gs_state::auxram4000_w)); +} + +void apple2gs_state::c100bank_map(address_map &map) +{ + map(0x0000, 0x01ff).rw(FUNC(apple2gs_state::c100_r), FUNC(apple2gs_state::c100_w)); + map(0x0200, 0x03ff).r(FUNC(apple2gs_state::c100_int_r)).nopw(); +} + +void apple2gs_state::c300bank_map(address_map &map) +{ + map(0x0000, 0x00ff).rw(FUNC(apple2gs_state::c300_r), FUNC(apple2gs_state::c300_w)); + map(0x0100, 0x01ff).r(FUNC(apple2gs_state::c300_int_r)).nopw(); +} + +void apple2gs_state::c400bank_map(address_map &map) +{ + map(0x0000, 0x03ff).rw(FUNC(apple2gs_state::c400_r), FUNC(apple2gs_state::c400_w)); + map(0x0400, 0x07ff).rw(FUNC(apple2gs_state::c400_int_r), FUNC(apple2gs_state::c400_w)); +} + +void apple2gs_state::c800bank_map(address_map &map) +{ + map(0x0000, 0x07ff).rw(FUNC(apple2gs_state::c800_r), FUNC(apple2gs_state::c800_w)); + map(0x0800, 0x0fff).rw(FUNC(apple2gs_state::c800_int_r), FUNC(apple2gs_state::c800_w)); +} + +void apple2gs_state::inhbank_map(address_map &map) +{ + map(0x0000, 0x2fff).m(m_lcbank, FUNC(address_map_bank_device::amap8)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::inh_r), FUNC(apple2gs_state::inh_w)); +} + +void apple2gs_state::inhaux_map(address_map &map) +{ + map(0x0000, 0x2fff).m(m_lcaux, FUNC(address_map_bank_device::amap8)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::inh_r), FUNC(apple2gs_state::inh_w)); +} + +void apple2gs_state::inh00_map(address_map &map) +{ + map(0x0000, 0x2fff).m(m_lc00, FUNC(address_map_bank_device::amap8)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::inh_r), FUNC(apple2gs_state::inh_w)); +} + +void apple2gs_state::inh01_map(address_map &map) +{ + map(0x0000, 0x2fff).m(m_lc01, FUNC(address_map_bank_device::amap8)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::inh_r), FUNC(apple2gs_state::inh_w)); +} + +void apple2gs_state::lcbank_map(address_map &map) +{ + map(0x0000, 0x2fff).rom().region("maincpu", 0x1000).w(FUNC(apple2gs_state::lc_w)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::lc_r), FUNC(apple2gs_state::lc_w)); +} + +void apple2gs_state::lcaux_map(address_map &map) +{ + map(0x0000, 0x2fff).rom().region("maincpu", 0x3d000).w(FUNC(apple2gs_state::lc_aux_w)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::lc_aux_r), FUNC(apple2gs_state::lc_aux_w)); +} + +void apple2gs_state::lc00_map(address_map &map) +{ + map(0x0000, 0x2fff).rom().region("maincpu", 0x3d000).w(FUNC(apple2gs_state::lc_00_w)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::lc_00_r), FUNC(apple2gs_state::lc_00_w)); +} + +void apple2gs_state::lc01_map(address_map &map) +{ + map(0x0000, 0x2fff).rom().region("maincpu", 0x3d000).w(FUNC(apple2gs_state::lc_01_w)); + map(0x3000, 0x5fff).rw(FUNC(apple2gs_state::lc_01_r), FUNC(apple2gs_state::lc_01_w)); +} + +void apple2gs_state::bank0_iolc_map(address_map &map) +{ + map(0x0000, 0x3fff).rw(FUNC(apple2gs_state::bank0_c000_r), FUNC(apple2gs_state::bank0_c000_w)); + map(0x4000, 0x407f).rw(FUNC(apple2gs_state::c000_r), FUNC(apple2gs_state::c000_w)); + map(0x4080, 0x40ff).rw(FUNC(apple2gs_state::c080_r), FUNC(apple2gs_state::c080_w)); + map(0x4100, 0x42ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); + map(0x4300, 0x43ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); + map(0x4400, 0x47ff).m(m_c400bank, FUNC(address_map_bank_device::amap8)); + map(0x4800, 0x4fff).m(m_c800bank, FUNC(address_map_bank_device::amap8)); + map(0x5000, 0x7fff).m(m_upper00, FUNC(address_map_bank_device::amap8)); +} + +void apple2gs_state::bank1_lower48_map(address_map &map) +{ + map(0x0000, 0x0bfff).rw(FUNC(apple2gs_state::bank1_0000_r), FUNC(apple2gs_state::bank1_0000_w)); + map(0xc000, 0x17fff).rw(FUNC(apple2gs_state::bank1_0000_r), FUNC(apple2gs_state::bank1_0000_sh_w)); +} + +void apple2gs_state::bank1_iolc_map(address_map &map) +{ + map(0x0000, 0x3fff).rw(FUNC(apple2gs_state::bank1_c000_r), FUNC(apple2gs_state::bank1_c000_w)); + map(0x4000, 0x407f).rw(FUNC(apple2gs_state::c000_r), FUNC(apple2gs_state::c000_w)); + map(0x4080, 0x40ff).rw(FUNC(apple2gs_state::c080_r), FUNC(apple2gs_state::c080_w)); + map(0x4100, 0x42ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); + map(0x4300, 0x43ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); + map(0x4400, 0x47ff).m(m_c400bank, FUNC(address_map_bank_device::amap8)); + map(0x4800, 0x4fff).m(m_c800bank, FUNC(address_map_bank_device::amap8)); + map(0x5000, 0x7fff).m(m_upper01, FUNC(address_map_bank_device::amap8)); +} + +void apple2gs_state::rb0000bank_map(address_map &map) +{ + map(0x0000, 0x01ff).rw(FUNC(apple2gs_state::b0ram0000_r), FUNC(apple2gs_state::b0ram0000_w)); + map(0x0200, 0x03ff).rw(FUNC(apple2gs_state::b1ram0000_r), FUNC(apple2gs_state::b1ram0000_w)); +} + +void apple2gs_state::rb0200bank_map(address_map &map) +{ + map(0x0000, 0x01ff).rw(FUNC(apple2gs_state::b0ram0200_r), FUNC(apple2gs_state::b0ram0200_w)); // wr 0 rd 0 + map(0x0200, 0x03ff).rw(FUNC(apple2gs_state::b1ram0200_r), FUNC(apple2gs_state::b0ram0200_w)); // wr 0 rd 1 + map(0x0400, 0x05ff).rw(FUNC(apple2gs_state::b0ram0200_r), FUNC(apple2gs_state::b1ram0200_w)); // wr 1 rd 0 + map(0x0600, 0x07ff).rw(FUNC(apple2gs_state::b1ram0200_r), FUNC(apple2gs_state::b1ram0200_w)); // wr 1 rd 1 +} + +void apple2gs_state::rb0400bank_map(address_map &map) +{ + map(0x0000, 0x03ff).rw(FUNC(apple2gs_state::b0ram0400_r), FUNC(apple2gs_state::b0ram0400_w)); // wr 0 rd 0 + map(0x0400, 0x07ff).rw(FUNC(apple2gs_state::b1ram0400_r), FUNC(apple2gs_state::b0ram0400_w)); // wr 0 rd 1 + map(0x0800, 0x0bff).rw(FUNC(apple2gs_state::b0ram0400_r), FUNC(apple2gs_state::b1ram0400_w)); // wr 1 rd 0 + map(0x0c00, 0x0fff).rw(FUNC(apple2gs_state::b1ram0400_r), FUNC(apple2gs_state::b1ram0400_w)); // wr 1 rd 1 +} + +void apple2gs_state::rb0800bank_map(address_map &map) +{ + map(0x0000, 0x17ff).rw(FUNC(apple2gs_state::b0ram0800_r), FUNC(apple2gs_state::b0ram0800_w)); + map(0x2000, 0x37ff).rw(FUNC(apple2gs_state::b1ram0800_r), FUNC(apple2gs_state::b0ram0800_w)); + map(0x4000, 0x57ff).rw(FUNC(apple2gs_state::b0ram0800_r), FUNC(apple2gs_state::b1ram0800_w)); + map(0x6000, 0x77ff).rw(FUNC(apple2gs_state::b1ram0800_r), FUNC(apple2gs_state::b1ram0800_w)); +} + +void apple2gs_state::rb2000bank_map(address_map &map) +{ + map(0x0000, 0x1fff).rw(FUNC(apple2gs_state::b0ram2000_r), FUNC(apple2gs_state::b0ram2000_w)); + map(0x2000, 0x3fff).rw(FUNC(apple2gs_state::b1ram2000_r), FUNC(apple2gs_state::b0ram2000_w)); + map(0x4000, 0x5fff).rw(FUNC(apple2gs_state::b0ram2000_r), FUNC(apple2gs_state::b1ram2000_w)); + map(0x6000, 0x7fff).rw(FUNC(apple2gs_state::b1ram2000_r), FUNC(apple2gs_state::b1ram2000_w)); +} + +void apple2gs_state::rb4000bank_map(address_map &map) +{ + map(0x00000, 0x07fff).rw(FUNC(apple2gs_state::b0ram4000_r), FUNC(apple2gs_state::b0ram4000_w)); + map(0x08000, 0x0ffff).rw(FUNC(apple2gs_state::b1ram4000_r), FUNC(apple2gs_state::b0ram4000_w)); + map(0x10000, 0x17fff).rw(FUNC(apple2gs_state::b0ram4000_r), FUNC(apple2gs_state::b1ram4000_w)); + map(0x18000, 0x1ffff).rw(FUNC(apple2gs_state::b1ram4000_r), FUNC(apple2gs_state::b1ram4000_w)); +} + +/*************************************************************************** + ADB microcontroller + KEYGLU emulation + + Huge thanks to Neil Parker's writeup on the ADB microcontroller! + http://www.llx.com/~nparker/a2/adb.html +***************************************************************************/ -#if RUN_ADB_MICRO READ8_MEMBER(apple2gs_state::adbmicro_p0_in) { return m_glu_bus; @@ -204,11 +3855,31 @@ READ8_MEMBER(apple2gs_state::adbmicro_p0_in) READ8_MEMBER(apple2gs_state::adbmicro_p1_in) { - if (m_is_rom3) +#if RUN_ADB_MICRO + switch (m_glu_kbd_y) { - return 0x06; // indicate ROM 3 + case 0: + return m_ky0->read(); + case 1: + return m_ky1->read(); + case 2: + return m_ky2->read(); + case 3: + return m_ky3->read(); + case 4: + return m_ky4->read(); + case 5: + return m_ky5->read(); + case 6: + return m_ky6->read(); + case 7: + return m_ky7->read(); + case 8: + return m_ky8->read(); + case 9: + return m_ky9->read(); } - +#endif return 0xff; } @@ -224,7 +3895,19 @@ READ8_MEMBER(apple2gs_state::adbmicro_p2_in) READ8_MEMBER(apple2gs_state::adbmicro_p3_in) { - return 0x7; // don't press IIE capslock/ctrl/shift + uint8_t rv = 0; +#if RUN_ADB_MICRO + uint8_t special = m_kbspecial->read(); + + rv |= (special & 0x06) ? 0x00 : 0x01; + rv |= (special & 0x08) ? 0x00 : 0x02; + rv |= (special & 0x01) ? 0x00 : 0x04; + rv |= (special & 0x10) ? 0x00 : 0x80; + rv |= (special & 0x20) ? 0x00 : 0x40; +#else + rv = 0xc7; +#endif + return rv; } WRITE8_MEMBER(apple2gs_state::adbmicro_p0_out) @@ -240,14 +3923,18 @@ WRITE8_MEMBER(apple2gs_state::adbmicro_p2_out) { if (!(data & 0x10)) { - if (m_adbmicro->are_port_bits_output(0, 0xff)) - { - keyglu_mcu_write(data & 7, m_glu_bus); - } - else // read GLU - { - m_glu_bus = keyglu_mcu_read(data & 7); - } + if (m_adbmicro->are_port_bits_output(0, 0xff)) + { + keyglu_mcu_write(data & 7, m_glu_bus); + } + else // read GLU + { + m_glu_bus = keyglu_mcu_read(data & 7); + } + } + else + { + m_glu_kbd_y = data & 0xf; } } @@ -255,40 +3942,692 @@ WRITE8_MEMBER(apple2gs_state::adbmicro_p3_out) { if (((data & 0x08) == 0x08) != m_adb_line) { - m_adb_dtime = (int)(machine().time().as_ticks(XTAL(3'579'545)*2) - m_last_adb_time); -// printf("ADB change to %d (dtime %d)\n", (data>>3) & 1, m_adb_dtime); - m_last_adb_time = machine().time().as_ticks(XTAL(3'579'545)*2); +// m_adb_dtime = (int)(machine().time().as_ticks(XTAL(3'579'545)*2) - m_last_adb_time); +// printf("ADB change to %d (dtime %d)\n", (data>>3) & 1, m_adb_dtime); +// m_last_adb_time = machine().time().as_ticks(XTAL(3'579'545)*2); m_adb_line = (data & 0x8) ? true : false; } } + +uint8_t apple2gs_state::keyglu_mcu_read(uint8_t offset) +{ + uint8_t rv = m_glu_regs[offset]; + +// printf("MCU reads reg %x\n", offset); + + // the command full flag is cleared by the MCU reading + // first the KGS register and then the command register + if ((offset == GLU_COMMAND) && (m_glu_mcu_read_kgs)) + { + m_glu_regs[GLU_KG_STATUS] &= ~KGS_COMMAND_FULL; + m_glu_mcu_read_kgs = false; +// printf("MCU reads COMMAND = %02x (drop command full)\n", rv); + } + + // prime for the next command register read to clear the command full flag + if (offset == GLU_KG_STATUS) + { + m_glu_mcu_read_kgs = true; + } + + return rv; +} + +void apple2gs_state::keyglu_mcu_write(uint8_t offset, uint8_t data) +{ + m_glu_regs[offset] = data; + +// printf("MCU writes %02x to reg %x\n", data, offset); + + switch (offset) + { + case GLU_KEY_DATA: + m_glu_regs[GLU_SYSSTAT] |= GLU_STATUS_KEYDATIRQ; + if (m_glu_regs[GLU_SYSSTAT] & GLU_STATUS_KEYDATIRQEN) + { + raise_irq(IRQS_ADB); + } + break; + + case GLU_MOUSEX: + case GLU_MOUSEY: + m_glu_regs[GLU_KG_STATUS] |= KGS_MOUSEX_FULL; + m_glu_regs[GLU_SYSSTAT] |= GLU_STATUS_MOUSEIRQ; + if (m_glu_regs[GLU_SYSSTAT] & GLU_STATUS_MOUSEIRQEN) + { + raise_irq(IRQS_ADB); + } + m_glu_mouse_read_stat = false; // signal next read will be mouse X + break; + + case GLU_ANY_KEY_DOWN: // bit 7 is the actual flag here; both MCU programs write either 0x7f or 0xff +// printf("%d to ANY_KEY_DOWN (PC=%x)\n", data, m_adbmicro->pc()); + if (data & 0x80) + { + m_glu_regs[GLU_KG_STATUS] |= KGS_ANY_KEY_DOWN | KGS_KEYSTROBE; + } + break; + + case GLU_DATA: + m_glu_regs[GLU_DATA] = data; + m_glu_regs[GLU_KG_STATUS] |= KGS_DATA_FULL; + m_glu_regs[GLU_SYSSTAT] |= GLU_STATUS_DATAIRQ; +#if RUN_ADB_MICRO + if (m_glu_regs[GLU_SYSSTAT] & GLU_STATUS_DATAIRQEN) + { + raise_irq(IRQS_ADB); + } #endif + m_glu_816_read_dstat = false; +// printf("MCU writes %02x to DATA\n", data); + break; + } +} -WRITE_LINE_MEMBER(apple2gs_state::a2bus_irq_w) +/* + Keyglu registers map as follows on the 816: + + C000 = key data + any key down, clears strobe + C010 = clears keystrobe + C024 MOUSEDATA = reads GLU mouseX and mouseY + C025 KEYMODREG = reads GLU keymod register + C026 DATAREG = writes from the 816 go to COMMAND, reads from DATA + C027 KMSTATUS = GLU system status register +*/ + +uint8_t apple2gs_state::keyglu_816_read(uint8_t offset) +{ + switch (offset) + { + case GLU_C000: + { + uint8_t rv; + rv = m_glu_regs[GLU_KEY_DATA] & 0x7f; + if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) + { + rv |= 0x80; + } + return rv; + } + break; + + case GLU_C010: + { + uint8_t rv; + rv = m_glu_regs[GLU_KEY_DATA] & 0x7f; + if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) + { + rv |= 0x80; + } + m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE; + return rv; + } + break; + + case GLU_MOUSEX: + case GLU_MOUSEY: + if (!m_glu_mouse_read_stat) + { + m_glu_mouse_read_stat = 1; + return m_glu_regs[GLU_MOUSEY]; + } + return m_glu_regs[GLU_MOUSEX]; + + case GLU_SYSSTAT: + // regenerate sysstat bits + m_glu_sysstat &= ~0xab; // mask off read/write bits + if (m_glu_regs[GLU_KG_STATUS] & KGS_COMMAND_FULL) + { + m_glu_sysstat |= 1; + } + if (m_glu_regs[GLU_KG_STATUS] & m_glu_mouse_read_stat) + { + m_glu_sysstat |= 2; + } + if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) + { + m_glu_sysstat |= 8; + } + if (m_glu_regs[GLU_KG_STATUS] & KGS_DATA_FULL) + { + m_glu_sysstat |= 0x20; + } + if (m_glu_regs[GLU_KG_STATUS] & KGS_MOUSEX_FULL) + { + m_glu_sysstat |= 0x80; + } + m_glu_816_read_dstat = true; +// printf("816 gets %02x in sysstat (data avail %02x)\n", m_glu_sysstat, m_glu_sysstat & 0x20); + return m_glu_sysstat; + + case GLU_DATA: + if (m_glu_816_read_dstat) + { + m_glu_816_read_dstat = false; + m_glu_regs[GLU_KG_STATUS] &= ~KGS_DATA_FULL; +// keyglu_regen_irqs(); +// printf("816 reads %02x from DATA\n", m_glu_regs[GLU_DATA]); + } + return m_glu_regs[GLU_DATA]; + + default: + return m_glu_regs[offset]; + break; + } + + return 0xff; +} + +void apple2gs_state::keyglu_816_write(uint8_t offset, uint8_t data) +{ + if (offset < GLU_C000) + { + m_glu_regs[offset&7] = data; + } + + switch (offset) + { + case GLU_C010: + m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE; + break; + + case GLU_COMMAND: +// printf("816 sets COMMAND to %02x (raise command full)\n", data); + m_glu_regs[GLU_KG_STATUS] |= KGS_COMMAND_FULL; + break; + + case GLU_SYSSTAT: + m_glu_sysstat &= 0xab; // clear the non-read-only fields + m_glu_sysstat |= (data & ~0xab); + + if (m_glu_sysstat) + { + } + break; + } +} + +/* Sound - DOC */ +WRITE_LINE_MEMBER(apple2gs_state::doc_irq) { if (state) { - apple2gs_add_irq(IRQ_SLOT); + raise_irq(IRQS_DOC); } else { - apple2gs_remove_irq(IRQ_SLOT); + lower_irq(IRQS_DOC); } } -WRITE_LINE_MEMBER(apple2gs_state::a2bus_nmi_w) +READ8_MEMBER(apple2gs_state::doc_adc_read) { - m_maincpu->set_input_line(INPUT_LINE_NMI, state); + return 0x80; } -WRITE_LINE_MEMBER(apple2gs_state::a2bus_inh_w) +// temporary hookup of old IWM + +int apple2gs_state::apple2_fdc_has_35() { - m_inh_slot = -1; - apple2_update_memory(); + return (floppy_get_count(machine())); // - apple525_get_count(machine)) > 0; +} + +int apple2gs_state::apple2_fdc_has_525() +{ + return 1; //apple525_get_count(machine) > 0; } +static void apple2_fdc_set_lines(device_t *device, uint8_t lines) +{ + apple2gs_state *state = device->machine().driver_data<apple2gs_state>(); + if (state->m_diskreg & 0x40) + { + if (state->apple2_fdc_has_35()) + { + /* slot 5: 3.5" disks */ + sony_set_lines(device,lines); + } + } + else + { + if (state->apple2_fdc_has_525()) + { + /* slot 6: 5.25" disks */ + apple525_set_lines(device,lines); + } + } +} + +static void apple2_fdc_set_enable_lines(device_t *device,int enable_mask) +{ + apple2gs_state *state = device->machine().driver_data<apple2gs_state>(); + int slot5_enable_mask = 0; + int slot6_enable_mask = 0; + + if (state->m_diskreg & 0x40) + slot5_enable_mask = enable_mask; + else + slot6_enable_mask = enable_mask; + + if (state->apple2_fdc_has_35()) + { + /* set the 3.5" enable lines */ + sony_set_enable_lines(device,slot5_enable_mask); + } + + if (state->apple2_fdc_has_525()) + { + /* set the 5.25" enable lines */ + apple525_set_enable_lines(device,slot6_enable_mask); + } +} + +static uint8_t apple2_fdc_read_data(device_t *device) +{ + apple2gs_state *state = device->machine().driver_data<apple2gs_state>(); + uint8_t result = 0x00; + + if (state->m_diskreg & 0x40) + { + if (state->apple2_fdc_has_35()) + { + /* slot 5: 3.5" disks */ + result = sony_read_data(device); + } + } + else + { + if (state->apple2_fdc_has_525()) + { + /* slot 6: 5.25" disks */ + result = apple525_read_data(device); + } + } + return result; +} + +static void apple2_fdc_write_data(device_t *device, uint8_t data) +{ + apple2gs_state *state = device->machine().driver_data<apple2gs_state>(); + if (state->m_diskreg & 0x40) + { + if (state->apple2_fdc_has_35()) + { + /* slot 5: 3.5" disks */ + sony_write_data(device,data); + } + } + else + { + if (state->apple2_fdc_has_525()) + { + /* slot 6: 5.25" disks */ + apple525_write_data(device,data); + } + } +} + +static int apple2_fdc_read_status(device_t *device) +{ + apple2gs_state *state = device->machine().driver_data<apple2gs_state>(); + int result = 0; + + if (state->m_diskreg & 0x40) + { + if (state->apple2_fdc_has_35()) + { + /* slot 5: 3.5" disks */ + result = sony_read_status(device); + } + } + else + { + if (state->apple2_fdc_has_525()) + { + /* slot 6: 5.25" disks */ + result = apple525_read_status(device); + } + } + return result; +} + +void apple2gs_state::apple2_iwm_setdiskreg(uint8_t data) +{ + if (apple2_fdc_has_35()) + { + sony_set_sel_line(m_iwm, m_diskreg & 0x80); + } +} + +const applefdc_interface apple2_fdc_interface = +{ + apple2_fdc_set_lines, /* set_lines */ + apple2_fdc_set_enable_lines, /* set_enable_lines */ + + apple2_fdc_read_data, /* read_data */ + apple2_fdc_write_data, /* write_data */ + apple2_fdc_read_status /* read_status */ +}; + +static const floppy_interface apple2gs_floppy35_floppy_interface = +{ + FLOPPY_STANDARD_5_25_DSHD, + LEGACY_FLOPPY_OPTIONS_NAME(apple35_iigs), + "floppy_3_5" +}; + +static const floppy_interface apple2gs_floppy525_floppy_interface = +{ + FLOPPY_STANDARD_5_25_DSHD, + LEGACY_FLOPPY_OPTIONS_NAME(apple2), + "floppy_5_25" +}; + + +/*************************************************************************** + INPUT PORTS +***************************************************************************/ + +static INPUT_PORTS_START( apple2gs_gameport ) + PORT_START("joystick_1_x") /* Joystick 1 X Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X) PORT_NAME("P1 Joystick X") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_4_PAD) PORT_CODE_INC(KEYCODE_6_PAD) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("joystick_1_y") /* Joystick 1 Y Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y) PORT_NAME("P1 Joystick Y") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_8_PAD) PORT_CODE_INC(KEYCODE_2_PAD) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + + PORT_START("joystick_2_x") /* Joystick 2 X Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X) PORT_NAME("P2 Joystick X") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("joystick_2_y") /* Joystick 2 Y Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y) PORT_NAME("P2 Joystick Y") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + + PORT_START("joystick_buttons") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(JOYCODE_BUTTON1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(1) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CODE(JOYCODE_BUTTON2) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON2) +INPUT_PORTS_END + + /* + Apple IIe platinum and IIgs upgrade key matrix + + | Y0 | Y1 | Y2 | Y3 | Y4 | Y5 | Y6 | Y7 | Y8 | Y9 | + | | | | | | | | | | | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X0 | ESC | 1 | 2 | 3 | 4 | 6 | 5 | 7 | 8 | 9 | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X1 | TAB | Q | W | E | R | Y | T | U | I | O | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X2 | A | D | S | H | F | G | J | K | ;: | L | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X3 | Z | X | C | V | B | M | N | ,< | .> | /? | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X4 | KP/ | | KP0 | KP1 | KP2 | KP3 | \| | += | 0 | -_ | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X5 | |KPEsc| KP4 | KP5 | KP6 | KP7 | `~ | P | [{ | ]} | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X6 | KP* | | KP8 | KP9 | KP. | KP+ |RETRN| UP | SPC | '" | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X7 | | | | KP- |KPENT| | DEL |DOWN |LEFT |RIGHT| + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + */ + +INPUT_PORTS_START( apple2gs ) +#if RUN_ADB_MICRO + PORT_START(A2GS_KBD_Y0_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START(A2GS_KBD_Y1_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad Esc") PORT_CODE(KEYCODE_NUMLOCK) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START(A2GS_KBD_Y2_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START(A2GS_KBD_Y3_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + + PORT_START(A2GS_KBD_Y4_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + + PORT_START(A2GS_KBD_Y5_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START(A2GS_KBD_Y6_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_BACKSPACE)PORT_CHAR(8) + + PORT_START(A2GS_KBD_Y7_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10) + + PORT_START(A2GS_KBD_Y8_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) + + PORT_START(A2GS_KBD_Y9_TAG) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) +#else + PORT_START("X0") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + + PORT_START("X1") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + + PORT_START("X2") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + + PORT_START("X3") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("X4") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + + PORT_START("X5") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad Esc") PORT_CODE(KEYCODE_NUMLOCK) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + + PORT_START("X6") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') + + PORT_START("X7") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_BACKSPACE)PORT_CHAR(8) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + + PORT_START("X8") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNUSED) +#endif + + PORT_START(A2GS_KBD_SPEC_TAG) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Open Apple") PORT_CODE(KEYCODE_LALT) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Solid Apple") PORT_CODE(KEYCODE_RALT) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) + + PORT_INCLUDE(apple2gs_gameport) + + PORT_START("adb_mouse_x") + PORT_BIT( 0x7f, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Mouse Button 1") + + PORT_START("adb_mouse_y") + PORT_BIT( 0x7f, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Mouse Button 0") +INPUT_PORTS_END + static void apple2_cards(device_slot_interface &device) { - device.option_add("diskii", A2BUS_DISKII); /* Disk II Controller Card */ + device.option_add("diskiing", A2BUS_DISKIING); /* Disk II Controller Card, cycle-accurate version */ device.option_add("mockingboard", A2BUS_MOCKINGBOARD); /* Sweet Micro Systems Mockingboard */ device.option_add("phasor", A2BUS_PHASOR); /* Applied Engineering Phasor */ device.option_add("cffa2", A2BUS_CFFA2); /* CFFA2000 Compact Flash for Apple II (www.dreher.net), 65C02/65816 firmware */ @@ -296,30 +4635,51 @@ static void apple2_cards(device_slot_interface &device) device.option_add("memexp", A2BUS_MEMEXP); /* Apple II Memory Expansion Card */ device.option_add("ramfactor", A2BUS_RAMFACTOR); /* Applied Engineering RamFactor */ device.option_add("thclock", A2BUS_THUNDERCLOCK); /* ThunderWare ThunderClock Plus */ + device.option_add("softcard", A2BUS_SOFTCARD); /* Microsoft SoftCard */ + device.option_add("videoterm", A2BUS_VIDEOTERM); /* Videx VideoTerm */ device.option_add("ssc", A2BUS_SSC); /* Apple Super Serial Card */ + device.option_add("swyft", A2BUS_SWYFT); /* IAI SwyftCard */ + device.option_add("themill", A2BUS_THEMILL); /* Stellation Two The Mill (6809 card) */ device.option_add("sam", A2BUS_SAM); /* SAM Software Automated Mouth (8-bit DAC + speaker) */ device.option_add("alfam2", A2BUS_ALFAM2); /* ALF Apple Music II */ device.option_add("echoii", A2BUS_ECHOII); /* Street Electronics Echo II */ + device.option_add("ap16", A2BUS_IBSAP16); /* IBS AP16 (German VideoTerm clone) */ + device.option_add("ap16alt", A2BUS_IBSAP16ALT); /* IBS AP16 (German VideoTerm clone), alternate revision */ + device.option_add("vtc1", A2BUS_VTC1); /* Unknown VideoTerm clone #1 */ + device.option_add("vtc2", A2BUS_VTC2); /* Unknown VideoTerm clone #2 */ device.option_add("arcbd", A2BUS_ARCADEBOARD); /* Third Millenium Engineering Arcade Board */ device.option_add("midi", A2BUS_MIDI); /* Generic 6840+6850 MIDI board */ - device.option_add("vulcan", A2BUS_VULCAN); /* AE Vulcan IDE card */ - device.option_add("vulcangold", A2BUS_VULCANGOLD); /* AE Vulcan Gold IDE card */ device.option_add("zipdrive", A2BUS_ZIPDRIVE); /* ZIP Technologies IDE card */ device.option_add("echoiiplus", A2BUS_ECHOPLUS); /* Street Electronics Echo Plus (Echo II + Mockingboard clone) */ -// device.option_add("mdturbo", A2BUS_UDRIVE_TURBO); /* ///SHH Systeme MicroDrive Turbo IDE card */ - -// device.option_add("softcard", A2BUS_SOFTCARD); /* Microsoft SoftCard */ // appears not to be IIgs compatible? device.option_add("scsi", A2BUS_SCSI); /* Apple II SCSI Card */ - device.option_add("hsscsi", A2BUS_HSSCSI); /* Apple II High-Speed SCSI Card */ + device.option_add("applicard", A2BUS_APPLICARD); /* PCPI Applicard */ + device.option_add("aesms", A2BUS_AESMS); /* Applied Engineering Super Music Synthesizer */ + device.option_add("ultraterm", A2BUS_ULTRATERM); /* Videx UltraTerm (original) */ + device.option_add("ultratermenh", A2BUS_ULTRATERMENH); /* Videx UltraTerm (enhanced //e) */ + device.option_add("aevm80", A2BUS_VTC2); /* Applied Engineering ViewMaster 80 */ + device.option_add("parallel", A2BUS_PIC); /* Apple Parallel Interface Card */ + device.option_add("corvus", A2BUS_CORVUS); /* Corvus flat-cable HDD interface (see notes in a2corvus.c) */ + device.option_add("mcms1", A2BUS_MCMS1); /* Mountain Computer Music System, card 1 of 2 */ + device.option_add("mcms2", A2BUS_MCMS2); /* Mountain Computer Music System, card 2 of 2. must be in card 1's slot + 1! */ + device.option_add("dx1", A2BUS_DX1); /* Decillonix DX-1 sampler card */ + device.option_add("tm2ho", A2BUS_TIMEMASTERHO); /* Applied Engineering TimeMaster II H.O. */ + device.option_add("mouse", A2BUS_MOUSE); /* Apple II Mouse Card */ + device.option_add("ezcgi", A2BUS_EZCGI); /* E-Z Color Graphics Interface */ + device.option_add("ezcgi9938", A2BUS_EZCGI_9938); /* E-Z Color Graphics Interface (TMS9938) */ + device.option_add("ezcgi9958", A2BUS_EZCGI_9958); /* E-Z Color Graphics Interface (TMS9958) */ +// device.option_add("magicmusician", A2BUS_MAGICMUSICIAN); /* Magic Musician Card */ +// device.option_add("pcxport", A2BUS_PCXPORTER); /* Applied Engineering PC Transporter */ } -MACHINE_CONFIG_START(apple2gs_state::apple2gs) +MACHINE_CONFIG_START( apple2gs_state::apple2gs ) /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", G65816, APPLE2GS_14M/5) + MCFG_DEVICE_ADD("maincpu", G65816, A2GS_MASTER_CLOCK/10) MCFG_DEVICE_PROGRAM_MAP(apple2gs_map) MCFG_DEVICE_ADDRESS_MAP(g65816_device::AS_VECTORS, vectors_map) - #if RUN_ADB_MICRO - MCFG_DEVICE_ADD(ADBMICRO_TAG, M50741, XTAL(3'579'545)) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", apple2gs_state, apple2_interrupt, "screen", 0, 1) + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + + MCFG_DEVICE_ADD(A2GS_ADBMCU_TAG, M50741, A2GS_MASTER_CLOCK/8) MCFG_M5074X_PORT0_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p0_in)) MCFG_M5074X_PORT0_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p0_out)) MCFG_M5074X_PORT1_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p1_in)) @@ -328,25 +4688,8 @@ MACHINE_CONFIG_START(apple2gs_state::apple2gs) MCFG_M5074X_PORT2_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p2_out)) MCFG_M5074X_PORT3_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p3_in)) MCFG_M5074X_PORT3_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p3_out)) - #endif - MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", apple2gs_state, apple2_interrupt, "screen", 0, 1) - MCFG_QUANTUM_TIME(attotime::from_hz(60)) - - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_SIZE(704, 262) // 640+32+32 for the borders - MCFG_SCREEN_VISIBLE_AREA(0,703,0,230) - MCFG_SCREEN_UPDATE_DRIVER(apple2gs_state, screen_update_apple2gs) - - MCFG_PALETTE_ADD("palette", 16) - MCFG_PALETTE_INIT_OWNER(apple2gs_state, apple2gs) - MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_apple2gs ) - - MCFG_MACHINE_START_OVERRIDE(apple2gs_state, apple2gs ) - MCFG_MACHINE_RESET_OVERRIDE(apple2gs_state, apple2gs ) - - MCFG_VIDEO_START_OVERRIDE(apple2gs_state, apple2gs ) +#if !RUN_ADB_MICRO /* keyboard controller */ MCFG_DEVICE_ADD("ay3600", AY3600, 0) MCFG_AY3600_MATRIX_X0(IOPORT("X0")) @@ -358,43 +4701,238 @@ MACHINE_CONFIG_START(apple2gs_state::apple2gs) MCFG_AY3600_MATRIX_X6(IOPORT("X6")) MCFG_AY3600_MATRIX_X7(IOPORT("X7")) MCFG_AY3600_MATRIX_X8(IOPORT("X8")) - MCFG_AY3600_SHIFT_CB(READLINE(*this, apple2_state, ay3600_shift_r)) - MCFG_AY3600_CONTROL_CB(READLINE(*this, apple2_state, ay3600_control_r)) - MCFG_AY3600_DATA_READY_CB(WRITELINE(*this, apple2_state, ay3600_iie_data_ready_w)) + MCFG_AY3600_SHIFT_CB(READLINE(*this, apple2gs_state, ay3600_shift_r)) + MCFG_AY3600_CONTROL_CB(READLINE(*this, apple2gs_state, ay3600_control_r)) + MCFG_AY3600_DATA_READY_CB(WRITELINE(*this, apple2gs_state, ay3600_data_ready_w)) + MCFG_AY3600_AKO_CB(WRITELINE(*this, apple2gs_state, ay3600_ako_w)) + + /* repeat timer. 15 Hz from page 7-15 of "Understanding the Apple IIe" */ + MCFG_TIMER_DRIVER_ADD_PERIODIC("repttmr", apple2gs_state, ay3600_repeat, attotime::from_hz(15)) +#endif + + MCFG_DEVICE_ADD(A2GS_VIDEO_TAG, APPLE2_VIDEO, A2GS_14M) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_SIZE(704, 262) // 640+32+32 for the borders + MCFG_SCREEN_VISIBLE_AREA(0,703,0,230) + MCFG_SCREEN_UPDATE_DRIVER(apple2gs_state, screen_update) + + MCFG_PALETTE_ADD("palette", 256) + MCFG_PALETTE_INIT_OWNER(apple2gs_state, apple2gs) /* sound hardware */ SPEAKER(config, "mono").front_center(); - MCFG_DEVICE_ADD("a2speaker", SPEAKER_SOUND) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + MCFG_DEVICE_ADD(A2GS_SPEAKER_TAG, SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - - MCFG_ES5503_ADD("es5503", APPLE2GS_7M) + MCFG_ES5503_ADD(A2GS_DOC_TAG, A2GS_7M) MCFG_ES5503_OUTPUT_CHANNELS(2) - MCFG_ES5503_IRQ_FUNC(WRITELINE(*this, apple2gs_state, apple2gs_doc_irq)) - MCFG_ES5503_ADC_FUNC(READ8(*this, apple2gs_state, apple2gs_adc_read)) + MCFG_ES5503_IRQ_FUNC(WRITELINE(*this, apple2gs_state, doc_irq)) + MCFG_ES5503_ADC_FUNC(READ8(*this, apple2gs_state, doc_adc_read)) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) - /* slot devices */ - MCFG_DEVICE_ADD(m_a2bus, A2BUS, 0) - MCFG_A2BUS_CPU("maincpu") - MCFG_A2BUS_OUT_IRQ_CB(WRITELINE(*this, apple2gs_state, a2bus_irq_w)) - MCFG_A2BUS_OUT_NMI_CB(WRITELINE(*this, apple2gs_state, a2bus_nmi_w)) - MCFG_A2BUS_OUT_INH_CB(WRITELINE(*this, apple2gs_state, a2bus_inh_w)) - A2BUS_SLOT(config, "sl1", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl2", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl3", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl4", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl5", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl6", m_a2bus, apple2_cards, nullptr); - A2BUS_SLOT(config, "sl7", m_a2bus, apple2_cards, nullptr); + /* RAM */ + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("2M") + MCFG_RAM_EXTRA_OPTIONS("1M,3M,4M,5M,6M,7M,8M") + MCFG_RAM_DEFAULT_VALUE(0x00) + + /* 0000 banking */ + MCFG_DEVICE_ADD(A2GS_0000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r0000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) + + /* 0200 banking */ + MCFG_DEVICE_ADD(A2GS_0200_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r0200bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) + + /* 0400 banking */ + MCFG_DEVICE_ADD(A2GS_0400_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r0400bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) + + /* 0800 banking */ + MCFG_DEVICE_ADD(A2GS_0800_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r0800bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + + /* 2000 banking */ + MCFG_DEVICE_ADD(A2GS_2000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r2000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + + /* 4000 banking */ + MCFG_DEVICE_ADD(A2GS_4000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(r4000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) + + /* C100 banking */ + MCFG_DEVICE_ADD(A2GS_C100_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(c100bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) + + /* C300 banking */ + MCFG_DEVICE_ADD(A2GS_C300_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(c300bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x100) + + /* C400 banking */ + MCFG_DEVICE_ADD(A2GS_C400_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(c400bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) + + /* C800 banking */ + MCFG_DEVICE_ADD(A2GS_C800_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(c800bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x800) + + /* built-in language card emulation */ + MCFG_DEVICE_ADD(A2GS_LCBANK_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(lcbank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* aux bank language card emulation */ + MCFG_DEVICE_ADD(A2GS_LCAUX_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(lcaux_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* bank 00 language card emulation */ + MCFG_DEVICE_ADD(A2GS_LC00_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(lc00_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* bank 01 language card emulation */ + MCFG_DEVICE_ADD(A2GS_LC01_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(lc01_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* /INH banking */ + MCFG_DEVICE_ADD(A2GS_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(inhbank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) - MCFG_IWM_ADD("fdc", apple2_fdc_interface) + /* /INH banking - aux bank */ + MCFG_DEVICE_ADD(A2GS_AUXUPPER_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(inhaux_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) - /* SCC */ - MCFG_DEVICE_ADD(SCC_TAG, SCC85C30, APPLE2GS_14M/2) + /* /INH banking - bank 00 */ + MCFG_DEVICE_ADD(A2GS_00UPPER_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(inh00_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* /INH banking - bank 01 */ + MCFG_DEVICE_ADD(A2GS_01UPPER_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(inh01_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* Bank 0 - I/O and LC area */ + MCFG_DEVICE_ADD(A2GS_B0CXXX_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(bank0_iolc_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) + + /* Bank 1 - lower 48K */ + MCFG_DEVICE_ADD(A2GS_B01_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(bank1_lower48_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0xc000) + + /* Bank 1 - I/O and LC area */ + MCFG_DEVICE_ADD(A2GS_B1CXXX_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(bank1_iolc_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) + + /* Bank 0 0000 banking */ + MCFG_DEVICE_ADD(A2GS_B00000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb0000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) + + /* Bank 0 0200 banking */ + MCFG_DEVICE_ADD(A2GS_B00200_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb0200bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) + + /* Bank 0 0400 banking */ + MCFG_DEVICE_ADD(A2GS_B00400_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb0400bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) + + /* Bank 0 0800 banking */ + MCFG_DEVICE_ADD(A2GS_B00800_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb0800bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + + /* Bank 0 2000 banking */ + MCFG_DEVICE_ADD(A2GS_B02000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb2000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + + /* Bank 0 4000 banking */ + MCFG_DEVICE_ADD(A2GS_B04000_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(rb4000bank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) + + /* serial */ + MCFG_DEVICE_ADD(SCC_TAG, SCC85C30, A2GS_14M/2) MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(RS232A_TAG, rs232_port_device, write_txd)) MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(RS232B_TAG, rs232_port_device, write_txd)) @@ -408,27 +4946,35 @@ MACHINE_CONFIG_START(apple2gs_state::apple2gs) MCFG_RS232_DCD_HANDLER(WRITELINE(SCC_TAG, z80scc_device, dcdb_w)) MCFG_RS232_CTS_HANDLER(WRITELINE(SCC_TAG, z80scc_device, ctsb_w)) + /* slot devices */ + MCFG_DEVICE_ADD("a2bus", A2BUS, 0) + MCFG_A2BUS_CPU("maincpu") + MCFG_A2BUS_OUT_IRQ_CB(WRITELINE(*this, apple2gs_state, a2bus_irq_w)) + MCFG_A2BUS_OUT_NMI_CB(WRITELINE(*this, apple2gs_state, a2bus_nmi_w)) + MCFG_A2BUS_OUT_INH_CB(WRITELINE(*this, apple2gs_state, a2bus_inh_w)) + A2BUS_SLOT(config, "sl1", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl2", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl3", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl4", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl5", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl6", m_a2bus, apple2_cards, nullptr); + A2BUS_SLOT(config, "sl7", m_a2bus, apple2_cards, nullptr); + + MCFG_IWM_ADD(A2GS_IWM_TAG, apple2_fdc_interface) MCFG_LEGACY_FLOPPY_APPLE_2_DRIVES_ADD(apple2gs_floppy525_floppy_interface,15,16) MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADDITIONAL_ADD(apple2gs_floppy35_floppy_interface) - - MCFG_NVRAM_ADD_0FILL("nvram") - - /* internal ram */ - MCFG_RAM_ADD(RAM_TAG) - MCFG_RAM_DEFAULT_SIZE("2M") // 1M on board + 1M in the expansion slot was common for ROM 03 - MCFG_RAM_EXTRA_OPTIONS("1M,3M,4M,5M,6M,7M,8M") - MCFG_RAM_DEFAULT_VALUE(0x00) - MCFG_SOFTWARE_LIST_ADD("flop35_list","apple2gs") MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("flop525_list", "apple2") MACHINE_CONFIG_END -MACHINE_CONFIG_START(apple2gs_state::apple2gsr1) +MACHINE_CONFIG_START( apple2gs_state::apple2gsr1 ) apple2gs(config); - MCFG_MACHINE_START_OVERRIDE(apple2gs_state, apple2gsr1 ) + MCFG_RAM_MODIFY(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("1280K") // 256K on board + 1M in the expansion slot was common for ROM 01 + MCFG_RAM_EXTRA_OPTIONS("256K,512K,768K,1M,2M,3M,4M,5M,6M,7M,8M") + MCFG_RAM_DEFAULT_VALUE(0x00) - #if RUN_ADB_MICRO - MCFG_DEVICE_REPLACE(ADBMICRO_TAG, M50740, XTAL(3'579'545)) + MCFG_DEVICE_REPLACE(A2GS_ADBMCU_TAG, M50740, A2GS_MASTER_CLOCK/8) MCFG_M5074X_PORT0_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p0_in)) MCFG_M5074X_PORT0_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p0_out)) MCFG_M5074X_PORT1_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p1_in)) @@ -437,12 +4983,6 @@ MACHINE_CONFIG_START(apple2gs_state::apple2gsr1) MCFG_M5074X_PORT2_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p2_out)) MCFG_M5074X_PORT3_READ_CALLBACK(READ8(*this, apple2gs_state, adbmicro_p3_in)) MCFG_M5074X_PORT3_WRITE_CALLBACK(WRITE8(*this, apple2gs_state, adbmicro_p3_out)) - #endif - - MCFG_RAM_MODIFY(RAM_TAG) - MCFG_RAM_DEFAULT_SIZE("1280K") // 256K on board + 1M in the expansion slot was common for ROM 01 - MCFG_RAM_EXTRA_OPTIONS("256K,512K,768K,1M,2M,3M,4M,5M,6M,7M,8M") - MCFG_RAM_DEFAULT_VALUE(0x00) MACHINE_CONFIG_END /*************************************************************************** @@ -450,10 +4990,9 @@ MACHINE_CONFIG_END Game driver(s) ***************************************************************************/ - ROM_START(apple2gs) // M50740/50741 ADB MCU inside the IIgs system unit - ROM_REGION(0x1000,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0x1000,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0632-2.bin", 0x000000, 0x001000, CRC(e1c11fb0) SHA1(141d18c36a617ab9dce668445440d34354be0672) ) // i8048 microcontroller inside the IIgs ADB Standard Keyboard @@ -475,7 +5014,7 @@ ROM_START(apple2gs) ROM_LOAD("341-0748", 0x30000, 0x10000, CRC(18190283) SHA1(c70576869deec92ca82c78438b1d5c686eac7480) ) /* 341-0748: IIgs ROM03 FE-FF */ ROM_CONTINUE ( 0x20000, 0x10000) /* high address line is inverted on PCB? */ - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) @@ -483,7 +5022,7 @@ ROM_START(apple2gs) ROM_END ROM_START(apple2gsr3p) - ROM_REGION(0x1000,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0x1000,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0632-2.bin", 0x000000, 0x001000, CRC(e1c11fb0) SHA1(141d18c36a617ab9dce668445440d34354be0672) ) ROM_REGION(0x400, "kmcu", 0) @@ -497,7 +5036,7 @@ ROM_START(apple2gsr3p) ROM_LOAD("341-0728", 0x00000, 0x20000, CRC(8d410067) SHA1(c0f4704233ead14cb8e1e8a68fbd7063c56afd27) ) /* 341-0728: IIgs ROM03 prototype FC-FD - 28 pin MASK rom */ ROM_LOAD("341-0729", 0x20000, 0x20000, NO_DUMP) /* 341-0729: IIgs ROM03 prototype FE-FF */ - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) @@ -505,7 +5044,7 @@ ROM_START(apple2gsr3p) ROM_END ROM_START(apple2gsr1) - ROM_REGION(0xc00,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0xc00,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0345.bin", 0x000000, 0x000c00, CRC(48cd5779) SHA1(97e421f5247c00a0ca34cd08b6209df573101480) ) ROM_REGION(0x400, "kmcu", 0) @@ -515,10 +5054,10 @@ ROM_START(apple2gsr1) ROM_REGION(0x1000,"gfx1",0) ROM_LOAD ( "apple2gs.chr", 0x0000, 0x1000, CRC(91e53cd8) SHA1(34e2443e2ef960a36c047a09ed5a93f471797f89)) /* need label/part number */ - ROM_REGION(0x20000,"maincpu",0) - ROM_LOAD("342-0077-b", 0x0000, 0x20000, CRC(42f124b0) SHA1(e4fc7560b69d062cb2da5b1ffbe11cd1ca03cc37)) /* 342-0077-B: IIgs ROM01 */ + ROM_REGION(0x40000,"maincpu",0) + ROM_LOAD("342-0077-b", 0x20000, 0x20000, CRC(42f124b0) SHA1(e4fc7560b69d062cb2da5b1ffbe11cd1ca03cc37)) /* 342-0077-B: IIgs ROM01 */ - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) @@ -526,7 +5065,7 @@ ROM_START(apple2gsr1) ROM_END ROM_START(apple2gsr0) - ROM_REGION(0xc00,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0xc00,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0345.bin", 0x000000, 0x000c00, CRC(48cd5779) SHA1(97e421f5247c00a0ca34cd08b6209df573101480) ) ROM_REGION(0x400, "kmcu", 0) @@ -536,10 +5075,10 @@ ROM_START(apple2gsr0) ROM_REGION(0x1000,"gfx1",0) ROM_LOAD ( "apple2gs.chr", 0x0000, 0x1000, CRC(91e53cd8) SHA1(34e2443e2ef960a36c047a09ed5a93f471797f89)) - ROM_REGION(0x20000,"maincpu",0) - ROM_LOAD("342-0077-a", 0x0000, 0x20000, CRC(dfbdd97b) SHA1(ff0c245dd0732ec4413a934fd80efc2defd8a8e3) ) /* 342-0077-A: IIgs ROM00 */ + ROM_REGION(0x40000,"maincpu",0) + ROM_LOAD("342-0077-a", 0x20000, 0x20000, CRC(dfbdd97b) SHA1(ff0c245dd0732ec4413a934fd80efc2defd8a8e3) ) /* 342-0077-A: IIgs ROM00 */ - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) @@ -547,7 +5086,7 @@ ROM_START(apple2gsr0) ROM_END ROM_START(apple2gsr0p) // 6/19/1986 Cortland prototype - ROM_REGION(0xc00,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0xc00,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0345.bin", 0x000000, 0x000c00, CRC(48cd5779) SHA1(97e421f5247c00a0ca34cd08b6209df573101480) ) ROM_REGION(0x400, "kmcu", 0) @@ -557,10 +5096,10 @@ ROM_START(apple2gsr0p) // 6/19/1986 Cortland prototype ROM_REGION(0x1000,"gfx1",0) ROM_LOAD ( "apple2gs.chr", 0x0000, 0x1000, CRC(91e53cd8) SHA1(34e2443e2ef960a36c047a09ed5a93f471797f89)) - ROM_REGION(0x20000,"maincpu",0) - ROM_LOAD( "rombf.bin", 0x000000, 0x020000, CRC(ab04fedf) SHA1(977589a17553956d583a21020080a39dd396df5c) ) + ROM_REGION(0x40000,"maincpu",0) + ROM_LOAD( "rombf.bin", 0x020000, 0x020000, CRC(ab04fedf) SHA1(977589a17553956d583a21020080a39dd396df5c) ) - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) @@ -568,7 +5107,7 @@ ROM_START(apple2gsr0p) // 6/19/1986 Cortland prototype ROM_END ROM_START(apple2gsr0p2) // 3/10/1986 Cortland prototype, boots as "Apple //'ing - Alpha 2.0" - ROM_REGION(0xc00,M5074X_INTERNAL_ROM(ADBMICRO_TAG),0) + ROM_REGION(0xc00,M5074X_INTERNAL_ROM(A2GS_ADBMCU_TAG),0) ROM_LOAD( "341s0345.bin", 0x000000, 0x000c00, CRC(48cd5779) SHA1(97e421f5247c00a0ca34cd08b6209df573101480) ) ROM_REGION(0x400, "kmcu", 0) @@ -578,20 +5117,20 @@ ROM_START(apple2gsr0p2) // 3/10/1986 Cortland prototype, boots as "Apple //'ing ROM_REGION(0x1000,"gfx1",0) ROM_LOAD ( "apple2gs.chr", 0x0000, 0x1000, CRC(91e53cd8) SHA1(34e2443e2ef960a36c047a09ed5a93f471797f89)) - ROM_REGION(0x20000,"maincpu",0) - ROM_LOAD( "apple iigs alpha rom 2.0 19860310.bin", 0x000000, 0x020000, CRC(a47d275f) SHA1(c5836adcfc8be69c7351b84afa94c814e8d92b81) ) + ROM_REGION(0x40000,"maincpu",0) + ROM_LOAD( "apple iigs alpha rom 2.0 19860310.bin", 0x020000, 0x020000, CRC(a47d275f) SHA1(c5836adcfc8be69c7351b84afa94c814e8d92b81) ) - ROM_REGION(0x20000, "es5503", ROMREGION_ERASE00) + ROM_REGION(0x20000, A2GS_DOC_TAG, ROMREGION_ERASE00) // temporary: use IIe enhanced keyboard decode ROM ROM_REGION( 0x800, "keyboard", 0 ) ROM_LOAD( "341-0132-d.e12", 0x000, 0x800, CRC(c506efb9) SHA1(8e14e85c645187504ec9d162b3ea614a0c421d32) ) ROM_END -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ -COMP( 1989, apple2gs, 0, apple2, apple2gs, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM03)", MACHINE_SUPPORTS_SAVE ) -COMP( 198?, apple2gsr3p, apple2gs, 0, apple2gs, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM03 prototype)", MACHINE_NOT_WORKING ) -COMP( 1987, apple2gsr1, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM01)", MACHINE_SUPPORTS_SAVE ) -COMP( 1986, apple2gsr0, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM00)", MACHINE_SUPPORTS_SAVE ) -COMP( 1986, apple2gsr0p, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM00 prototype 6/19/1986)", MACHINE_SUPPORTS_SAVE ) -COMP( 1986, apple2gsr0p2, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, empty_init, "Apple Computer", "Apple IIgs (ROM00 prototype 3/10/1986)", MACHINE_SUPPORTS_SAVE ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ +COMP( 1989, apple2gs, 0, apple2, apple2gs, apple2gs, apple2gs_state, rom3_init, "Apple Computer", "Apple IIgs (ROM03)", MACHINE_SUPPORTS_SAVE ) +COMP( 198?, apple2gsr3p, apple2gs, 0, apple2gs, apple2gs, apple2gs_state, rom3_init, "Apple Computer", "Apple IIgs (ROM03 prototype)", MACHINE_NOT_WORKING ) +COMP( 1987, apple2gsr1, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, rom1_init, "Apple Computer", "Apple IIgs (ROM01)", MACHINE_SUPPORTS_SAVE ) +COMP( 1986, apple2gsr0, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, rom1_init, "Apple Computer", "Apple IIgs (ROM00)", MACHINE_SUPPORTS_SAVE ) +COMP( 1986, apple2gsr0p, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, rom1_init, "Apple Computer", "Apple IIgs (ROM00 prototype 6/19/1986)", MACHINE_SUPPORTS_SAVE ) +COMP( 1986, apple2gsr0p2, apple2gs, 0, apple2gsr1, apple2gs, apple2gs_state, rom1_init, "Apple Computer", "Apple IIgs (ROM00 prototype 3/10/1986)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/apple2.h b/src/mame/includes/apple2.h deleted file mode 100644 index a218b806d88..00000000000 --- a/src/mame/includes/apple2.h +++ /dev/null @@ -1,395 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/*************************************************************************** - - includes/apple2.h - - Include file to handle emulation of the Apple II series. - -***************************************************************************/ - -#ifndef MAME_INCLUDES_APPLE2_H -#define MAME_INCLUDES_APPLE2_H - -#include "cpu/m6502/m6502.h" -#include "cpu/m6502/m65c02.h" - -#include "imagedev/cassette.h" - -#include "machine/applefdc.h" -#include "machine/kb3600.h" -#include "machine/mos6551.h" -#include "machine/ram.h" -#include "machine/timer.h" - -#include "sound/spkrdev.h" - -#include "bus/a2bus/a2bus.h" -#include "bus/a2bus/a2eauxslot.h" -#include "bus/rs232/rs232.h" - -#include "emupal.h" -#include "screen.h" - - -#define AUXSLOT_TAG "auxbus" - -#define IIC_ACIA1_TAG "acia1" -#define IIC_ACIA2_TAG "acia2" -#define IICP_IWM_TAG "fdc" - -#define LASER128_UDC_TAG "l128udc" - -#define PRINTER_PORT_TAG "printer" -#define MODEM_PORT_TAG "modem" - -/*************************************************************************** - SOFTSWITCH VALUES -***************************************************************************/ - -#define VAR_80STORE 0x000001 -#define VAR_RAMRD 0x000002 -#define VAR_RAMWRT 0x000004 -#define VAR_INTCXROM 0x000008 -#define VAR_ALTZP 0x000010 -#define VAR_SLOTC3ROM 0x000020 -#define VAR_80COL 0x000040 -#define VAR_ALTCHARSET 0x000080 -#define VAR_TEXT 0x000100 -#define VAR_MIXED 0x000200 -#define VAR_PAGE2 0x000400 -#define VAR_HIRES 0x000800 -#define VAR_AN0 0x001000 -#define VAR_AN1 0x002000 -#define VAR_AN2 0x004000 -#define VAR_AN3 0x008000 -#define VAR_LCRAM 0x010000 -#define VAR_LCRAM2 0x020000 -#define VAR_LCWRITE 0x040000 -#define VAR_ROMSWITCH 0x080000 -#define VAR_TK2000RAM 0x100000 // ROM/RAM switch for TK2000 - -#define VAR_DHIRES VAR_AN3 - -/*************************************************************************** - OTHER -***************************************************************************/ - -/* ----------------------------------------------------------------------- - * New Apple II memory manager - * ----------------------------------------------------------------------- */ - -#define APPLE2_MEM_AUX 0x40000000 -#define APPLE2_MEM_SLOT 0x80000000 -#define APPLE2_MEM_ROM 0xC0000000 -#define APPLE2_MEM_FLOATING 0xFFFFFFFF -#define APPLE2_MEM_MASK 0x00FFFFFF - -enum machine_type_t -{ - APPLE_II, // Apple II/II+ - APPLE_IIE, // Apple IIe with aux slots - APPLE_IIGS, // Apple IIgs - APPLE_IIC, // Apple IIc - APPLE_IICPLUS, // Apple IIc+ - TK2000, // Microdigital TK2000 - TK3000, // Microdigital TK3000 - LASER128, // Laser 128/128EX/128EX2 - SPACE84, // "Space 84" with flipped text mode - LABA2P // lab equipment (?) II Plus with flipped text mode -}; - -enum bank_disposition_t -{ - A2MEM_IO = 0, /* this is always handlers; never banked memory */ - A2MEM_MONO = 1, /* this is a bank where read and write are always in unison */ - A2MEM_DUAL = 2 /* this is a bank where read and write can go different places */ -}; - -struct apple2_meminfo -{ - uint32_t read_mem; - read8_delegate *read_handler; - uint32_t write_mem; - write8_delegate *write_handler; -}; - -struct apple2_memmap_entry -{ - offs_t begin; - offs_t end; - void (*get_meminfo)(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo); - bank_disposition_t bank_disposition; -}; - -struct apple2_memmap_config -{ - int first_bank; - uint8_t *auxmem; - uint32_t auxmem_length; - const apple2_memmap_entry *memmap; -}; - -class apple2_state : public driver_device -{ -public: - apple2_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_screen(*this, "screen"), - m_ram(*this, RAM_TAG), - m_ay3600(*this, "ay3600"), - m_a2bus(*this, "a2bus"), - m_speaker(*this, "a2speaker"), - m_a2eauxslot(*this, AUXSLOT_TAG), - m_joy1x(*this, "joystick_1_x"), - m_joy1y(*this, "joystick_1_y"), - m_joy2x(*this, "joystick_2_x"), - m_joy2y(*this, "joystick_2_y"), - m_joybuttons(*this, "joystick_buttons"), - m_kbdrom(*this, "keyboard"), - m_kbspecial(*this, "keyb_special"), - m_kbrepeat(*this, "keyb_repeat"), - m_resetdip(*this, "reset_dip"), - m_sysconfig(*this, "a2_config"), - m_cassette(*this, "cassette"), - m_acia1(*this, IIC_ACIA1_TAG), - m_acia2(*this, IIC_ACIA2_TAG), - m_laserudc(*this, LASER128_UDC_TAG), - m_iicpiwm(*this, IICP_IWM_TAG) - { } - - required_device<cpu_device> m_maincpu; - required_device<screen_device> m_screen; - required_device<ram_device> m_ram; - required_device<ay3600_device> m_ay3600; - required_device<a2bus_device> m_a2bus; - required_device<speaker_sound_device> m_speaker; - optional_device<a2eauxslot_device> m_a2eauxslot; - - optional_ioport m_joy1x, m_joy1y, m_joy2x, m_joy2y, m_joybuttons; - optional_memory_region m_kbdrom; - required_ioport m_kbspecial; - optional_ioport m_kbrepeat; - optional_ioport m_resetdip; - optional_ioport m_sysconfig; - optional_device<cassette_image_device> m_cassette; - - optional_device<mos6551_device> m_acia1, m_acia2; - optional_device<applefdc_base_device> m_laserudc; - optional_device<iwm_device> m_iicpiwm; - - uint32_t m_flags, m_flags_mask; - int32_t m_a2_cnxx_slot; - uint32_t m_a2_mask; - uint32_t m_a2_set; - int m_a2_speaker_state; - double m_joystick_x1_time; - double m_joystick_y1_time; - double m_joystick_x2_time; - double m_joystick_y2_time; - apple2_memmap_config m_mem_config; - std::unique_ptr<apple2_meminfo[]> m_current_meminfo; - int m_fdc_diskreg; - const uint8_t *m_a2_videoram, *m_a2_videoaux, *m_textgfx_data; - uint32_t m_a2_videomask, m_textgfx_datalen; - uint32_t m_old_a2; - int m_fgcolor; - int m_bgcolor; - int m_flash; - int m_alt_charset_value; - std::unique_ptr<uint16_t[]> m_hires_artifact_map; - std::unique_ptr<uint16_t[]> m_dhires_artifact_map; - bool m_monochrome_dhr; - int m_inh_slot; - int m_reset_flag; - - uint8_t *m_rambase; - - uint8_t *m_rom, *m_slot_ram; - uint32_t m_rom_length, m_slot_length; - - machine_type_t m_machinetype; - - device_a2eauxslot_card_interface *m_auxslotdevice; - - uint16_t m_lastchar, m_strobe; - uint8_t m_transchar; - - READ8_MEMBER(apple2_c0xx_r); - WRITE8_MEMBER(apple2_c0xx_w); - READ8_MEMBER(apple2_c080_r); - WRITE8_MEMBER(apple2_c080_w); - - READ8_MEMBER ( apple2_c00x_r ); - READ8_MEMBER ( apple2_c01x_r ); - READ8_MEMBER ( apple2_c02x_r ); - READ8_MEMBER ( apple2_c03x_r ); - READ8_MEMBER ( apple2_c05x_r ); - READ8_MEMBER ( apple2_c06x_r ); - READ8_MEMBER ( apple2_c07x_r ); - WRITE8_MEMBER ( apple2_c00x_w ); - WRITE8_MEMBER ( apple2_c01x_w ); - WRITE8_MEMBER ( apple2_c02x_w ); - WRITE8_MEMBER ( apple2_c03x_w ); - WRITE8_MEMBER ( apple2_c05x_w ); - WRITE8_MEMBER ( apple2_c07x_w ); - - READ8_MEMBER ( apple2_mainram0000_r ); - READ8_MEMBER ( apple2_mainram0200_r ); - READ8_MEMBER ( apple2_mainram0400_r ); - READ8_MEMBER ( apple2_mainram0800_r ); - READ8_MEMBER ( apple2_mainram2000_r ); - READ8_MEMBER ( apple2_mainram4000_r ); - READ8_MEMBER ( apple2_mainramc000_r ); - READ8_MEMBER ( apple2_mainramd000_r ); - READ8_MEMBER ( apple2_mainrame000_r ); - READ8_MEMBER ( apple2_auxram0000_r ); - READ8_MEMBER ( apple2_auxram0200_r ); - READ8_MEMBER ( apple2_auxram0400_r ); - READ8_MEMBER ( apple2_auxram0800_r ); - READ8_MEMBER ( apple2_auxram2000_r ); - READ8_MEMBER ( apple2_auxram4000_r ); - READ8_MEMBER ( apple2_auxramc000_r ); - READ8_MEMBER ( apple2_auxramd000_r ); - READ8_MEMBER ( apple2_auxrame000_r ); - - WRITE8_MEMBER ( apple2_mainram0000_w ); - WRITE8_MEMBER ( apple2_mainram0200_w ); - WRITE8_MEMBER ( apple2_mainram0400_w ); - WRITE8_MEMBER ( apple2_mainram0800_w ); - WRITE8_MEMBER ( apple2_mainram2000_w ); - WRITE8_MEMBER ( apple2_mainram4000_w ); - WRITE8_MEMBER ( apple2_mainramc000_w ); - WRITE8_MEMBER ( apple2_mainramd000_w ); - WRITE8_MEMBER ( apple2_mainrame000_w ); - WRITE8_MEMBER ( apple2_auxram0000_w ); - WRITE8_MEMBER ( apple2_auxram0200_w ); - WRITE8_MEMBER ( apple2_auxram0400_w ); - WRITE8_MEMBER ( apple2_auxram0800_w ); - WRITE8_MEMBER ( apple2_auxram2000_w ); - WRITE8_MEMBER ( apple2_auxram4000_w ); - WRITE8_MEMBER ( apple2_auxramc000_w ); - WRITE8_MEMBER ( apple2_auxramd000_w ); - WRITE8_MEMBER ( apple2_auxrame000_w ); - - READ8_MEMBER ( apple2_c1xx_r ); - WRITE8_MEMBER ( apple2_c1xx_w ); - READ8_MEMBER ( apple2_c3xx_r ); - WRITE8_MEMBER ( apple2_c3xx_w ); - READ8_MEMBER ( apple2_c4xx_r ); - WRITE8_MEMBER ( apple2_c4xx_w ); - - READ8_MEMBER ( apple2_c800_r ); - WRITE8_MEMBER ( apple2_c800_w ); - READ8_MEMBER ( apple2_ce00_r ); - WRITE8_MEMBER ( apple2_ce00_w ); - - READ8_MEMBER ( apple2_inh_d000_r ); - WRITE8_MEMBER ( apple2_inh_d000_w ); - READ8_MEMBER ( apple2_inh_e000_r ); - WRITE8_MEMBER ( apple2_inh_e000_w ); - - READ8_MEMBER(read_floatingbus); - - READ8_MEMBER(apple2_cfff_r); - WRITE8_MEMBER(apple2_cfff_w); - - void apple2_refresh_delegates(); - int apple2_pressed_specialkey(uint8_t key); - void langcard_touch(offs_t offset); - - read8_delegate read_delegates_master[4]; - write8_delegate write_delegates_master[3]; - write8_delegate write_delegates_0000[2]; - write8_delegate write_delegates_0200[2]; - write8_delegate write_delegates_0400[2]; - write8_delegate write_delegates_0800[2]; - write8_delegate write_delegates_2000[2]; - write8_delegate write_delegates_4000[2]; - write8_delegate write_delegates_c000[2]; - write8_delegate write_delegates_d000[2]; - write8_delegate write_delegates_e000[2]; - read8_delegate read_delegates_0000[2]; - read8_delegate read_delegates_0200[2]; - read8_delegate read_delegates_0400[2]; - read8_delegate read_delegates_0800[2]; - read8_delegate read_delegates_2000[2]; - read8_delegate read_delegates_4000[2]; - read8_delegate read_delegates_c000[2]; - read8_delegate read_delegates_d000[2]; - read8_delegate read_delegates_e000[2]; - read8_delegate rd_c000; - write8_delegate wd_c000; - read8_delegate rd_c080; - write8_delegate wd_c080; - read8_delegate rd_cfff; - write8_delegate wd_cfff; - read8_delegate rd_c800; - write8_delegate wd_c800; - read8_delegate rd_ce00; - write8_delegate wd_ce00; - read8_delegate rd_inh_d000; - write8_delegate wd_inh_d000; - read8_delegate rd_inh_e000; - write8_delegate wd_inh_e000; - DECLARE_MACHINE_START(apple2orig); - DECLARE_MACHINE_START(apple2e); - DECLARE_MACHINE_START(apple2c); - DECLARE_MACHINE_START(apple2cp); - DECLARE_MACHINE_START(tk2000); - DECLARE_MACHINE_START(tk3000); - DECLARE_MACHINE_START(laser128); - DECLARE_MACHINE_START(space84); - DECLARE_MACHINE_START(laba2p); - DECLARE_VIDEO_START(apple2); - DECLARE_PALETTE_INIT(apple2); - DECLARE_VIDEO_START(apple2p); - DECLARE_VIDEO_START(apple2e); - DECLARE_VIDEO_START(apple2c); - uint32_t screen_update_apple2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_DEVICE_CALLBACK_MEMBER(apple2_interrupt); - DECLARE_WRITE_LINE_MEMBER(a2bus_irq_w); - DECLARE_WRITE_LINE_MEMBER(a2bus_nmi_w); - DECLARE_WRITE_LINE_MEMBER(a2bus_inh_w); - DECLARE_READ_LINE_MEMBER(ay3600_shift_r); - DECLARE_READ_LINE_MEMBER(ay3600_control_r); - DECLARE_WRITE_LINE_MEMBER(ay3600_data_ready_w); - DECLARE_WRITE_LINE_MEMBER(ay3600_iie_data_ready_w); - void apple2_update_memory_postload(); - virtual void machine_reset() override; - void apple2_setup_memory(const apple2_memmap_config *config); - void apple2_update_memory(); - inline uint32_t effective_a2(); - uint32_t compute_video_address(int col, int row); - void adjust_begin_and_end_row(const rectangle &cliprect, int *beginrow, int *endrow); - inline void apple2_plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code, - const uint8_t *textgfx_data, uint32_t textgfx_datalen, uint32_t my_a2); - void apple2_text_draw(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int beginrow, int endrow); - void apple2_lores_draw(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int beginrow, int endrow); - void apple2_hires_draw(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int beginrow, int endrow); - void apple2_video_start(const uint8_t *vram, const uint8_t *aux_vram, uint32_t ignored_softswitches, int hires_modulo); - void apple2_setvar(uint32_t val, uint32_t mask); - uint8_t apple2_getfloatingbusvalue(); - int apple2_fdc_has_35(); - int apple2_fdc_has_525(); - void apple2_iwm_setdiskreg(uint8_t data); - void apple2_init_common(); - void apple2eplus_init_common(void *apple2cp_ce00_ram); - int8_t apple2_slotram_r(int slotnum, int offset); - int a2_no_ctrl_reset(); - -private: - // Laser 128EX2 slot 5 Apple Memory Expansion emulation vars - uint8_t m_exp_bankhior; - int m_exp_addrmask; - uint8_t m_exp_regs[0x10]; - std::unique_ptr<uint8_t[]> m_exp_ram; - int m_exp_wptr, m_exp_liveptr; -}; -/*----------- defined in drivers/apple2.c -----------*/ -INPUT_PORTS_EXTERN( apple2ep ); -/*----------- defined in machine/apple2.c -----------*/ -extern const applefdc_interface apple2_fdc_interface; - -#endif // MAME_INCLUDES_APPLE2_H diff --git a/src/mame/includes/apple2gs.h b/src/mame/includes/apple2gs.h deleted file mode 100644 index edce53aad21..00000000000 --- a/src/mame/includes/apple2gs.h +++ /dev/null @@ -1,278 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods,R. Belmont -/***************************************************************************** - * - * includes/apple2gs.h - * - * Apple IIgs - * - ****************************************************************************/ - -#ifndef MAME_INCLUDES_APPLE2GS_H -#define MAME_INCLUDES_APPLE2GS_H - -#define RUN_ADB_MICRO (0) - -#include "includes/apple2.h" -#include "sound/es5503.h" -#include "machine/nvram.h" -#include "cpu/g65816/g65816.h" -#include "cpu/m6502/m5074x.h" -#include "machine/z80scc.h" -#include "emupal.h" - -#define ADBMICRO_TAG "adbmicro" -#define SCC_TAG "scc" -#define RS232A_TAG "printer" -#define RS232B_TAG "modem" - -// IIgs clocks as marked on the schematics -#define APPLE2GS_28M (XTAL(28'636'363)) // IIGS master clock -#define APPLE2GS_14M (APPLE2GS_28M/2) -#define APPLE2GS_7M (APPLE2GS_28M/4) - -// screen dimensions -#define BORDER_LEFT (32) -#define BORDER_RIGHT (32) -#define BORDER_TOP (16) // (plus bottom) - -// these are numbered as seen from the MCU -enum glu_reg_names -{ - GLU_KEY_DATA = 0, // MCU W - GLU_COMMAND, // MCU R - GLU_MOUSEX, // MCU W - GLU_MOUSEY, // MCU W - GLU_KG_STATUS, // MCU R - GLU_ANY_KEY_DOWN, // MCU W - GLU_KEYMOD, // MCU W - GLU_DATA, // MCU W - - GLU_C000, // 816 R - GLU_C010, // 816 RW - GLU_SYSSTAT // 816 R/(limited) W -}; - -enum glu_kg_status -{ - KGS_ANY_KEY_DOWN = 0x01, - KGS_KEYSTROBE = 0x10, - KGS_DATA_FULL = 0x20, - KGS_COMMAND_FULL = 0x40, - KGS_MOUSEX_FULL = 0x80 -}; - -enum apple2gs_clock_mode -{ - CLOCKMODE_IDLE, - CLOCKMODE_TIME, - CLOCKMODE_INTERNALREGS, - CLOCKMODE_BRAM1, - CLOCKMODE_BRAM2 -}; - - -enum adbstate_t -{ - ADBSTATE_IDLE, - ADBSTATE_INCOMMAND, - ADBSTATE_INRESPONSE -}; - -#define IRQ_KBD_SRQ 0x01 -#define IRQ_ADB_DATA 0x02 -#define IRQ_ADB_MOUSE 0x04 -#define IRQ_VGC_SCANLINE 0x08 -#define IRQ_VGC_SECOND 0x10 -#define IRQ_INTEN_QSECOND 0x20 -#define IRQ_INTEN_VBL 0x40 -#define IRQ_DOC 0x80 -#define IRQ_SLOT 0x100 - -void apple2gs_add_irq(running_machine &machine, uint16_t irq_mask); -void apple2gs_remove_irq(running_machine &machine, uint16_t irq_mask); - -class apple2gs_state : public apple2_state -{ -public: - apple2gs_state(const machine_config &mconfig, device_type type, const char *tag) - : apple2_state(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_es5503(*this, "es5503"), - m_fdc(*this, "fdc"), - m_scc(*this, "scc"), - #if RUN_ADB_MICRO - m_adbmicro(*this, ADBMICRO_TAG), - #endif - m_adb_mousex(*this, "adb_mouse_x"), - m_adb_mousey(*this, "adb_mouse_y"), - m_palette(*this, "palette") - { } - - required_device<g65816_device> m_maincpu; - required_device<es5503_device> m_es5503; - required_device<applefdc_base_device> m_fdc; - required_device<z80scc_device> m_scc; - #if RUN_ADB_MICRO - optional_device<m5074x_device> m_adbmicro; - #endif - - required_ioport m_adb_mousex, m_adb_mousey; - required_device<palette_device> m_palette; - - std::unique_ptr<uint8_t[]> m_slowmem; - uint8_t m_newvideo; - uint16_t m_bordercolor; - uint8_t m_vgcint; - uint8_t m_langsel; - uint8_t m_sltromsel; - uint8_t m_cyareg; - uint8_t m_inten; - uint8_t m_intflag; - uint8_t m_shadow; - uint16_t m_pending_irqs; - uint8_t m_mouse_x; - uint8_t m_mouse_y; - int8_t m_mouse_dx; - int8_t m_mouse_dy; - device_t *m_cur_slot6_image; - emu_timer *m_scanline_timer; - emu_timer *m_clock_timer; - emu_timer *m_qsecond_timer; - uint8_t m_clock_data; - uint8_t m_clock_control; - uint8_t m_clock_read; - uint8_t m_clock_reg1; - apple2gs_clock_mode m_clock_mode; - uint32_t m_clock_curtime; - seconds_t m_clock_curtime_interval; - uint8_t m_clock_bram[256]; - #if !RUN_ADB_MICRO - adbstate_t m_adb_state; - uint8_t m_adb_command; - uint8_t m_adb_mode; - uint8_t m_adb_kmstatus; - uint8_t m_adb_latent_result; - int32_t m_adb_command_length; - int32_t m_adb_command_pos; - uint8_t m_adb_command_bytes[8]; - uint8_t m_adb_response_bytes[8]; - uint8_t m_adb_response_length; - int32_t m_adb_response_pos; - uint8_t m_adb_memory[0x100]; - int m_adb_address_keyboard; - int m_adb_address_mouse; - #endif - uint8_t m_sndglu_ctrl; - int m_sndglu_addr; - int m_sndglu_dummy_read; - std::unique_ptr<bitmap_ind16> m_legacy_gfx; - bool m_is_rom3; - uint8_t m_echo_bank; - uint64_t m_last_adb_time; - int m_adb_dtime; - uint32_t m_a2_palette[16]; - uint32_t m_shr_palette[256]; - - READ8_MEMBER( apple2gs_c0xx_r ); - WRITE8_MEMBER( apple2gs_c0xx_w ); - WRITE8_MEMBER( apple2gs_main0400_w ); - WRITE8_MEMBER( apple2gs_aux0400_w ); - WRITE8_MEMBER( apple2gs_main2000_w ); - WRITE8_MEMBER( apple2gs_aux2000_w ); - WRITE8_MEMBER( apple2gs_main4000_w ); - WRITE8_MEMBER( apple2gs_aux4000_w ); - - uint8_t adb_read_datareg(); - uint8_t adb_read_kmstatus(); - - void apple2gs_refresh_delegates(); - - write8_delegate write_delegates_2gs0400[2]; - write8_delegate write_delegates_2gs2000[2]; - write8_delegate write_delegates_2gs4000[2]; - DECLARE_MACHINE_START(apple2gs); - DECLARE_MACHINE_RESET(apple2gs); - DECLARE_VIDEO_START(apple2gs); - DECLARE_PALETTE_INIT(apple2gs); - DECLARE_MACHINE_START(apple2gsr1); - DECLARE_MACHINE_START(apple2gscommon); - uint32_t screen_update_apple2gs(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(apple2gs_clock_tick); - TIMER_CALLBACK_MEMBER(apple2gs_qsecond_tick); - TIMER_CALLBACK_MEMBER(apple2gs_scanline_tick); - DECLARE_WRITE_LINE_MEMBER(a2bus_irq_w); - DECLARE_WRITE_LINE_MEMBER(a2bus_nmi_w); - DECLARE_WRITE_LINE_MEMBER(a2bus_inh_w); - DECLARE_READ8_MEMBER(apple2gs_read_vector); - - // ADB MCU and ADB GLU stuff - #if RUN_ADB_MICRO - uint8_t m_glu_regs[8], m_glu_bus, m_glu_sysstat; - bool m_glu_mcu_read_kgs, m_glu_816_read_dstat, m_glu_mouse_read_stat, m_adb_line; - - uint8_t keyglu_mcu_read(uint8_t offset); - void keyglu_mcu_write(uint8_t offset, uint8_t data); - uint8_t keyglu_816_read(uint8_t offset); - void keyglu_816_write(uint8_t offset, uint8_t data); - - DECLARE_READ8_MEMBER(adbmicro_p0_in); - DECLARE_READ8_MEMBER(adbmicro_p1_in); - DECLARE_READ8_MEMBER(adbmicro_p2_in); - DECLARE_READ8_MEMBER(adbmicro_p3_in); - DECLARE_WRITE8_MEMBER(adbmicro_p0_out); - DECLARE_WRITE8_MEMBER(adbmicro_p1_out); - DECLARE_WRITE8_MEMBER(adbmicro_p2_out); - DECLARE_WRITE8_MEMBER(adbmicro_p3_out); - #endif - void process_clock(); - const char *apple2gs_irq_name(uint16_t irq_mask); - void apple2gs_add_irq(uint16_t irq_mask); - void apple2gs_remove_irq(uint16_t irq_mask); - uint8_t adb_read_memory(uint32_t address); - void adb_write_memory(uint32_t address, uint8_t data); - void adb_set_mode(uint8_t mode); - void adb_set_config(uint8_t b1, uint8_t b2, uint8_t b3); - void adb_post_response(const uint8_t *bytes, size_t length); - void adb_post_response_1(uint8_t b); - void adb_post_response_2(uint8_t b1, uint8_t b2); - void adb_do_command(); - void adb_write_datareg(uint8_t data); - void adb_write_kmstatus(uint8_t data); - uint8_t adb_read_mousedata(); - int8_t seven_bit_diff(uint8_t v1, uint8_t v2); - void adb_check_mouse(); - void apple2gs_set_scanint(uint8_t data); - int apple2gs_get_vpos(); - uint8_t *apple2gs_getslotmem(offs_t address); - uint8_t apple2gs_xxCxxx_r(address_space &space, offs_t address); - void apple2gs_xxCxxx_w(address_space &space, offs_t address, uint8_t data); - void apple2gs_setup_memory(); - - DECLARE_READ8_MEMBER( gssnd_r ); - DECLARE_WRITE8_MEMBER( gssnd_w ); - DECLARE_READ8_MEMBER( apple2gs_00Cxxx_r ); - DECLARE_READ8_MEMBER( apple2gs_01Cxxx_r ); - DECLARE_READ8_MEMBER( apple2gs_E0Cxxx_r ); - DECLARE_READ8_MEMBER( apple2gs_E1Cxxx_r ); - DECLARE_WRITE8_MEMBER( apple2gs_00Cxxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_01Cxxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E0Cxxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E1Cxxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_Exxxxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E004xx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E02xxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E104xx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_E12xxx_w ); - DECLARE_WRITE8_MEMBER( apple2gs_slowmem_w ); - DECLARE_READ8_MEMBER(apple2gs_bank_echo_r); - DECLARE_WRITE_LINE_MEMBER( apple2gs_doc_irq); - DECLARE_READ8_MEMBER(apple2gs_adc_read); - - void apple2gs(machine_config &config); - void apple2gsr1(machine_config &config); - void apple2gs_map(address_map &map); - void vectors_map(address_map &map); -}; - -#endif // MAME_INCLUDES_APPLE2GS_H diff --git a/src/mame/machine/apple2.cpp b/src/mame/machine/apple2.cpp deleted file mode 100644 index b5d78232afa..00000000000 --- a/src/mame/machine/apple2.cpp +++ /dev/null @@ -1,2537 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/*************************************************************************** - - apple2.c - - Machine file to handle emulation of the Apple II series. - -***************************************************************************/ - -#include "emu.h" -#include "includes/apple2.h" - -#include "imagedev/flopdrv.h" -#include "machine/appldriv.h" -#include "machine/applefdc.h" -#include "machine/sonydriv.h" - -#include "debugger.h" - - -#ifdef MAME_DEBUG -#define VERBOSE 1 -#else -#define VERBOSE 0 -#endif /* MAME_DEBUG */ - -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) - -#define PROFILER_C00X PROFILER_USER2 -#define PROFILER_C01X PROFILER_USER2 -#define PROFILER_C08X PROFILER_USER2 -#define PROFILER_A2INT PROFILER_USER2 - -/* ----------------------------------------------------------------------- - * New Apple II memory manager - * ----------------------------------------------------------------------- */ - -READ8_MEMBER(apple2_state::read_floatingbus) -{ - return apple2_getfloatingbusvalue(); -} - - - -void apple2_state::apple2_setup_memory(const apple2_memmap_config *config) -{ - m_mem_config = *config; - m_current_meminfo = nullptr; - apple2_update_memory(); -} - -void apple2_state::langcard_touch(offs_t offset) -{ - uint32_t val, mask; - - //logerror("language card bankswitch read, offset: $c08%0x\n", offset); - - // determine which flags to change - mask = VAR_LCWRITE | VAR_LCRAM | VAR_LCRAM2; - val = 0; - - if (offset & 0x01) - val |= VAR_LCWRITE; - - switch(offset & 0x03) - { - case 0x03: - case 0x00: - val |= VAR_LCRAM; - break; - } - - if ((offset & 0x08) == 0) - val |= VAR_LCRAM2; - - // change the flags - apple2_setvar(val, mask); -} - -void apple2_state::apple2_update_memory() -{ - address_space& space = m_maincpu->space(AS_PROGRAM); - int i, bank; - char rbank[10], wbank[10]; - int full_update = 0; - apple2_meminfo meminfo; - read8_delegate *rh; - write8_delegate *wh; - offs_t begin, end_r, end_w; - uint8_t *rbase, *wbase; - uint32_t offset; - bank_disposition_t bank_disposition; - int wh_nop = 0; - - /* need to build list of current info? */ - if (!m_current_meminfo) - { - for (i = 0; m_mem_config.memmap[i].end; i++) - ; - m_current_meminfo = std::make_unique<apple2_meminfo[]>(i); - full_update = 1; - } - - /* loop through the entire memory map */ - bank = m_mem_config.first_bank; - for (i = 0; m_mem_config.memmap[i].get_meminfo; i++) - { - /* retrieve information on this entry */ - memset(&meminfo, 0, sizeof(meminfo)); - m_mem_config.memmap[i].get_meminfo(machine(),m_mem_config.memmap[i].begin, m_mem_config.memmap[i].end, &meminfo); - - bank_disposition = m_mem_config.memmap[i].bank_disposition; - - /* do we need to memory reading? */ - if (full_update - || (meminfo.read_mem != m_current_meminfo[i].read_mem) - || (meminfo.read_handler != m_current_meminfo[i].read_handler)) - { - rbase = nullptr; - sprintf(rbank,"bank%d",bank); - begin = m_mem_config.memmap[i].begin; - end_r = m_mem_config.memmap[i].end; - rh = nullptr; - - LOG(("apple2_update_memory(): Updating RD {%06X..%06X} [#%02d] --> %08X\n", - begin, end_r, bank, meminfo.read_mem)); - - /* read handling */ - if (meminfo.read_handler) - { - /* handler */ - rh = meminfo.read_handler; - } - else if (meminfo.read_mem == APPLE2_MEM_FLOATING) - { - /* floating RAM */ - rh = &read_delegates_master[0]; - } - else if ((meminfo.read_mem & 0xC0000000) == APPLE2_MEM_AUX) - { - /* auxillary memory */ - assert(m_mem_config.auxmem); - offset = meminfo.read_mem & APPLE2_MEM_MASK; - rbase = &m_mem_config.auxmem[offset]; - } - else if ((meminfo.read_mem & 0xC0000000) == APPLE2_MEM_SLOT) - { - // slots 1-2 - if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0) - { - rh = &read_delegates_master[1]; - } - else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x200) - { // slot 3 - rh = &read_delegates_master[2]; - } - else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) - { // slots 4-7 - rh = &read_delegates_master[3]; - } - else - { - printf("ERROR: Unhandled case for APPLE2_MEM_SLOT write_mem = %x!\n", (meminfo.write_mem & APPLE2_MEM_MASK)); - } - } - else if ((meminfo.read_mem & 0xC0000000) == APPLE2_MEM_ROM) - { - /* ROM */ - offset = meminfo.read_mem & APPLE2_MEM_MASK; - rbase = &m_rom[offset % m_rom_length]; - } - else - { - /* RAM */ - if (end_r >= m_ram->size()) - end_r = m_ram->size() - 1; - offset = meminfo.read_mem & APPLE2_MEM_MASK; - if (end_r >= begin) - rbase = &m_ram->pointer()[offset]; - } - - /* install the actual handlers */ - if (begin <= end_r) { - if (rh) { - space.install_read_handler(begin, end_r, *rh); - } else { - space.install_read_bank(begin, end_r, rbank); - } - } - - /* did we 'go past the end?' */ - if (end_r < m_mem_config.memmap[i].end) - space.nop_read(end_r + 1, m_mem_config.memmap[i].end); - - /* set the memory bank */ - if (rbase) - { - membank(rbank)->set_base(rbase); - } - - /* record the current settings */ - m_current_meminfo[i].read_mem = meminfo.read_mem; - m_current_meminfo[i].read_handler = meminfo.read_handler; - } - - /* do we need to memory writing? */ - if (full_update - || (meminfo.write_mem != m_current_meminfo[i].write_mem) - || (meminfo.write_handler != m_current_meminfo[i].write_handler)) - { - wbase = nullptr; - if (bank_disposition == A2MEM_MONO) - sprintf(wbank,"bank%d",bank); - else if (bank_disposition == A2MEM_DUAL) - sprintf(wbank,"bank%d",bank+1); - begin = m_mem_config.memmap[i].begin; - end_w = m_mem_config.memmap[i].end; - wh = nullptr; - - LOG(("apple2_update_memory(): Updating WR {%06X..%06X} [#%02d] --> %08X\n", - begin, end_w, bank, meminfo.write_mem)); - - /* write handling */ - if (meminfo.write_handler) - { - /* handler */ - wh = meminfo.write_handler; - } - else if ((meminfo.write_mem & 0xC0000000) == APPLE2_MEM_AUX) - { - /* auxillary memory */ - assert(m_mem_config.auxmem); - offset = meminfo.write_mem & APPLE2_MEM_MASK; - wbase = &m_mem_config.auxmem[offset]; - } - else if ((meminfo.write_mem & 0xC0000000) == APPLE2_MEM_SLOT) - { - /* slot RAM/ROM */ - - // slots 1-2 - if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0) - { - wh = &write_delegates_master[0]; - } - else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x200) - { // slot 3 - wh = &write_delegates_master[1]; - } - else if ((meminfo.write_mem & APPLE2_MEM_MASK) == 0x300) - { // slots 4-7 - wh = &write_delegates_master[2]; - } - } - else if ((meminfo.write_mem & 0xC0000000) == APPLE2_MEM_ROM) - { - /* ROM */ - wh_nop = 1; - } - else - { - /* RAM */ - if (end_w >= m_ram->size()) - end_w = m_ram->size() - 1; - offset = meminfo.write_mem & APPLE2_MEM_MASK; - if (end_w >= begin) - wbase = &m_ram->pointer()[offset]; - } - - - /* install the actual handlers */ - if (begin <= end_w) { - if (wh) { - space.install_write_handler(begin, end_w, *wh); - } else { - if (wh_nop) { - space.nop_write(begin, end_w); - } else { - space.install_write_bank(begin, end_w, wbank); - } - } - } - - /* did we 'go past the end?' */ - if (end_w < m_mem_config.memmap[i].end) - space.nop_write(end_w + 1, m_mem_config.memmap[i].end); - - /* set the memory bank */ - if (wbase) - { - membank(wbank)->set_base(wbase); - } - - /* record the current settings */ - m_current_meminfo[i].write_mem = meminfo.write_mem; - m_current_meminfo[i].write_handler = meminfo.write_handler; - } - bank += bank_disposition; - } -} - - - -void apple2_state::apple2_update_memory_postload() -{ - apple2_update_memory(); -} - - - -/* ----------------------------------------------------------------------- - * Apple II memory map - * ----------------------------------------------------------------------- */ - -READ8_MEMBER(apple2_state::apple2_c0xx_r) -{ - if(!machine().side_effects_disabled()) - { - read8_delegate handlers[] = - { - read8_delegate(FUNC(apple2_state::apple2_c00x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c01x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c02x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c03x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c03x_r), this), // not called here, handled elsewhere - read8_delegate(FUNC(apple2_state::apple2_c05x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c06x_r), this), - read8_delegate(FUNC(apple2_state::apple2_c07x_r), this) - }; - - offset &= 0x7F; - - /* normal handler */ - if (offset / 0x10 != 4) - { - return handlers[offset / 0x10](space, offset % 0x10, 0); - } - } - - return 0; -} - - - -WRITE8_MEMBER(apple2_state::apple2_c0xx_w) -{ - write8_delegate handlers[] = - { - write8_delegate(FUNC(apple2_state::apple2_c00x_w), this), - write8_delegate(FUNC(apple2_state::apple2_c01x_w), this), - write8_delegate(FUNC(apple2_state::apple2_c02x_w), this), - write8_delegate(FUNC(apple2_state::apple2_c03x_w), this), - write8_delegate(FUNC(apple2_state::apple2_c03x_w), this), // unused - write8_delegate(FUNC(apple2_state::apple2_c05x_w), this), - write8_delegate(FUNC(apple2_state::apple2_c05x_w), this), // unused - write8_delegate(FUNC(apple2_state::apple2_c07x_w), this) - }; - - offset &= 0x7F; - - /* normal handler */ - if (((offset / 0x10) != 4) && (offset / 0x10) != 6) - { - handlers[offset / 0x10](space, offset % 0x10, data, 0); - } -} - -READ8_MEMBER(apple2_state::apple2_c080_r) -{ - if(!machine().side_effects_disabled()) - { - device_a2bus_card_interface *slotdevice; - int slot; - - offset &= 0x7F; - slot = offset / 0x10; - - if (slot == 0) - { - langcard_touch(offset); - return 0; - } - - /* now identify the device */ - slotdevice = m_a2bus->get_a2bus_card(slot); - - /* and if we can, read from the slot */ - if (slotdevice != nullptr) - { - return slotdevice->read_c0nx(offset % 0x10); - } - } - - return 0; -} - - -WRITE8_MEMBER(apple2_state::apple2_c080_w) -{ - device_a2bus_card_interface *slotdevice; - int slot; - - offset &= 0x7F; - slot = offset / 0x10; - - if (slot == 0) - { - langcard_touch(offset); - return; - } - - /* now identify the device */ - slotdevice = m_a2bus->get_a2bus_card(slot); - - /* and if we can, write to the slot */ - if (slotdevice != nullptr) - { - slotdevice->write_c0nx(offset % 0x10, data); - } -} - -/* returns default CnXX slotram for a slot space */ -int8_t apple2_state::apple2_slotram_r(int slotnum, int offset) -{ - if (m_slot_ram) - { - if (!machine().side_effects_disabled()) - { -// printf("slotram_r: taking cnxx_slot to -1\n"); - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } - - return m_slot_ram[offset]; - } - - // else fall through to floating bus - return apple2_getfloatingbusvalue(); -} - -READ8_MEMBER(apple2_state::apple2_c1xx_r ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = ((offset>>8) & 0xf) + 1; - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - if (slotdevice != nullptr) - { - if ((slotdevice->take_c800()) && (!machine().side_effects_disabled())) - { -// printf("c1xx_r: taking cnxx_slot to %d\n", slotnum); - m_a2_cnxx_slot = slotnum; - apple2_update_memory(); - } - - return slotdevice->read_cnxx(offset&0xff); - } - else - { - return apple2_slotram_r(slotnum, offset); - } - - // else fall through to floating bus - // never executed - //return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_c1xx_w ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = ((offset>>8) & 0xf) + 1; - - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - if (slotdevice != nullptr) - { - slotdevice->write_cnxx(offset&0xff, data); - } - else - { - if (m_slot_ram) - m_slot_ram[offset] = data; - } -} - -READ8_MEMBER(apple2_state::apple2_c3xx_r ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = 3; - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - // is a card installed in this slot? - if (slotdevice != nullptr) - { - if ((slotdevice->take_c800()) && (!machine().side_effects_disabled())) - { -// printf("c3xx_r: taking cnxx_slot to %d\n", slotnum); - m_a2_cnxx_slot = slotnum; - apple2_update_memory(); - } - return slotdevice->read_cnxx(offset&0xff); - } - else - { - return apple2_slotram_r(slotnum, offset); - } - - // else fall through to floating bus - // never executed - //return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_c3xx_w ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = 3; - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - if (slotdevice != nullptr) - { - if ((slotdevice->take_c800()) && (!machine().side_effects_disabled())) - { -// printf("c3xx_w: taking cnxx_slot to %d\n", slotnum); - m_a2_cnxx_slot = slotnum; - apple2_update_memory(); - } - slotdevice->write_cnxx(offset&0xff, data); - } - else - { - if (m_slot_ram) - m_slot_ram[offset] = data; - } -} - -READ8_MEMBER(apple2_state::apple2_c4xx_r ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = ((offset>>8) & 0xf) + 4; - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - // is a card installed in this slot? - if (slotdevice != nullptr) - { - if (slotdevice->take_c800() && (m_a2_cnxx_slot != slotnum) && (!machine().side_effects_disabled())) - { - m_a2_cnxx_slot = slotnum; - apple2_update_memory(); - } - return slotdevice->read_cnxx(offset&0xff); - } - else - { - return apple2_slotram_r(slotnum, offset); - } - - // else fall through to floating bus - // never executed - //return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER ( apple2_state::apple2_c4xx_w ) -{ - int slotnum; - device_a2bus_card_interface *slotdevice; - - slotnum = ((offset>>8) & 0xf) + 4; - slotdevice = m_a2bus->get_a2bus_card(slotnum); - - if (slotdevice != nullptr) - { - if ((slotdevice->take_c800()) && (!machine().side_effects_disabled())) - { -// printf("c4xx_w: taking cnxx_slot to %d\n", slotnum); - m_a2_cnxx_slot = slotnum; - apple2_update_memory(); - } - slotdevice->write_cnxx(offset&0xff, data); - } - else - { - if (m_slot_ram) - m_slot_ram[offset] = data; - } -} - -READ8_MEMBER(apple2_state::apple2_cfff_r) -{ - // debugger guard - if (!machine().side_effects_disabled()) - { -// printf("cfff_r: taking cnxx_slot to -1\n"); - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } - - return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_cfff_w) -{ - if (!machine().side_effects_disabled()) - { -// printf("cfff_w: taking cnxx_slot to -1\n"); - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } -} - -READ8_MEMBER(apple2_state::apple2_c800_r ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - - if (slotdevice != nullptr) - { - return slotdevice->read_c800(offset&0xfff); - } - - return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_c800_w ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - - if (slotdevice != nullptr) - { - slotdevice->write_c800(offset&0xfff, data); - } -} - -READ8_MEMBER(apple2_state::apple2_ce00_r ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - - if (slotdevice != nullptr) - { - return slotdevice->read_c800((offset&0xfff) + 0x600); - } - - return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_ce00_w ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - - if (slotdevice != nullptr) - { - slotdevice->write_c800((offset&0xfff)+0x600, data); - } -} - -READ8_MEMBER(apple2_state::apple2_inh_d000_r ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_inh_slot); - - if (slotdevice != nullptr) - { - return slotdevice->read_inh_rom(offset & 0xfff); - } - - return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_inh_d000_w ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_inh_slot); - - if (slotdevice != nullptr) - { - return slotdevice->write_inh_rom(offset & 0xfff, data); - } -} - -READ8_MEMBER(apple2_state::apple2_inh_e000_r ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_inh_slot); - - if (slotdevice != nullptr) - { - return slotdevice->read_inh_rom((offset & 0x1fff) + 0x1000); - } - - return apple2_getfloatingbusvalue(); -} - -WRITE8_MEMBER(apple2_state::apple2_inh_e000_w ) -{ - device_a2bus_card_interface *slotdevice; - - slotdevice = m_a2bus->get_a2bus_card(m_inh_slot); - - if (slotdevice != nullptr) - { - slotdevice->write_inh_rom((offset & 0x1fff) + 0x1000, data); - } -} - -static void apple2_mem_0000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - meminfo->read_handler = (state->m_flags & VAR_ALTZP) ? &state->read_delegates_0000[0] : &state->read_delegates_0000[1]; - meminfo->write_handler = (state->m_flags & VAR_ALTZP) ? &state->write_delegates_0000[0] : &state->write_delegates_0000[1]; -} - -static void apple2_mem_0200(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - meminfo->read_handler = (state->m_flags & VAR_RAMRD) ? &state->read_delegates_0200[0] : &state->read_delegates_0200[1]; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_0200[0] : &state->write_delegates_0200[1]; -} - -static void apple2_mem_0400(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - if (state->m_flags & VAR_80STORE) - { - meminfo->read_handler = (state->m_flags & VAR_PAGE2) ? &state->read_delegates_0400[0] : &state->read_delegates_0400[1]; - meminfo->write_handler = (state->m_flags & VAR_PAGE2) ? &state->write_delegates_0400[0] : &state->write_delegates_0400[1]; - } - else - { - meminfo->read_handler = (state->m_flags & VAR_RAMRD) ? &state->read_delegates_0400[0] : &state->read_delegates_0400[1]; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_0400[0] : &state->write_delegates_0400[1]; - } -} - -static void apple2_mem_0800(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - meminfo->read_handler = (state->m_flags & VAR_RAMRD) ? &state->read_delegates_0800[0] : &state->read_delegates_0800[1]; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_0800[0] : &state->write_delegates_0800[1]; -} - -static void apple2_mem_2000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - if ((state->m_flags & (VAR_80STORE|VAR_HIRES)) == (VAR_80STORE|VAR_HIRES)) - { - meminfo->read_handler = (state->m_flags & VAR_PAGE2) ? &state->read_delegates_2000[0] : &state->read_delegates_2000[1]; - meminfo->write_handler = (state->m_flags & VAR_PAGE2) ? &state->write_delegates_2000[0] : &state->write_delegates_2000[1]; - } - else - { - meminfo->read_handler = (state->m_flags & VAR_RAMRD) ? &state->read_delegates_2000[0] : &state->read_delegates_2000[1]; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2000[0] : &state->write_delegates_2000[1]; - } -} - -static void apple2_mem_4000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - meminfo->read_handler = (state->m_flags & VAR_RAMRD) ? &state->read_delegates_4000[0] : &state->read_delegates_4000[1]; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_4000[0] : &state->write_delegates_4000[1]; -} - -static void apple2_mem_C000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - meminfo->read_handler = &state->rd_c000; - meminfo->write_handler = &state->wd_c000; -} - -static void apple2_mem_C080(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - meminfo->read_handler = &state->rd_c080; - meminfo->write_handler = &state->wd_c080; -} - -static void tk2000_mem_C100(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - if (state->m_flags & VAR_TK2000RAM) - { - meminfo->read_mem = 0x00C100; - meminfo->write_mem = 0x00C100; - } - else - { - meminfo->read_mem = (begin & 0x3fff) | APPLE2_MEM_ROM; - meminfo->write_mem = 0x00C100; - } -} - -static void apple2_mem_CFFF(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - meminfo->read_handler = &state->rd_cfff; - meminfo->write_handler = &state->wd_cfff; -} - -static void apple2_mem_Cx00(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - if (state->m_flags & VAR_INTCXROM) - { - meminfo->read_mem = (begin & 0x0FFF) | (state->m_flags & VAR_ROMSWITCH ? 0x4000 : 0x0000) | APPLE2_MEM_ROM; - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - else - { - meminfo->read_mem = ((begin & 0x0FFF) - 0x100) | APPLE2_MEM_SLOT; - meminfo->write_mem = ((begin & 0x0FFF) - 0x100) | APPLE2_MEM_SLOT; - } -} - -static void apple2_mem_C300(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - if (((state->m_flags & (VAR_INTCXROM|VAR_SLOTC3ROM)) != VAR_SLOTC3ROM) && !(state->m_flags_mask & VAR_SLOTC3ROM)) - { - meminfo->read_mem = (begin & 0x0FFF) | (state->m_flags & VAR_ROMSWITCH ? 0x4000 : 0x0000) | APPLE2_MEM_ROM; - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - else - { - meminfo->read_mem = ((begin & 0x0FFF) - 0x100) | APPLE2_MEM_SLOT; - meminfo->write_mem = ((begin & 0x0FFF) - 0x100) | APPLE2_MEM_SLOT; - } -} - -static void apple2_mem_C800(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - if ((state->m_flags & VAR_INTCXROM) || (state->m_a2_cnxx_slot == -1)) - { - meminfo->read_mem = (begin & 0x0FFF) | (state->m_flags & VAR_ROMSWITCH ? 0x4000 : 0x0000) | APPLE2_MEM_ROM; - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - else - { - meminfo->read_handler = &state->rd_c800; - meminfo->write_handler = &state->wd_c800; - } -} - -static void apple2_mem_CE00(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - if ((state->m_flags & VAR_ROMSWITCH) && !strcmp(machine.system().name, "apple2cp")) - { - meminfo->read_mem = APPLE2_MEM_AUX; - meminfo->write_mem = APPLE2_MEM_AUX; - } - else - { - if ((state->m_flags & VAR_INTCXROM) || (state->m_a2_cnxx_slot == -1)) - { - meminfo->read_mem = (begin & 0x0FFF) | (state->m_flags & VAR_ROMSWITCH ? 0x4000 : 0x0000) | APPLE2_MEM_ROM; - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - else - { - meminfo->read_handler = &state->rd_ce00; - meminfo->write_handler = &state->wd_ce00; - } - } -} - -static void apple2_mem_D000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - if (state->m_inh_slot == -1) - { - if (state->m_flags & VAR_LCRAM) - { - if (state->m_flags & VAR_LCRAM2) - { - meminfo->read_handler = (state->m_flags & VAR_ALTZP) ? &state->read_delegates_c000[0] : &state->read_delegates_c000[1]; - } - else - { - meminfo->read_handler = (state->m_flags & VAR_ALTZP) ? &state->read_delegates_d000[0] : &state->read_delegates_d000[1]; - } - } - else - { - meminfo->read_mem = (state->m_flags & VAR_ROMSWITCH) ? 0x005000 : 0x001000; - meminfo->read_mem |= APPLE2_MEM_ROM; - } - - if (state->m_flags & VAR_LCWRITE) - { - if (state->m_flags & VAR_LCRAM2) - { - meminfo->write_handler = (state->m_flags & VAR_ALTZP) ? &state->write_delegates_c000[0] : &state->write_delegates_c000[1]; - } - else - { - meminfo->write_handler = (state->m_flags & VAR_ALTZP) ? &state->write_delegates_d000[0] : &state->write_delegates_d000[1]; - } - } - else - { - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - } - else - { - meminfo->read_handler = &state->rd_inh_d000; - meminfo->write_handler = &state->wd_inh_d000; - } -} - -static void apple2_mem_E000(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2_state *state = machine.driver_data<apple2_state>(); - - if (state->m_inh_slot == -1) - { - if (state->m_flags & VAR_LCRAM) - { - meminfo->read_handler = (state->m_flags & VAR_ALTZP) ? &state->read_delegates_e000[0] : &state->read_delegates_e000[1]; - } - else - { - meminfo->read_mem = (state->m_flags & VAR_ROMSWITCH) ? 0x006000 : 0x002000; - meminfo->read_mem |= APPLE2_MEM_ROM; - } - - if (state->m_flags & VAR_LCWRITE) - { - meminfo->write_handler = (state->m_flags & VAR_ALTZP) ? &state->write_delegates_e000[0] : &state->write_delegates_e000[1]; - } - else - { - meminfo->write_mem = APPLE2_MEM_FLOATING; - } - } - else - { - meminfo->read_handler = &state->rd_inh_e000; - meminfo->write_handler = &state->wd_inh_e000; - } -} - - - -static const apple2_memmap_entry apple2_memmap_entries[] = -{ - { 0x0000, 0x01FF, apple2_mem_0000, A2MEM_MONO }, - { 0x0200, 0x03FF, apple2_mem_0200, A2MEM_DUAL }, - { 0x0400, 0x07FF, apple2_mem_0400, A2MEM_DUAL }, - { 0x0800, 0x1FFF, apple2_mem_0800, A2MEM_DUAL }, - { 0x2000, 0x3FFF, apple2_mem_2000, A2MEM_DUAL }, - { 0x4000, 0xBFFF, apple2_mem_4000, A2MEM_DUAL }, - { 0xC000, 0xC07F, apple2_mem_C000, A2MEM_IO }, - { 0xC080, 0xC0FF, apple2_mem_C080, A2MEM_IO }, - { 0xC100, 0xC2FF, apple2_mem_Cx00, A2MEM_MONO }, - { 0xC300, 0xC3FF, apple2_mem_C300, A2MEM_MONO }, - { 0xC400, 0xC7FF, apple2_mem_Cx00, A2MEM_MONO }, - { 0xC800, 0xCDFF, apple2_mem_C800, A2MEM_MONO }, - { 0xCE00, 0xCFFE, apple2_mem_CE00, A2MEM_MONO }, - { 0xCFFF, 0xCFFF, apple2_mem_CFFF, A2MEM_IO }, - { 0xD000, 0xDFFF, apple2_mem_D000, A2MEM_DUAL }, - { 0xE000, 0xFFFF, apple2_mem_E000, A2MEM_DUAL }, - { 0 } -}; - - -static const apple2_memmap_entry tk2000_memmap_entries[] = -{ - { 0x0000, 0x01FF, apple2_mem_0000, A2MEM_MONO }, - { 0x0200, 0x03FF, apple2_mem_0200, A2MEM_DUAL }, - { 0x0400, 0x07FF, apple2_mem_0400, A2MEM_DUAL }, - { 0x0800, 0x1FFF, apple2_mem_0800, A2MEM_DUAL }, - { 0x2000, 0x3FFF, apple2_mem_2000, A2MEM_DUAL }, - { 0x4000, 0xBFFF, apple2_mem_4000, A2MEM_DUAL }, - { 0xC000, 0xC07F, apple2_mem_C000, A2MEM_IO }, - { 0xC080, 0xC0FF, apple2_mem_C080, A2MEM_IO }, - { 0xC100, 0xFFFF, tk2000_mem_C100, A2MEM_DUAL }, - { 0 } -}; - -void apple2_state::apple2_setvar(uint32_t val, uint32_t mask) -{ - LOG(("apple2_setvar(): val=0x%06x mask=0x%06x pc=0x%04x\n", val, mask, - (unsigned int) m_maincpu->pc())); - - assert((val & mask) == val); - - /* apply mask and set */ - val &= m_a2_mask; - val |= m_a2_set; - - /* change the softswitch */ - m_flags &= ~mask; - m_flags |= val; - - // disable flags that don't apply (INTCXROM/SLOTC3ROM on II/II+ for instance) - m_flags &= ~m_flags_mask; - - apple2_update_memory(); -} - - - -/* ----------------------------------------------------------------------- - * Floating bus code - * - * preliminary floating bus video scanner code - look for comments - * with FIX: - * ----------------------------------------------------------------------- */ - -uint8_t apple2_state::apple2_getfloatingbusvalue() -{ - enum - { - // scanner types - kScannerNone = 0, kScannerApple2, kScannerApple2e, - - // scanner constants - kHBurstClock = 53, // clock when Color Burst starts - kHBurstClocks = 4, // clocks per Color Burst duration - kHClock0State = 0x18, // H[543210] = 011000 - kHClocks = 65, // clocks per horizontal scan (including HBL) - kHPEClock = 40, // clock when HPE (horizontal preset enable) goes low - kHPresetClock = 41, // clock when H state presets - kHSyncClock = 49, // clock when HSync starts - kHSyncClocks = 4, // clocks per HSync duration - kNTSCScanLines = 262, // total scan lines including VBL (NTSC) - kNTSCVSyncLine = 224, // line when VSync starts (NTSC) - kPALScanLines = 312, // total scan lines including VBL (PAL) - kPALVSyncLine = 264, // line when VSync starts (PAL) - kVLine0State = 0x100, // V[543210CBA] = 100000000 - kVPresetLine = 256, // line when V state presets - kVSyncLines = 4, // lines per VSync duration - kClocksPerVSync = kHClocks * kNTSCScanLines // FIX: NTSC only? - }; - - // vars - // - int i, Hires, Mixed, Page2, _80Store, ScanLines, /* VSyncLine, ScanCycles,*/ - h_clock, h_state, h_0, h_1, h_2, h_3, h_4, h_5, - v_line, v_state, v_A, v_B, v_C, v_0, v_1, v_2, v_3, v_4, /* v_5, */ - _hires, addend0, addend1, addend2, sum, address; - - // video scanner data - // - i = m_maincpu->total_cycles() % kClocksPerVSync; // cycles into this VSync - - // machine state switches - // - Hires = (m_flags & VAR_HIRES) ? 1 : 0; - Mixed = (m_flags & VAR_MIXED) ? 1 : 0; - Page2 = (m_flags & VAR_PAGE2) ? 1 : 0; - _80Store = (m_flags & VAR_80STORE) ? 1 : 0; - - // calculate video parameters according to display standard - // - ScanLines = 1 ? kNTSCScanLines : kPALScanLines; // FIX: NTSC only? - // VSyncLine = 1 ? kNTSCVSyncLine : kPALVSyncLine; // FIX: NTSC only? - // ScanCycles = ScanLines * kHClocks; - - // calculate horizontal scanning state - // - h_clock = (i + kHPEClock) % kHClocks; // which horizontal scanning clock - h_state = kHClock0State + h_clock; // H state bits - if (h_clock >= kHPresetClock) // check for horizontal preset - { - h_state -= 1; // correct for state preset (two 0 states) - } - h_0 = (h_state >> 0) & 1; // get horizontal state bits - h_1 = (h_state >> 1) & 1; - h_2 = (h_state >> 2) & 1; - h_3 = (h_state >> 3) & 1; - h_4 = (h_state >> 4) & 1; - h_5 = (h_state >> 5) & 1; - - // calculate vertical scanning state - // - v_line = i / kHClocks; // which vertical scanning line - v_state = kVLine0State + v_line; // V state bits - if ((v_line >= kVPresetLine)) // check for previous vertical state preset - { - v_state -= ScanLines; // compensate for preset - } - v_A = (v_state >> 0) & 1; // get vertical state bits - v_B = (v_state >> 1) & 1; - v_C = (v_state >> 2) & 1; - v_0 = (v_state >> 3) & 1; - v_1 = (v_state >> 4) & 1; - v_2 = (v_state >> 5) & 1; - v_3 = (v_state >> 6) & 1; - v_4 = (v_state >> 7) & 1; - //v_5 = (v_state >> 8) & 1; - - // calculate scanning memory address - // - _hires = Hires; - if (Hires && Mixed && (v_4 & v_2)) - { - _hires = 0; // (address is in text memory) - } - - addend0 = 0x68; // 1 1 0 1 - addend1 = (h_5 << 5) | (h_4 << 4) | (h_3 << 3); - addend2 = (v_4 << 6) | (v_3 << 5) | (v_4 << 4) | (v_3 << 3); - sum = (addend0 + addend1 + addend2) & (0x0F << 3); - - address = 0; - address |= h_0 << 0; // a0 - address |= h_1 << 1; // a1 - address |= h_2 << 2; // a2 - address |= sum; // a3 - aa6 - address |= v_0 << 7; // a7 - address |= v_1 << 8; // a8 - address |= v_2 << 9; // a9 - address |= ((_hires) ? v_A : (1 ^ (Page2 & (1 ^ _80Store)))) << 10; // a10 - address |= ((_hires) ? v_B : (Page2 & (1 ^ _80Store))) << 11; // a11 - if (_hires) // hires? - { - // Y: insert hires only address bits - // - address |= v_C << 12; // a12 - address |= (1 ^ (Page2 & (1 ^ _80Store))) << 13; // a13 - address |= (Page2 & (1 ^ _80Store)) << 14; // a14 - } - else - { - // N: text, so no higher address bits unless Apple ][, not Apple //e - // - if ((1) && // Apple ][? // FIX: check for Apple ][? (FB is most useful in old games) - (kHPEClock <= h_clock) && // Y: HBL? - (h_clock <= (kHClocks - 1))) - { - address |= 1 << 12; // Y: a12 (add $1000 to address!) - } - } - - // update VBL' state - // - if (v_4 & v_3) // VBL? - { - //CMemory::mState &= ~CMemory::kVBLBar; // Y: VBL' is false // FIX: MESS? - } - else - { - //CMemory::mState |= CMemory::kVBLBar; // N: VBL' is true // FIX: MESS? - } - - return m_ram->pointer()[address % m_ram->size()]; // FIX: this seems to work, but is it right!? -} - - - -/* ----------------------------------------------------------------------- - * Machine reset - * ----------------------------------------------------------------------- */ - -void apple2_state::machine_reset() -{ - int need_intcxrom; - - m_reset_flag = 0; - m_rambase = m_ram->pointer(); - apple2_refresh_delegates(); - - need_intcxrom = !strcmp(machine().system().name, "apple2c") - || !strcmp(machine().system().name, "apple2c0") - || !strcmp(machine().system().name, "apple2c3") - || !strcmp(machine().system().name, "apple2c4") - || !strcmp(machine().system().name, "prav8c") - || !strcmp(machine().system().name, "apple2cp") - || !strncmp(machine().system().name, "apple2g", 7); - apple2_setvar(need_intcxrom ? VAR_INTCXROM : 0, ~0); - - // IIgs ROM 0 cannot boot unless language card bank 2 is write-enabled (but read ROM) on startup - // Peter Ferrie reports this is also the default on the IIe/IIc at least - apple2_setvar(VAR_LCWRITE|VAR_LCRAM2, VAR_LCWRITE | VAR_LCRAM | VAR_LCRAM2); - - m_a2_speaker_state = 0; - - m_a2_cnxx_slot = -1; // bank in ROM at C800 on reset - - m_joystick_x1_time = m_joystick_y1_time = 0; - m_joystick_x2_time = m_joystick_y2_time = 0; - - memset(m_exp_regs, 0, sizeof(uint8_t) * 0x10); - m_exp_wptr = m_exp_liveptr = 0; - -} - -int apple2_state::a2_no_ctrl_reset() -{ - return ((m_kbrepeat.found() && !m_resetdip.found()) || - (m_resetdip.found() && !m_resetdip->read())); -} - -/* ----------------------------------------------------------------------- - * Apple II interrupt; used to force partial updates - * ----------------------------------------------------------------------- */ - -TIMER_DEVICE_CALLBACK_MEMBER(apple2_state::apple2_interrupt) -{ - int scanline = param; - - if((scanline % 8) == 0) - m_screen->update_partial(m_screen->vpos()); - if ((m_kbspecial->read() & 0x80) && - (a2_no_ctrl_reset() || (m_kbspecial->read() & 0x08))) - { - if (!m_reset_flag) - { - m_reset_flag = 1; - /* using PULSE_LINE does not allow us to press and hold key */ - m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - } - return; - } - - if (m_reset_flag) - { - m_reset_flag = 0; - m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - machine().schedule_soft_reset(); - } -} - - - -/*************************************************************************** - apple2_mainramxx00_r - apple2_mainramxx00_w - apple2_auxramxx00_r - apple2_auxramxx00_w -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_mainram0000_r ) -{ - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainram0200_r ) -{ - offset += 0x200; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainram0400_r ) -{ - offset += 0x400; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainram0800_r ) -{ - offset += 0x800; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainram2000_r ) -{ - offset += 0x2000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainram4000_r ) -{ - offset += 0x4000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainramc000_r ) -{ - offset += 0xc000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainramd000_r ) -{ - offset += 0xd000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_mainrame000_r ) -{ - offset += 0xe000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram0000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x10000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram0200_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0x200); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x10200; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram0400_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0x400); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x10400; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram0800_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0x800); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x10800; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram2000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0x2000); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x12000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxram4000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0x4000); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x14000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxramc000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0xc000); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x1c000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxramd000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0xd000); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x1d000; - return m_rambase[offset]; -} - -READ8_MEMBER ( apple2_state::apple2_auxrame000_r ) -{ - if (m_auxslotdevice) - { - return m_auxslotdevice->read_auxram(offset+0xe000); - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return 0xff; - } - - offset += 0x1e000; - return m_rambase[offset]; -} - - -WRITE8_MEMBER ( apple2_state::apple2_mainram0000_w ) -{ - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainram0200_w ) -{ - offset += 0x200; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainram0400_w ) -{ - offset += 0x400; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainram0800_w ) -{ - offset += 0x800; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainram2000_w ) -{ - offset += 0x2000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainram4000_w ) -{ - offset += 0x4000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainramc000_w ) -{ - offset += 0xc000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainramd000_w ) -{ - offset += 0xd000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_mainrame000_w ) -{ - offset += 0xe000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram0000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x10000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram0200_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0x200, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x10200; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram0400_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0x400, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x10400; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram0800_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0x800, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x10800; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram2000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0x2000, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x12000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxram4000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0x4000, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x14000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxramc000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0xc000, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x1c000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxramd000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0xd000, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x1d000; - m_rambase[offset] = data; -} - -WRITE8_MEMBER ( apple2_state::apple2_auxrame000_w ) -{ - if (m_auxslotdevice) - { - m_auxslotdevice->write_auxram(offset+0xe000, data); - return; - } - else if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - return; - } - - offset += 0x1e000; - m_rambase[offset] = data; -} - -/*************************************************************************** - apple2_c00x_r -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_c00x_r ) -{ - uint8_t result = 0; - - if(!machine().side_effects_disabled()) - { - /* Read the keyboard data and strobe */ - g_profiler.start(PROFILER_C00X); - result = m_transchar | m_strobe; - g_profiler.stop(); - } - - - - return result; -} - - - -/*************************************************************************** - apple2_c00x_w - - C000 80STOREOFF - C001 80STOREON - use 80-column memory mapping - C002 RAMRDOFF - C003 RAMRDON - read from aux 48k - C004 RAMWRTOFF - C005 RAMWRTON - write to aux 48k - C006 INTCXROMOFF - C007 INTCXROMON - C008 ALTZPOFF - C009 ALTZPON - use aux ZP, stack and language card area - C00A SLOTC3ROMOFF - C00B SLOTC3ROMON - use external slot 3 ROM - C00C 80COLOFF - C00D 80COLON - use 80-column display mode - C00E ALTCHARSETOFF - C00F ALTCHARSETON - use alt character set -***************************************************************************/ - -WRITE8_MEMBER ( apple2_state::apple2_c00x_w ) -{ - uint32_t mask; - - mask = 1 << (offset / 2); - apple2_setvar((offset & 1) ? mask : 0, mask); -} - - - -/*************************************************************************** - apple2_c01x_r -***************************************************************************/ - -READ8_MEMBER( apple2_state::apple2_c01x_r ) -{ - uint8_t result = apple2_getfloatingbusvalue() & 0x7F; - - if(!machine().side_effects_disabled()) - { - g_profiler.start(PROFILER_C01X); - - LOG(("a2 softswitch_r: %04x\n", offset + 0xc010)); - switch (offset) - { - case 0x00: result |= m_transchar | m_strobe; m_strobe = 0; break; - case 0x01: result |= (m_flags & VAR_LCRAM2) ? 0x80 : 0x00; break; - case 0x02: result |= (m_flags & VAR_LCRAM) ? 0x80 : 0x00; break; - case 0x03: result |= (m_flags & VAR_RAMRD) ? 0x80 : 0x00; break; - case 0x04: result |= (m_flags & VAR_RAMWRT) ? 0x80 : 0x00; break; - case 0x05: result |= (m_flags & VAR_INTCXROM) ? 0x80 : 0x00; break; - case 0x06: result |= (m_flags & VAR_ALTZP) ? 0x80 : 0x00; break; - case 0x07: result |= (m_flags & VAR_SLOTC3ROM) ? 0x80 : 0x00; break; - case 0x08: result |= (m_flags & VAR_80STORE) ? 0x80 : 0x00; break; - case 0x09: result |= !m_screen->vblank() ? 0x80 : 0x00; break; - case 0x0A: result |= (m_flags & VAR_TEXT) ? 0x80 : 0x00; break; - case 0x0B: result |= (m_flags & VAR_MIXED) ? 0x80 : 0x00; break; - case 0x0C: result |= (m_flags & VAR_PAGE2) ? 0x80 : 0x00; break; - case 0x0D: result |= (m_flags & VAR_HIRES) ? 0x80 : 0x00; break; - case 0x0E: result |= (m_flags & VAR_ALTCHARSET) ? 0x80 : 0x00; break; - case 0x0F: result |= (m_flags & VAR_80COL) ? 0x80 : 0x00; break; - } - - g_profiler.stop(); - } - - return result; -} - - - -/*************************************************************************** - apple2_c01x_w -***************************************************************************/ - -WRITE8_MEMBER( apple2_state::apple2_c01x_w ) -{ - /* Clear the keyboard strobe */ - g_profiler.start(PROFILER_C01X); - m_strobe = 0; - g_profiler.stop(); -} - - - -/*************************************************************************** - apple2_c02x_r -***************************************************************************/ - -READ8_MEMBER( apple2_state::apple2_c02x_r ) -{ - if(!machine().side_effects_disabled()) - { - apple2_c02x_w(space, offset, 0, 0); - } - return apple2_getfloatingbusvalue(); -} - - - -/*************************************************************************** - apple2_c02x_w -***************************************************************************/ - -WRITE8_MEMBER( apple2_state::apple2_c02x_w ) -{ - switch(offset) - { - case 0x08: - apple2_setvar((m_flags & VAR_ROMSWITCH) ^ VAR_ROMSWITCH, VAR_ROMSWITCH); - break; - } -} - - - -/*************************************************************************** - apple2_c03x_r -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_c03x_r ) -{ - if(!machine().side_effects_disabled()) - { - if (!offset) - { - m_a2_speaker_state ^= 1; - m_speaker->level_w(m_a2_speaker_state); - } - } - return apple2_getfloatingbusvalue(); -} - - - -/*************************************************************************** - apple2_c03x_w -***************************************************************************/ - -WRITE8_MEMBER ( apple2_state::apple2_c03x_w ) -{ - apple2_c03x_r(space, offset, 0); -} - - - -/*************************************************************************** - apple2_c05x_r -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_c05x_r ) -{ - if(!machine().side_effects_disabled()) - { - uint32_t mask; - - if (m_machinetype == TK2000) - { - if (offset == 0xa) // RAM - { - apple2_setvar(VAR_TK2000RAM, ~0); - } - else if (offset == 0xb) // ROM - { - apple2_setvar(0, ~VAR_TK2000RAM); - } - } - - /* ANx has reverse SET logic */ - if (offset >= 8) - { - offset ^= 1; - } - - mask = 0x100 << (offset / 2); - apple2_setvar((offset & 1) ? mask : 0, mask); - } - return apple2_getfloatingbusvalue(); -} - - - -/*************************************************************************** - apple2_c05x_w -***************************************************************************/ - -WRITE8_MEMBER ( apple2_state::apple2_c05x_w ) -{ - apple2_c05x_r(space, offset, 0); -} - - - -/*************************************************************************** - apple2_c06x_r -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_c06x_r ) -{ - int result = 0; - if(!machine().side_effects_disabled()) - { - switch (offset & 0x0F) - { - case 0x00: - /* Cassette input */ - { - if (m_cassette) - { - result = m_cassette->input() > 0.0 ? 0x80 : 0; - } - else - { - result = 0; - } - } - break; - case 0x01: - /* Open-Apple/Joystick button 0 */ - result = apple2_pressed_specialkey(0x10); - break; - case 0x02: - /* Closed-Apple/Joystick button 1 */ - result = apple2_pressed_specialkey(0x20); - break; - case 0x03: - /* Joystick button 2. Later revision motherboards connected this to SHIFT also */ - result = apple2_pressed_specialkey(0x40); - break; - case 0x04: - /* X Joystick 1 axis */ - result = machine().time().as_double() < m_joystick_x1_time; - break; - case 0x05: - /* Y Joystick 1 axis */ - result = machine().time().as_double() < m_joystick_y1_time; - break; - case 0x06: - /* X Joystick 2 axis */ - result = machine().time().as_double() < m_joystick_x2_time; - break; - case 0x07: - /* Y Joystick 2 axis */ - result = machine().time().as_double() < m_joystick_y2_time; - break; - default: - /* c060 Empty Cassette head read - * and any other non joystick c06 port returns this according to applewin - */ - return apple2_getfloatingbusvalue(); - } - } - return result ? 0x80 : 0x00; -} - - - -/*************************************************************************** - apple2_c07x_r -***************************************************************************/ - -READ8_MEMBER ( apple2_state::apple2_c07x_r ) -{ - if(!machine().side_effects_disabled()) - { - double x_calibration = attotime::from_usec(12).as_double(); - double y_calibration = attotime::from_usec(13).as_double(); - - if (offset == 0) - { - m_joystick_x1_time = machine().time().as_double() + x_calibration * m_joy1x->read(); - m_joystick_y1_time = machine().time().as_double() + y_calibration * m_joy1y->read(); - m_joystick_x2_time = machine().time().as_double() + x_calibration * m_joy2x->read(); - m_joystick_y2_time = machine().time().as_double() + y_calibration * m_joy2y->read(); - } - } - return 0; -} - - - -/*************************************************************************** - apple2_c07x_w -***************************************************************************/ - -WRITE8_MEMBER ( apple2_state::apple2_c07x_w ) -{ - // this a machine with an aux slot? - if (m_auxslotdevice) - { - m_auxslotdevice->write_c07x(space, offset&0xf, data); - } - - // AE RamWorks manual indicates that even if the auxslot card sees the c07x write, - // so does the motherboard and it will trigger the paddles. So always call this. - apple2_c07x_r(space, offset, 0); -} - - - -/* ----------------------------------------------------------------------- - * Floppy disk controller - * ----------------------------------------------------------------------- */ - - -int apple2_state::apple2_fdc_has_35() -{ - return (floppy_get_count(machine())); // - apple525_get_count(machine)) > 0; -} - -int apple2_state::apple2_fdc_has_525() -{ - return 1; //apple525_get_count(machine) > 0; -} - -static void apple2_fdc_set_lines(device_t *device, uint8_t lines) -{ - apple2_state *state = device->machine().driver_data<apple2_state>(); - if (state->m_fdc_diskreg & 0x40) - { - if (state->apple2_fdc_has_35()) - { - /* slot 5: 3.5" disks */ - sony_set_lines(device,lines); - } - } - else - { - if (state->apple2_fdc_has_525()) - { - /* slot 6: 5.25" disks */ - apple525_set_lines(device,lines); - } - } -} - - - -static void apple2_fdc_set_enable_lines(device_t *device,int enable_mask) -{ - apple2_state *state = device->machine().driver_data<apple2_state>(); - int slot5_enable_mask = 0; - int slot6_enable_mask = 0; - - if (state->m_fdc_diskreg & 0x40) - slot5_enable_mask = enable_mask; - else - slot6_enable_mask = enable_mask; - - if (state->apple2_fdc_has_35()) - { - /* set the 3.5" enable lines */ - sony_set_enable_lines(device,slot5_enable_mask); - } - - if (state->apple2_fdc_has_525()) - { - /* set the 5.25" enable lines */ - apple525_set_enable_lines(device,slot6_enable_mask); - } -} - - - -static uint8_t apple2_fdc_read_data(device_t *device) -{ - apple2_state *state = device->machine().driver_data<apple2_state>(); - uint8_t result = 0x00; - - if (state->m_fdc_diskreg & 0x40) - { - if (state->apple2_fdc_has_35()) - { - /* slot 5: 3.5" disks */ - result = sony_read_data(device); - } - } - else - { - if (state->apple2_fdc_has_525()) - { - /* slot 6: 5.25" disks */ - result = apple525_read_data(device); - } - } - return result; -} - - - -static void apple2_fdc_write_data(device_t *device, uint8_t data) -{ - apple2_state *state = device->machine().driver_data<apple2_state>(); - if (state->m_fdc_diskreg & 0x40) - { - if (state->apple2_fdc_has_35()) - { - /* slot 5: 3.5" disks */ - sony_write_data(device,data); - } - } - else - { - if (state->apple2_fdc_has_525()) - { - /* slot 6: 5.25" disks */ - apple525_write_data(device,data); - } - } -} - - - -static int apple2_fdc_read_status(device_t *device) -{ - apple2_state *state = device->machine().driver_data<apple2_state>(); - int result = 0; - - if (state->m_fdc_diskreg & 0x40) - { - if (state->apple2_fdc_has_35()) - { - /* slot 5: 3.5" disks */ - result = sony_read_status(device); - } - } - else - { - if (state->apple2_fdc_has_525()) - { - /* slot 6: 5.25" disks */ - result = apple525_read_status(device); - } - } - return result; -} - - -void apple2_state::apple2_iwm_setdiskreg(uint8_t data) -{ - m_fdc_diskreg = data & 0xC0; - if (apple2_fdc_has_35()) - sony_set_sel_line(m_iicpiwm, m_fdc_diskreg & 0x80); -} - - -const applefdc_interface apple2_fdc_interface = -{ - apple2_fdc_set_lines, /* set_lines */ - apple2_fdc_set_enable_lines, /* set_enable_lines */ - - apple2_fdc_read_data, /* read_data */ - apple2_fdc_write_data, /* write_data */ - apple2_fdc_read_status /* read_status */ -}; - - - -/* ----------------------------------------------------------------------- - * Driver init - * ----------------------------------------------------------------------- */ - -void apple2_state::apple2_init_common() -{ - m_inh_slot = -1; - m_flags = 0; - m_fdc_diskreg = 0; - - // do these lookups once at startup - m_rom = memregion("maincpu")->base(); - m_rom_length = memregion("maincpu")->bytes() & ~0xFFF; - m_slot_length = memregion("maincpu")->bytes() - m_rom_length; - m_slot_ram = (m_slot_length > 0) ? &m_rom[m_rom_length] : nullptr; - - m_auxslotdevice = nullptr; - if (m_machinetype == APPLE_IIE || m_machinetype == TK3000) - { - m_auxslotdevice = m_a2eauxslot->get_a2eauxslot_card(); - } - - /* state save registers */ - save_item(NAME(m_flags)); - machine().save().register_postload(save_prepost_delegate(FUNC(apple2_state::apple2_update_memory_postload), this)); - - /* --------------------------------------------- * - * set up the softswitch mask/set * - * --------------------------------------------- */ - m_a2_mask = ~0; - m_a2_set = 0; - - /* disable VAR_ROMSWITCH if the ROM is only 16k */ - if (memregion("maincpu")->bytes() < 0x8000) - m_a2_mask &= ~VAR_ROMSWITCH; - - if (m_ram->size() <= 64*1024) - m_a2_mask &= ~(VAR_RAMRD | VAR_RAMWRT | VAR_80STORE | VAR_ALTZP | VAR_80COL); - - apple2_refresh_delegates(); -} - -void apple2_state::apple2eplus_init_common(void *apple2cp_ce00_ram) -{ - apple2_memmap_config mem_cfg; - - m_flags_mask = 0; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)apple2cp_ce00_ram; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,apple2c) -{ - m_machinetype = APPLE_IIC; - - apple2eplus_init_common((void *)nullptr); -} - -MACHINE_START_MEMBER(apple2_state,tk3000) -{ - m_machinetype = TK3000; // enhanced IIe clone with Z80 keyboard scanner subcpu - - apple2eplus_init_common((void *)nullptr); -} - -MACHINE_START_MEMBER(apple2_state,apple2cp) -{ - void *apple2cp_ce00_ram; - - /* there appears to be some hidden RAM that is swapped in on the Apple - * IIc plus; I have not found any official documentation but the BIOS - * clearly uses this area as writeable memory */ - apple2cp_ce00_ram = auto_alloc_array(machine(), uint8_t, 0x200); - memset(apple2cp_ce00_ram, 0, sizeof(uint8_t) * 0x200); - - m_machinetype = APPLE_IICPLUS; - - apple2eplus_init_common(apple2cp_ce00_ram); -} - -MACHINE_START_MEMBER(apple2_state,apple2e) -{ - apple2_memmap_config mem_cfg; - - m_flags_mask = 0; - - m_machinetype = APPLE_IIE; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)nullptr; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,laser128) -{ - apple2_memmap_config mem_cfg; - - m_flags_mask = 0; - m_machinetype = LASER128; - - apple2_init_common(); - - // 1 MB of expansion RAM in slot 5 - m_exp_ram = std::make_unique<uint8_t[]>(1024*1024); - memset(m_exp_ram.get(), 0xff, 1024*1024); - - m_exp_bankhior = 0xf0; - m_exp_addrmask = 0xfffff; - - // save memory expansion vars - save_item(NAME(m_exp_regs)); - save_item(NAME(m_exp_wptr)); - save_item(NAME(m_exp_liveptr)); - save_item(NAME(m_exp_bankhior)); - save_item(NAME(m_exp_addrmask)); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)nullptr; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,apple2orig) -{ - apple2_memmap_config mem_cfg; - void *apple2cp_ce00_ram = nullptr; - - // II and II+ have no internal ROM or internal slot 3 h/w, so don't allow these states - m_flags_mask = VAR_INTCXROM|VAR_SLOTC3ROM; - - m_machinetype = APPLE_II; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)apple2cp_ce00_ram; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,space84) -{ - apple2_memmap_config mem_cfg; - void *apple2cp_ce00_ram = nullptr; - - // II and II+ have no internal ROM or internal slot 3 h/w, so don't allow these states - m_flags_mask = VAR_INTCXROM|VAR_SLOTC3ROM; - - m_machinetype = SPACE84; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)apple2cp_ce00_ram; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,laba2p) -{ - apple2_memmap_config mem_cfg; - void *apple2cp_ce00_ram = nullptr; - - // II and II+ have no internal ROM or internal slot 3 h/w, so don't allow these states - m_flags_mask = VAR_INTCXROM|VAR_SLOTC3ROM; - - m_machinetype = LABA2P; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = apple2_memmap_entries; - mem_cfg.auxmem = (uint8_t*)apple2cp_ce00_ram; - apple2_setup_memory(&mem_cfg); -} - -MACHINE_START_MEMBER(apple2_state,tk2000) -{ - apple2_memmap_config mem_cfg; - - // II and II+ have no internal ROM or internal slot 3 h/w, so don't allow these states - m_flags_mask = VAR_INTCXROM|VAR_SLOTC3ROM; - - m_machinetype = TK2000; - - apple2_init_common(); - - /* setup memory */ - memset(&mem_cfg, 0, sizeof(mem_cfg)); - mem_cfg.first_bank = 1; - mem_cfg.memmap = tk2000_memmap_entries; - mem_cfg.auxmem = (uint8_t*)nullptr; - apple2_setup_memory(&mem_cfg); -} - -int apple2_state::apple2_pressed_specialkey(uint8_t key) -{ - return (m_kbspecial.read_safe(0) & key) - || (m_joybuttons.read_safe(0) & key); -} - -void apple2_state::apple2_refresh_delegates() -{ - read_delegates_master[0] = read8_delegate(FUNC(apple2_state::read_floatingbus), this); - read_delegates_master[1] = read8_delegate(FUNC(apple2_state::apple2_c1xx_r), this); - read_delegates_master[2] = read8_delegate(FUNC(apple2_state::apple2_c3xx_r), this); - read_delegates_master[3] = read8_delegate(FUNC(apple2_state::apple2_c4xx_r), this); - write_delegates_master[0] = write8_delegate(FUNC(apple2_state::apple2_c1xx_w), this); - write_delegates_master[1] = write8_delegate(FUNC(apple2_state::apple2_c3xx_w), this); - write_delegates_master[2] = write8_delegate(FUNC(apple2_state::apple2_c4xx_w), this); - - rd_c000 = read8_delegate(FUNC(apple2_state::apple2_c0xx_r), this); - wd_c000 = write8_delegate(FUNC(apple2_state::apple2_c0xx_w), this); - - rd_c080 = read8_delegate(FUNC(apple2_state::apple2_c080_r), this); - wd_c080 = write8_delegate(FUNC(apple2_state::apple2_c080_w), this); - - rd_cfff = read8_delegate(FUNC(apple2_state::apple2_cfff_r), this); - wd_cfff = write8_delegate(FUNC(apple2_state::apple2_cfff_w), this); - - rd_c800 = read8_delegate(FUNC(apple2_state::apple2_c800_r), this); - wd_c800 = write8_delegate(FUNC(apple2_state::apple2_c800_w), this); - - rd_ce00 = read8_delegate(FUNC(apple2_state::apple2_ce00_r), this); - wd_ce00 = write8_delegate(FUNC(apple2_state::apple2_ce00_w), this); - - rd_inh_d000 = read8_delegate(FUNC(apple2_state::apple2_inh_d000_r), this); - wd_inh_d000 = write8_delegate(FUNC(apple2_state::apple2_inh_d000_w), this); - - rd_inh_e000 = read8_delegate(FUNC(apple2_state::apple2_inh_e000_r), this); - wd_inh_e000 = write8_delegate(FUNC(apple2_state::apple2_inh_e000_w), this); - - read_delegates_0000[0] = read8_delegate(FUNC(apple2_state::apple2_auxram0000_r), this); - read_delegates_0000[1] = read8_delegate(FUNC(apple2_state::apple2_mainram0000_r), this); - read_delegates_0200[0] = read8_delegate(FUNC(apple2_state::apple2_auxram0200_r), this); - read_delegates_0200[1] = read8_delegate(FUNC(apple2_state::apple2_mainram0200_r), this); - read_delegates_0400[0] = read8_delegate(FUNC(apple2_state::apple2_auxram0400_r), this); - read_delegates_0400[1] = read8_delegate(FUNC(apple2_state::apple2_mainram0400_r), this); - read_delegates_0800[0] = read8_delegate(FUNC(apple2_state::apple2_auxram0800_r), this); - read_delegates_0800[1] = read8_delegate(FUNC(apple2_state::apple2_mainram0800_r), this); - read_delegates_2000[0] = read8_delegate(FUNC(apple2_state::apple2_auxram2000_r), this); - read_delegates_2000[1] = read8_delegate(FUNC(apple2_state::apple2_mainram2000_r), this); - read_delegates_4000[0] = read8_delegate(FUNC(apple2_state::apple2_auxram4000_r), this); - read_delegates_4000[1] = read8_delegate(FUNC(apple2_state::apple2_mainram4000_r), this); - read_delegates_c000[0] = read8_delegate(FUNC(apple2_state::apple2_auxramc000_r), this); - read_delegates_c000[1] = read8_delegate(FUNC(apple2_state::apple2_mainramc000_r), this); - read_delegates_d000[0] = read8_delegate(FUNC(apple2_state::apple2_auxramd000_r), this); - read_delegates_d000[1] = read8_delegate(FUNC(apple2_state::apple2_mainramd000_r), this); - read_delegates_e000[0] = read8_delegate(FUNC(apple2_state::apple2_auxrame000_r), this); - read_delegates_e000[1] = read8_delegate(FUNC(apple2_state::apple2_mainrame000_r), this); - - write_delegates_0000[0] = write8_delegate(FUNC(apple2_state::apple2_auxram0000_w), this); - write_delegates_0000[1] = write8_delegate(FUNC(apple2_state::apple2_mainram0000_w), this); - write_delegates_0200[0] = write8_delegate(FUNC(apple2_state::apple2_auxram0200_w), this); - write_delegates_0200[1] = write8_delegate(FUNC(apple2_state::apple2_mainram0200_w), this); - write_delegates_0400[0] = write8_delegate(FUNC(apple2_state::apple2_auxram0400_w), this); - write_delegates_0400[1] = write8_delegate(FUNC(apple2_state::apple2_mainram0400_w), this); - write_delegates_0800[0] = write8_delegate(FUNC(apple2_state::apple2_auxram0800_w), this); - write_delegates_0800[1] = write8_delegate(FUNC(apple2_state::apple2_mainram0800_w), this); - write_delegates_2000[0] = write8_delegate(FUNC(apple2_state::apple2_auxram2000_w), this); - write_delegates_2000[1] = write8_delegate(FUNC(apple2_state::apple2_mainram2000_w), this); - write_delegates_4000[0] = write8_delegate(FUNC(apple2_state::apple2_auxram4000_w), this); - write_delegates_4000[1] = write8_delegate(FUNC(apple2_state::apple2_mainram4000_w), this); - write_delegates_c000[0] = write8_delegate(FUNC(apple2_state::apple2_auxramc000_w), this); - write_delegates_c000[1] = write8_delegate(FUNC(apple2_state::apple2_mainramc000_w), this); - write_delegates_d000[0] = write8_delegate(FUNC(apple2_state::apple2_auxramd000_w), this); - write_delegates_d000[1] = write8_delegate(FUNC(apple2_state::apple2_mainramd000_w), this); - write_delegates_e000[0] = write8_delegate(FUNC(apple2_state::apple2_auxrame000_w), this); - write_delegates_e000[1] = write8_delegate(FUNC(apple2_state::apple2_mainrame000_w), this); -} - -READ_LINE_MEMBER(apple2_state::ay3600_shift_r) -{ - // either shift key - if (m_kbspecial->read() & 0x06) - { - return ASSERT_LINE; - } - - return CLEAR_LINE; -} - -READ_LINE_MEMBER(apple2_state::ay3600_control_r) -{ - if (m_kbspecial->read() & 0x08) - { - return ASSERT_LINE; - } - - return CLEAR_LINE; -} - -static const uint8_t a2_key_remap[0x32][4] = -{ -/* norm shft ctrl both */ - { 0x33,0x23,0x33,0x23 }, /* 3 # 00 */ - { 0x34,0x24,0x34,0x24 }, /* 4 $ 01 */ - { 0x35,0x25,0x35,0x25 }, /* 5 % 02 */ - { 0x36,0x5e,0x35,0x53 }, /* 6 ^ 03 */ - { 0x37,0x26,0x37,0x26 }, /* 7 & 04 */ - { 0x38,0x2a,0x38,0x2a }, /* 8 * 05 */ - { 0x39,0x28,0x39,0x28 }, /* 9 ( 06 */ - { 0x30,0x29,0x30,0x29 }, /* 0 ) 07 */ - { 0x3b,0x3a,0x3b,0x3a }, /* ; : 08 */ - { 0x2d,0x5f,0x2d,0x1f }, /* - _ 09 */ - { 0x51,0x51,0x11,0x11 }, /* q Q 0a */ - { 0x57,0x57,0x17,0x17 }, /* w W 0b */ - { 0x45,0x45,0x05,0x05 }, /* e E 0c */ - { 0x52,0x52,0x12,0x12 }, /* r R 0d */ - { 0x54,0x54,0x14,0x14 }, /* t T 0e */ - { 0x59,0x59,0x19,0x19 }, /* y Y 0f */ - { 0x55,0x55,0x15,0x15 }, /* u U 10 */ - { 0x49,0x49,0x09,0x09 }, /* i I 11 */ - { 0x4f,0x4f,0x0f,0x0f }, /* o O 12 */ - { 0x50,0x50,0x10,0x10 }, /* p P 13 */ - { 0x44,0x44,0x04,0x04 }, /* d D 14 */ - { 0x46,0x46,0x06,0x06 }, /* f F 15 */ - { 0x47,0x47,0x07,0x07 }, /* g G 16 */ - { 0x48,0x48,0x08,0x08 }, /* h H 17 */ - { 0x4a,0x4a,0x0a,0x0a }, /* j J 18 */ - { 0x4b,0x4b,0x0b,0x0b }, /* k K 19 */ - { 0x4c,0x4c,0x0c,0x0c }, /* l L 1a */ - { 0x3d,0x2b,0x3d,0x2b }, /* = + 1b */ - { 0x08,0x08,0x08,0x08 }, /* Left 1c */ - { 0x15,0x15,0x15,0x15 }, /* Right 1d */ - { 0x5a,0x5a,0x1a,0x1a }, /* z Z 1e */ - { 0x58,0x58,0x18,0x18 }, /* x X 1f */ - { 0x43,0x43,0x03,0x03 }, /* c C 20 */ - { 0x56,0x56,0x16,0x16 }, /* v V 21 */ - { 0x42,0x42,0x02,0x02 }, /* b B 22 */ - { 0x4e,0x4e,0x0e,0x0e }, /* n N 23 */ - { 0x4d,0x4d,0x0d,0x0d }, /* m M 24 */ - { 0x2c,0x3c,0x2c,0x3c }, /* , < 25 */ - { 0x2e,0x3e,0x2e,0x3e }, /* . > 26 */ - { 0x2f,0x3f,0x2f,0x3f }, /* / ? 27 */ - { 0x53,0x53,0x13,0x13 }, /* s S 28 */ - { 0x32,0x40,0x32,0x00 }, /* 2 @ 29 */ - { 0x31,0x21,0x31,0x31 }, /* 1 ! 2a */ - { 0x9b,0x9b,0x9b,0x9b }, /* Escape 2b */ - { 0x41,0x41,0x01,0x01 }, /* a A 2c */ - { 0x20,0x20,0x20,0x20 }, /* Space 2d */ - { 0x00,0x00,0x00,0x00 }, /* 0x2e unused */ - { 0x00,0x00,0x00,0x00 }, /* 0x2f unused */ - { 0x00,0x00,0x00,0x00 }, /* 0x30 unused */ - { 0x0d,0x0d,0x0d,0x0d }, /* Enter 31 */ -}; - -WRITE_LINE_MEMBER(apple2_state::ay3600_data_ready_w) -{ - if (state == ASSERT_LINE) - { - int mod = 0; - m_lastchar = m_ay3600->b_r(); - - mod = (m_kbspecial->read() & 0x06) ? 0x01 : 0x00; - mod |= (m_kbspecial->read() & 0x08) ? 0x02 : 0x00; - - m_transchar = a2_key_remap[m_lastchar&0x3f][mod]; - - if (m_transchar != 0) - { - m_strobe = 0x80; -// printf("new char = %04x (%02x)\n", m_lastchar&0x3f, m_transchar); - } - } -} - -WRITE_LINE_MEMBER(apple2_state::ay3600_iie_data_ready_w) -{ - if (state == ASSERT_LINE) - { - uint8_t *decode = m_kbdrom->base(); - uint16_t trans; - - m_lastchar = m_ay3600->b_r(); - - trans = m_lastchar & ~(0x1c0); // clear the 3600's control/shift stuff - trans |= (m_lastchar & 0x100)>>2; // bring the 0x100 bit down to the 0x40 place - trans <<= 2; // 4 entries per key - trans |= (m_kbspecial->read() & 0x06) ? 0x00 : 0x01; // shift is bit 1 (active low) - trans |= (m_kbspecial->read() & 0x08) ? 0x00 : 0x02; // control is bit 2 (active low) - trans |= (m_kbspecial->read() & 0x01) ? 0x0000 : 0x0200; // caps lock is bit 9 (active low) - - m_transchar = decode[trans]; - m_strobe = 0x80; - -// printf("new char = %04x (%02x)\n", m_lastchar, m_transchar); - } -} diff --git a/src/mame/machine/apple2gs.cpp b/src/mame/machine/apple2gs.cpp deleted file mode 100644 index 5ac18a3d759..00000000000 --- a/src/mame/machine/apple2gs.cpp +++ /dev/null @@ -1,2248 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods,R. Belmont -/********************************************************************* - - apple2gs.c - - Apple IIgs code - - - Apple IIgs specific softswitches: - - C019 - RDVBLBAR - bits 7 - set during vblank (when at scanline 192 or higher) - - C022 - TBCOLOR - bits 7-4 - text foreground color - bits 3-0 - text background color - - C023 - VGCINT - bit 7 - set for interrupt generated by VGC - - bit 6 - set during one second interrupt - bit 5 - set during scanline interrupt - - bit 4 - set during external interrupt - bit 3 - ??? - bit 2 - set for interrupt every second - - bit 1 - set for scanline interrupt - bit 0 - set for external interrupt - - C025 - KEYMODREG (comes from ?) - bit 7 - option key pressed - bit 6 - command key presssed - bit 5 - modified latch - bit 4 - keypad key pressed - bit 3 - repeating - bit 2 - caps lock latched - bit 1 - control key pressed - bit 0 - shift key pressed - - C027 - KMSTATUS (GLU system status) - bit 7 - set if mouse register full - bit 6 - mouse interrupt enable flag - bit 5 - set if data register full - bit 4 - data interrupt enabled - bit 3 - set if key data full - bit 2 - key data interurpt enabled - bit 1 - clear if horizontal mouse data, set if vertical - bit 0 - command register full - - C029 - NEWVIDEO - bit 7 - 1 for Super Hi-Res mode, 0 for old Apple II video modes - bit 6 - 1 to enable memory linearization (2000-9D00 in banks 01/E1), 0 for physical layout - bit 5 - 1 to display double hi-res mode in monochrome, 0 for color - bit 4 - ??? - bit 3 - ??? - bit 2 - ??? - bit 1 - ??? - bit 0 - ??? - - C02D - SLTROMSEL - - C031 - DISKREG - bit 7 - set to select head on 3.5" drive - bit 6 - set to enable 3.5" drive, clear to enable 5.25" drive - - C035 - SHADOW - bit 7 - ??? - bit 6 - set to inhibit I/O and LC operations ($C000-$FFFF) - bit 5 - ??? - bit 4 - set to inhibit shadowing aux hires page - bit 3 - set to inhibit shadowing super hires video - bit 2 - set to inhibit shadowing hires page 2 - bit 1 - set to inhibit shadowing hires page 2 - bit 0 - set to inhibit shadowing text pages - - C036 - CYAREG - bit 7 - clear for slow speed, set for hi speed - bit 6 - ??? - bit 5 - ??? - bit 4 - shadow in all RAM banks - bit 3 - slot 7 motor on - bit 2 - slot 6 motor on - bit 1 - slot 5 motor on - bit 0 - slot 4 motor on - - C041 - INTEN - bit 4 - set to enable quarter second interrupts - bit 3 - set to enable VBL interrupts - bit 2 - set to enable Mega II mouse switch interrupts - bit 1 - set to enable Mega II mouse movement interrupts - bit 0 - set to enable Mega II mouse mouse operation - - C046 - DIAGTYPE/INTFLAG - bit 7 - set if mouse button currently down - bit 6 - set if mouse button down on last read - bit 5 - set for AN3 - bit 4 - set if currently in quarter second interrupt - bit 3 - set if currently in VBL interrupt - bit 2 - set if currently in Mega II mouse switch interrupt - bit 1 - set if currently in Mega II mouse movement interrupt - bit 0 - set if system IRQ line asserted - - C047 - CLRVBLINT - - C068 - STATEREG - bit 7 - ALTZP status - bit 6 - PAGE2 status - bit 5 - RAMRD status - bit 4 - RAMWRT status - bit 3 - !LCRAM status (inverted) - bit 2 - LCRAM2 status - bit 1 - ROMBANK status (unimplemented) - bit 0 - INTCXROM status - -*********************************************************************/ - -#include "emu.h" - -#include "includes/apple2gs.h" -#include "includes/apple2.h" - -#include "machine/applefdc.h" -#include "machine/sonydriv.h" -#include "machine/8530scc.h" -#include "imagedev/flopdrv.h" -#include "cpu/g65816/g65816.h" -#include "sound/es5503.h" -#include "machine/ram.h" - -#include "debugger.h" - -#define LOG_C0XX 0 -#define LOG_ADB 0 -#define LOG_IRQ 0 - -/* ----------------------------------------------------------------------- - * Apple IIgs clock - * ----------------------------------------------------------------------- */ - -void apple2gs_state::process_clock() -{ - uint8_t operation; - seconds_t current_interval; - - /* update clock_curtime */ - current_interval = machine().time().seconds(); - m_clock_curtime += current_interval - m_clock_curtime_interval; - m_clock_curtime_interval = current_interval; - - switch(m_clock_mode) - { - case CLOCKMODE_IDLE: - m_clock_read = (m_clock_data >> 7); - m_clock_reg1 = (m_clock_data >> 2) & 0x03; - operation = (m_clock_data >> 4) & 0x07; - - if ((m_clock_data & 0x40) == 0x00) - { - switch(operation) - { - case 0x00: - /* read/write seconds register */ - m_clock_mode = CLOCKMODE_TIME; - break; - - case 0x03: - /* internal registers */ - if (m_clock_reg1 & 0x02) - { - m_clock_mode = CLOCKMODE_BRAM2; - m_clock_reg1 = (m_clock_data & 0x07) << 5; - } - else - { - m_clock_mode = CLOCKMODE_INTERNALREGS; - } - break; - - default: - //fatalerror("NYI\n"); - break; - } - } - break; - - case CLOCKMODE_BRAM1: - if (m_clock_read) - m_clock_data = m_clock_bram[m_clock_reg1]; - else - m_clock_bram[m_clock_reg1] = m_clock_data; - m_clock_mode = CLOCKMODE_IDLE; - break; - - case CLOCKMODE_BRAM2: - m_clock_reg1 |= (m_clock_data >> 2) & 0x1F; - m_clock_mode = CLOCKMODE_BRAM1; - break; - - case CLOCKMODE_INTERNALREGS: - switch (m_clock_reg1) - { - case 0x00: - /* test register */ - break; - - case 0x01: - /* write protect register */ - break; - } - m_clock_mode = CLOCKMODE_IDLE; - break; - - case CLOCKMODE_TIME: - if (m_clock_data & 0x40) - { - m_clock_data = m_clock_curtime >> (m_clock_reg1 * 8); - } - else - { - m_clock_curtime &= ~(0xFF << (m_clock_reg1 * 8)); - m_clock_curtime |= m_clock_data << (m_clock_reg1 * 8); - } - m_clock_mode = CLOCKMODE_IDLE; - break; - - default: - //fatalerror("NYI\n"); - break; - } -} - -/* ----------------------------------------------------------------------- - * Interrupts - * ----------------------------------------------------------------------- */ - -const char *apple2gs_state::apple2gs_irq_name(uint16_t irq_mask) -{ - switch(irq_mask) - { - case IRQ_KBD_SRQ: return "IRQ_KBD_SRQ"; - case IRQ_ADB_DATA: return "IRQ_ADB_DATA"; - case IRQ_ADB_MOUSE: return "IRQ_ADB_MOUSE"; - case IRQ_VGC_SCANLINE: return "IRQ_VGC_SCANLINE"; - case IRQ_VGC_SECOND: return "IRQ_VGC_SECOND"; - case IRQ_INTEN_QSECOND: return "IRQ_INTEN_QSECOND"; - case IRQ_INTEN_VBL: return "IRQ_INTEN_VBL"; - case IRQ_DOC: return "IRQ_DOC"; - case IRQ_SLOT: return "IRQ_SLOT"; - } - return nullptr; -} - -void apple2gs_state::apple2gs_add_irq(uint16_t irq_mask) -{ - if ((m_pending_irqs & irq_mask) == 0x00) - { - if (LOG_IRQ) - logerror("apple2gs_add_irq(): adding %s\n", apple2gs_irq_name(irq_mask)); - - m_pending_irqs |= irq_mask; - m_maincpu->set_input_line(G65816_LINE_IRQ, m_pending_irqs ? ASSERT_LINE : CLEAR_LINE); - } -} - - - -void apple2gs_state::apple2gs_remove_irq(uint16_t irq_mask) -{ - if (m_pending_irqs & irq_mask) - { - if (LOG_IRQ) - logerror("apple2gs_remove_irq(): removing %s\n", apple2gs_irq_name(irq_mask)); - - m_pending_irqs &= ~irq_mask; - m_maincpu->set_input_line(G65816_LINE_IRQ, m_pending_irqs ? ASSERT_LINE : CLEAR_LINE); - } -} - -WRITE_LINE_MEMBER(apple2gs_state::apple2gs_doc_irq) -{ - if (state) - { - apple2gs_add_irq(IRQ_DOC); - } - else - { - apple2gs_remove_irq(IRQ_DOC); - } -} - - -/* Clock interrupt */ -TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_clock_tick) -{ - if ((m_vgcint & 0x04) && !(m_vgcint & 0x40)) - { - m_vgcint |= 0xc0; - apple2gs_add_irq(IRQ_VGC_SECOND); - } -} - - -/* Quarter-second interrupt */ -TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_qsecond_tick) -{ - if ((m_inten & 0x10) && !(m_intflag & 0x10)) - { - m_intflag |= 0x10; - apple2gs_add_irq(IRQ_INTEN_QSECOND); - } -} - - -/* ----------------------------------------------------------------------- - * ADB - * ----------------------------------------------------------------------- */ - - -#if !RUN_ADB_MICRO -uint8_t apple2gs_state::adb_read_memory(uint32_t address) -{ - if (address < ARRAY_LENGTH(m_adb_memory)) - return m_adb_memory[address]; - else - return 0x00; -} - - - -void apple2gs_state::adb_write_memory(uint32_t address, uint8_t data) -{ - if (address < ARRAY_LENGTH(m_adb_memory)) - m_adb_memory[address] = data; -} - - - -void apple2gs_state::adb_set_mode(uint8_t mode) -{ - m_adb_mode = mode; -} - - - -void apple2gs_state::adb_set_config(uint8_t b1, uint8_t b2, uint8_t b3) -{ - /* ignore for now */ -} - - - -void apple2gs_state::adb_post_response(const uint8_t *bytes, size_t length) -{ - assert(length < ARRAY_LENGTH(m_adb_response_bytes)); - memcpy(m_adb_response_bytes, bytes, length); - - m_adb_state = ADBSTATE_INRESPONSE; - m_adb_response_length = length; - m_adb_response_pos = 0; -} - - - -void apple2gs_state::adb_post_response_1(uint8_t b) -{ - adb_post_response(&b, 1); -} - - - -void apple2gs_state::adb_post_response_2(uint8_t b1, uint8_t b2) -{ - uint8_t b[2]; - b[0] = b1; - b[1] = b2; - adb_post_response(b, 2); -} - - -void apple2gs_state::adb_do_command() -{ - int device; - uint32_t address; - uint8_t val; - - m_adb_state = ADBSTATE_IDLE; - if (LOG_ADB) - logerror("adb_do_command(): adb_command=0x%02x\n", m_adb_command); - - switch(m_adb_command) - { - case 0x00: /* ??? */ - break; - - case 0x03: /* flush keyboard buffer */ - break; - - case 0x04: /* set modes */ - adb_set_mode(m_adb_mode | m_adb_command_bytes[0]); - break; - - case 0x05: /* clear modes */ - adb_set_mode(m_adb_mode & ~m_adb_command_bytes[0]); - break; - - case 0x06: /* set config */ - adb_set_config(m_adb_command_bytes[0], m_adb_command_bytes[1], m_adb_command_bytes[2]); - break; - - case 0x07: /* synchronize */ - adb_set_mode(m_adb_command_bytes[0]); - adb_set_config(m_adb_command_bytes[1], m_adb_command_bytes[2], m_adb_command_bytes[3]); - break; - - case 0x08: /* write memory */ - address = m_adb_command_bytes[0]; - val = m_adb_command_bytes[1]; - adb_write_memory(address, val); - break; - - case 0x09: /* read memory */ - address = (m_adb_command_bytes[1] << 8) | m_adb_command_bytes[0]; - adb_post_response_1(adb_read_memory(address)); - break; - - case 0x0a: /* ??? */ - case 0x0b: /* ??? */ - break; - - case 0x0d: /* get version */ - adb_post_response_1(0x06); - break; - - case 0x0e: /* read available charsets */ - adb_post_response_2(0x01, 0x00); - break; - - case 0x0f: /* read available layouts */ - adb_post_response_2(0x01, 0x00); - break; - - case 0x12: /* mystery command 0x12 */ - case 0x13: /* mystery command 0x13 */ - break; - - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - /* send data to device */ - device = m_adb_command & 0x0f; - if (device == m_adb_address_keyboard) - { - } - else if (device == m_adb_address_mouse) - { - } - break; - - case 0xf2: - break; - - default: - fatalerror("ADB command 0x%02x unimplemented\n", m_adb_command); - } - m_adb_kmstatus |= 0x20; -} - - -uint8_t apple2gs_state::adb_read_datareg() -{ - uint8_t result; - - switch(m_adb_state) - { - case ADBSTATE_INRESPONSE: - result = m_adb_response_bytes[m_adb_response_pos++]; - if (m_adb_response_pos >= m_adb_response_length) - { - m_adb_state = ADBSTATE_IDLE; - m_adb_latent_result = result; - m_adb_kmstatus &= ~0x20; - } - break; - - default: - result = 0; //m_adb_latent_result & 0x7f; - break; - } - - if (LOG_ADB) - logerror("adb_read_datareg(): result=0x%02x\n", result); - - return result; -} - - -void apple2gs_state::adb_write_datareg(uint8_t data) -{ - if (LOG_ADB) - logerror("adb_write_datareg(): data=0x%02x\n", data); - - switch(m_adb_state) - { - case ADBSTATE_IDLE: - m_adb_command = data; - m_adb_command_length = 0; - m_adb_command_pos = 0; - -// printf("ADB command %02x\n", data); - switch(data) - { - case 0x00: /* ??? */ - case 0x01: /* abort */ - /* do nothing for now */ - break; - - case 0x03: /* flush keyboard buffer */ - m_adb_command_length = 0; - break; - - case 0x04: /* set modes */ - case 0x05: /* clear modes */ - m_adb_command_length = 1; - break; - - case 0x06: /* set config */ - m_adb_command_length = 3; - break; - - case 0x07: /* synchronize */ - if (m_is_rom3) - m_adb_command_length = 8; // ROM 3 has 8 bytes: mode byte, 3 config bytes, kbd/mouse params, disk eject options - else - m_adb_command_length = 4; // ROM 0/1 has 4 bytes sync - break; - - case 0x08: /* write memory */ - case 0x09: /* read memory */ - m_adb_command_length = 2; - break; - - case 0x0a: /* ??? */ - case 0x0b: /* ??? */ - m_adb_command_length = 0; - break; - - case 0x0d: /* get version */ - m_adb_command_length = 0; - break; - - case 0x0e: /* read available charsets */ - m_adb_command_length = 0; - m_adb_state = ADBSTATE_INCOMMAND; /* HACK */ - break; - - case 0x0f: /* read available layouts */ - m_adb_command_length = 0; - m_adb_state = ADBSTATE_INCOMMAND; /* HACK */ - break; - - case 0x12: /* mystery command 0x12 */ - case 0x13: /* mystery command 0x13 */ - m_adb_command_length = 2; - break; - - case 0x70: /* disable SRQ device 0 */ - case 0x71: /* disable SRQ device 1 */ - case 0x72: /* disable SRQ device 2 */ - case 0x73: /* disable SRQ device 3 */ - /* ignore for now */ - break; - - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - /* send data to device */ - m_adb_command_length = 2; - break; - - case 0xf2: - break; - - default: - fatalerror("ADB command 0x%02x unimplemented\n", data); - } - - if (m_adb_command_length > 0) - { - m_adb_state = ADBSTATE_INCOMMAND; - if (LOG_ADB) - logerror("adb_write_datareg(): in command length %u\n", (unsigned) m_adb_command_length); - } - break; - - case ADBSTATE_INCOMMAND: - assert(m_adb_command_pos < ARRAY_LENGTH(m_adb_command_bytes)); -// printf("ADB param %02x\n", data); - m_adb_command_bytes[m_adb_command_pos++] = data; - break; - - case ADBSTATE_INRESPONSE: - m_adb_state = ADBSTATE_IDLE; - break; - } - - /* do command if necessary */ - if ((m_adb_state == ADBSTATE_INCOMMAND) && (m_adb_command_pos >= m_adb_command_length)) - adb_do_command(); -} - -// real rom 3 h/w reads 0x90 when idle, 0x98 when key pressed -// current MESS reads back 0xb0 when idle -uint8_t apple2gs_state::adb_read_kmstatus() -{ - return m_adb_kmstatus; -} - - -void apple2gs_state::adb_write_kmstatus(uint8_t data) -{ - m_adb_kmstatus &= ~0x54; - m_adb_kmstatus |= data & 0x54; -} - - - -uint8_t apple2gs_state::adb_read_mousedata() -{ - uint8_t result = 0x00; - uint8_t absolute; - int8_t delta; - - if (m_adb_kmstatus & 0x80) // mouse register full - { - if (m_adb_kmstatus & 0x02) // H/V mouse data select - { - absolute = m_mouse_y; - delta = m_mouse_dy; - m_adb_kmstatus &= ~0x82; - apple2gs_remove_irq(IRQ_ADB_MOUSE); - } - else - { - absolute = m_mouse_x; - delta = m_mouse_dx; - m_adb_kmstatus |= 0x02; - } - - if (delta > 63) - delta = 63; - else if (delta < -64) - delta = -64; - - result = (absolute & 0x80) | (delta & 0x7F); - } - return result; -} - - -int8_t apple2gs_state::seven_bit_diff(uint8_t v1, uint8_t v2) -{ - v1 -= v2; - if (v1 & 0x40) - v1 |= 0x80; - else - v1 &= ~0x80; - return v1; -} - - - -void apple2gs_state::adb_check_mouse() -{ - uint8_t new_mouse_x, new_mouse_y; - - /* read mouse values */ - if ((m_adb_kmstatus & 0x80) == 0x00) - { - new_mouse_x = m_adb_mousex->read(); - new_mouse_y = m_adb_mousey->read(); - - if ((m_mouse_x != new_mouse_x) || (m_mouse_y != new_mouse_y)) - { - m_mouse_dx = seven_bit_diff(new_mouse_x, m_mouse_x); - m_mouse_dy = seven_bit_diff(new_mouse_y, m_mouse_y); - m_mouse_x = new_mouse_x; - m_mouse_y = new_mouse_y; - - m_adb_kmstatus |= 0x80; - m_adb_kmstatus &= ~0x02; - if (m_adb_kmstatus & 0x40) - apple2gs_add_irq(IRQ_ADB_MOUSE); - } - } -} -#endif - - -void apple2gs_state::apple2gs_set_scanint(uint8_t data) -{ - /* second interrupt */ - if ((m_vgcint & 0x40) && !(data & 0x40)) - { - apple2gs_remove_irq(IRQ_VGC_SECOND); - m_vgcint &= ~0xC0; - } - - /* scanline interrupt */ - if ((m_vgcint & 0x20) && !(data & 0x20)) - { - apple2gs_remove_irq(IRQ_VGC_SCANLINE); - m_vgcint &= ~0xA0; - } - - if (m_pending_irqs & (IRQ_VGC_SECOND | IRQ_VGC_SCANLINE)) - m_vgcint |= 0x80; -} - - -TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_scanline_tick) -{ - int scanline; - - scanline = m_screen->vpos(); - m_screen->update_partial(scanline); - - /* check scanline interrupt bits if we're in super hi-res and the current scanline is within the active display area */ - if ((m_newvideo & 0x80) && (scanline >= (BORDER_TOP-1)) && (scanline < (200+BORDER_TOP-1))) - { - uint8_t scb; - - scb = m_slowmem[0x19D00 + scanline - BORDER_TOP + 1]; - - if (scb & 0x40) - { - // scanline int flag is set even when the actual interrupt is disabled - m_vgcint |= 0x20; - - // see if the interrupt is also enabled and trigger it if so - if (m_vgcint & 0x02) - { - m_vgcint |= 0x80; - apple2gs_add_irq(IRQ_VGC_SCANLINE); - } - } - } - - if (scanline == (192+BORDER_TOP)) - { - /* VBL interrupt */ - if ((m_inten & 0x08) && !(m_intflag & 0x08)) - { - m_intflag |= 0x08; - apple2gs_add_irq(IRQ_INTEN_VBL); - } - } - - /* check the mouse status */ - if ((scanline % 8) == 0) - { - #if !RUN_ADB_MICRO - adb_check_mouse(); - #endif - - /* call Apple II interrupt handler */ - if ((m_screen->vpos() % 8) == 7) - { - //apple2_interrupt(m_maincpu); - /* TODO: check me! */ - m_screen->update_partial(m_screen->vpos()); - } - } - - m_scanline_timer->adjust(m_screen->time_until_pos((scanline+1)%262, 0)); -} - - - -/* ----------------------------------------------------------------------- - * Sound handlers - * ----------------------------------------------------------------------- */ - - -READ8_MEMBER( apple2gs_state::gssnd_r ) -{ - uint8_t ret = 0; - - switch (offset) - { - case 0: // control - ret = m_sndglu_ctrl; - break; - case 1: // data read - ret = m_sndglu_dummy_read; - - if (m_sndglu_ctrl & 0x40) // docram access - { - uint8_t *docram = memregion("es5503")->base(); - m_sndglu_dummy_read = docram[m_sndglu_addr]; - } - else - { - m_sndglu_dummy_read = m_es5503->read(space, m_sndglu_addr); - } - - if (m_sndglu_ctrl & 0x20) // auto-increment - { - m_sndglu_addr++; - } - break; - case 2: // addr l - ret = m_sndglu_addr & 0xff; - break; - case 3: // addr h - ret = (m_sndglu_addr >> 8) & 0xff; - break; - } - - return ret; -} - - - -WRITE8_MEMBER( apple2gs_state::gssnd_w ) -{ - switch (offset) - { - case 0: // control - m_sndglu_ctrl = data & 0x7f; // make sure DOC is never busy - if (!(m_sndglu_ctrl & 0x40)) // clear hi byte of address pointer on DOC access - { - m_sndglu_addr &= 0xff; - } - break; - case 1: // data write - if (m_sndglu_ctrl & 0x40) // docram access - { - uint8_t *docram = memregion("es5503")->base(); - docram[m_sndglu_addr] = data; - } - else - { - m_es5503->write(space, m_sndglu_addr, data); - } - - if (m_sndglu_ctrl & 0x20) // auto-increment - { - m_sndglu_addr++; - } - break; - case 2: // addr l - m_sndglu_addr &= 0xff00; - m_sndglu_addr |= data; - break; - case 3: // addr h - m_sndglu_addr &= 0x00ff; - m_sndglu_addr |= data<<8; - break; - } -} - -/* ----------------------------------------------------------------------- - * IO handlers - * ----------------------------------------------------------------------- */ - -// apple2gs_get_vpos - return the correct vertical counter value for the current scanline, -// keeping borders in mind. - -int apple2gs_state::apple2gs_get_vpos() -{ - int result, scan; - static const uint8_t top_border_vert[BORDER_TOP] = - { - 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, - - }; - - scan = m_screen->vpos(); - - if (scan < BORDER_TOP) - { - result = top_border_vert[scan]; - } - else - { - result = scan - BORDER_TOP + 0x100 + 1; - } - - return result; -} - -READ8_MEMBER( apple2gs_state::apple2gs_c0xx_r ) -{ - uint8_t result; - - if(machine().side_effects_disabled()) - { - return 0; - } - - offset &= 0xFF; - - switch(offset) - { - #if RUN_ADB_MICRO - case 0x00: /* C000 - KEYDATA */ - result = keyglu_816_read(GLU_C000); - break; - - case 0x10: /* C010 - KBDSTRB */ - result = keyglu_816_read(GLU_C010); - break; - #endif - - case 0x19: /* C019 - RDVBLBAR */ - result = (m_screen->vpos() >= (192+BORDER_TOP)) ? 0x80 : 0x00; - break; - - case 0x22: /* C022 - TBCOLOR */ - result = (m_fgcolor << 4) | m_bgcolor; - break; - - case 0x23: /* C023 - VGCINT */ - result = m_vgcint; - break; - - case 0x24: /* C024 - MOUSEDATA */ - #if RUN_ADB_MICRO - result = keyglu_816_read(GLU_MOUSEX); - #else - result = adb_read_mousedata(); - #endif - break; - - case 0x25: /* C025 - KEYMODREG */ - #if RUN_ADB_MICRO - result = keyglu_816_read(GLU_KEYMOD); - #else - - result = 0; - { - uint8_t temp = m_kbspecial->read(); - if (temp & 1) // capslock - { - result |= 4; - } - if (temp & 6) // shift - { - result |= 1; - } - if (temp & 8) // control - { - result |= 2; - } - if (temp & 0x10) // open apple/command - { - result |= 0x40; - } - if (temp & 0x20) // option - { - result |= 0x80; - } - // keypad is a little rough right now - if (m_lastchar >= 0x28 && m_lastchar <= 0x2d) - { - result |= 0x10; - } - else if (m_lastchar >= 0x32 && m_lastchar <= 0x3f) - { - result |= 0x10; - } - else if (m_lastchar >= 0x100 && m_lastchar <= 0x101) - { - result |= 0x10; - } - else if (m_lastchar >= 0x109 && m_lastchar <= 0x10a) - { - result |= 0x10; - } - } -#endif - break; - - case 0x26: /* C026 - DATAREG */ - #if RUN_ADB_MICRO - result = keyglu_816_read(GLU_DATA); - #else - result = adb_read_datareg(); - #endif - break; - - case 0x27: /* C027 - KMSTATUS */ - #if RUN_ADB_MICRO - result = keyglu_816_read(GLU_SYSSTAT); - #else - result = adb_read_kmstatus(); - #endif - break; - - case 0x29: /* C029 - NEWVIDEO */ - result = m_newvideo; - break; - - case 0x2B: /* C02B - LANGSEL */ - result = m_langsel; - break; - - case 0x2D: /* C02D - SLTROMSEL */ - result = m_sltromsel; - break; - - case 0x2E: /* C02E - VERTCNT */ - result = apple2gs_get_vpos() >> 1; - break; - - case 0x2F: /* C02F - HORIZCNT */ - result = m_screen->hpos() / 11; - if (result > 0) - { - result += 0x40; - } - - if (apple2gs_get_vpos() & 1) - { - result |= 0x80; - } - break; - - case 0x31: /* C031 - DISKREG */ - result = m_fdc_diskreg; - break; - - case 0x33: /* C033 - CLOCKDATA */ - result = m_clock_data; - break; - - case 0x34: /* C034 - CLOCKCTL */ - result = m_clock_control; - break; - - case 0x35: /* C035 - SHADOW */ - result = m_shadow; - break; - - case 0x36: /* C036 - CYAREG */ - result = m_cyareg; - break; - - case 0x38: /* C038 - SCCBREG */ - result = m_scc->cb_r(space, 0, mem_mask); - break; - - case 0x39: /* C039 - SCCAREG */ - result = m_scc->ca_r(space, 0, mem_mask); - break; - - case 0x3A: /* C03A - SCCBDATA */ - result = m_scc->db_r(space, 0, mem_mask); - break; - - case 0x3B: /* C03B - SCCADATA */ - result = m_scc->da_r(space, 0, mem_mask); - break; - - case 0x3C: /* C03C - SOUNDCTL */ - case 0x3D: /* C03D - SOUNDDATA */ - case 0x3E: /* C03E - SOUNDADRL */ - case 0x3F: /* C03F - SOUNDADRH */ - result = gssnd_r(space, offset & 0x03, mem_mask); - break; - - case 0x41: /* C041 - INTEN */ - result = m_inten; - break; - - case 0x46: /* C046 - INTFLAG */ - result = m_intflag; - break; - - case 0x68: /* C068 - STATEREG */ - result = ((m_flags & VAR_ALTZP) ? 0x80 : 0x00) - | ((m_flags & VAR_PAGE2) ? 0x40 : 0x00) - | ((m_flags & VAR_RAMRD) ? 0x20 : 0x00) - | ((m_flags & VAR_RAMWRT) ? 0x10 : 0x00) - | ((m_flags & VAR_LCRAM) ? 0x00 : 0x08) - | ((m_flags & VAR_LCRAM2) ? 0x04 : 0x00) - | ((m_flags & VAR_INTCXROM)? 0x01 : 0x00); - break; - - case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - offset |= (memregion("maincpu")->bytes() - 1) & ~0x3FFF; - result = m_rom[offset]; - break; - - case 0x21: /* C021 - MONOCOLOR */ - case 0x2C: /* C02C - CHARROM */ - result = 0x00; - break; - - // slot 6 registers should go to applefdc if slot 6 not "Your Card" - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: - if ((m_sltromsel & (1 << 6)) == 0) - { - result = m_fdc->read(offset); - } - else - { - result = apple2_c0xx_r(space, offset, 0); - } - break; - - default: - if (offset < 0x80) - { - result = apple2_c0xx_r(space, offset, 0); - } - else - { - result = apple2_c080_r(space, offset, 0); - } - break; - } - - if (LOG_C0XX) - logerror("apple2gs_c0xx_r(): offset=0x%02x result=0x%02x\n", offset, result); - - return result; -} - - - -WRITE8_MEMBER( apple2gs_state::apple2gs_c0xx_w ) -{ - offset &= 0xFF; - - if (LOG_C0XX) - logerror("apple2gs_c0xx_w(): offset=0x%02x data=0x%02x\n", offset, data); - - switch(offset) - { - #if RUN_ADB_MICRO - case 0x10: - break; - #endif - - case 0x22: /* C022 - TBCOLOR */ - m_fgcolor = (data >> 4) & 0x0F; - m_bgcolor = (data >> 0) & 0x0F; - break; - - case 0x23: /* C023 - VGCINT */ - m_vgcint &= ~0x0F; - m_vgcint |= data & 0x0F; - break; - - case 0x24: /* C024 - MOUSEDATA */ - case 0x25: /* C025 - KEYMODREG */ - case 0x28: /* C028 - ROMBANK */ - case 0x2C: /* C02C - CHARROM */ - case 0x2E: /* C02E - VERTCNT */ - case 0x2F: /* C02F - HORIZCNT */ - /* ignore these writes */ - break; - - case 0x26: /* C026 - DATAREG */ - #if RUN_ADB_MICRO - keyglu_816_write(GLU_COMMAND, data); - #else - adb_write_datareg(data); - #endif - break; - - case 0x27: /* C027 - KMSTATUS */ - #if RUN_ADB_MICRO - keyglu_816_write(GLU_SYSSTAT, data); - #else - adb_write_kmstatus(data); - #endif - break; - - case 0x29: /* C029 - NEWVIDEO */ - m_newvideo = data; - break; - - case 0x2B: /* C02B - LANGSEL */ - m_langsel = data; - break; - - case 0x2D: /* C02D - SLTROMSEL */ - m_sltromsel = data; - apple2_update_memory(); - break; - - case 0x31: /* C031 - DISKREG */ - apple2_iwm_setdiskreg(data); - break; - - case 0x32: /* C032 - SCANINT */ - apple2gs_set_scanint(data); - break; - - case 0x33: /* C033 - CLOCKDATA */ - m_clock_data = data; - break; - - case 0x34: /* C034 - CLOCKCTL */ - m_clock_control = data & 0x7F; - m_bordercolor = data & 0x0F; - if (data & 0x80) - process_clock(); - break; - - case 0x35: /* C035 - SHADOW */ - if (m_shadow != data) - { - m_shadow = data; - apple2_update_memory(); - } - break; - - case 0x36: /* C036 - CYAREG */ - m_cyareg = data & ~0x20; - m_maincpu->set_unscaled_clock((data & 0x80) ? APPLE2GS_14M/5 : APPLE2GS_7M/7); - break; - - case 0x38: /* C038 - SCCBREG */ - m_scc->cb_w(space, 0, data); - break; - - case 0x39: /* C039 - SCCAREG */ - m_scc->ca_w(space, 0, data); - break; - - case 0x3A: /* C03A - SCCBDATA */ - m_scc->db_w(space, 0, data); - break; - - case 0x3B: /* C03B - SCCADATA */ - m_scc->da_w(space, 0, data); - break; - - case 0x3C: /* C03C - SOUNDCTL */ - case 0x3D: /* C03D - SOUNDDATA */ - case 0x3E: /* C03E - SOUNDADRL */ - case 0x3F: /* C03F - SOUNDADRH */ - gssnd_w(space, offset & 0x03, data, mem_mask); - break; - - case 0x41: /* C041 - INTEN */ - m_inten = data & 0x1F; - if ((m_inten & 0x10) == 0x00) - apple2gs_remove_irq(IRQ_INTEN_QSECOND); - if ((m_inten & 0x08) == 0x00) - apple2gs_remove_irq(IRQ_INTEN_VBL); - break; - - case 0x47: /* C047 - CLRVBLINT */ - m_intflag &= ~0x18; - apple2gs_remove_irq(IRQ_INTEN_QSECOND); - apple2gs_remove_irq(IRQ_INTEN_VBL); - break; - - case 0x68: /* C068 - STATEREG */ - apple2_setvar( - ((data & 0x80) ? VAR_ALTZP : 0) | - ((data & 0x40) ? VAR_PAGE2 : 0) | - ((data & 0x20) ? VAR_RAMRD : 0) | - ((data & 0x10) ? VAR_RAMWRT : 0) | - ((data & 0x08) ? 0 : VAR_LCRAM) | - ((data & 0x04) ? VAR_LCRAM2 : 0) | - ((data & 0x01) ? VAR_INTCXROM : 0), - VAR_ALTZP | VAR_PAGE2 | VAR_RAMRD | VAR_RAMWRT | VAR_LCRAM | VAR_LCRAM2 | VAR_INTCXROM); - break; - - // slot 6 registers should go to applefdc if slot 6 not "Your Card" - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: - if ((m_sltromsel & (1 << 6)) == 0) - { - m_fdc->write(offset, data); - } - else - { - apple2_c0xx_w(space, offset, data, 0); - } - break; - - default: - if (offset < 0x80) - { - apple2_c0xx_w(space, offset, data, 0); - } - else - { - apple2_c080_w(space, offset, data, 0); - } - break; - } -} - - - -/* ----------------------------------------------------------------------- - * Memory management - * ----------------------------------------------------------------------- */ - -WRITE8_MEMBER( apple2gs_state::apple2gs_main0400_w ) -{ - offset += 0x000400; - m_rambase[offset] = data; - - if (!(m_shadow & 0x01)) - { - m_slowmem[offset] = data; - } -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_aux0400_w ) -{ - offset += 0x010400; - m_rambase[offset] = data; - - if (!(m_shadow & 0x01)) - { - m_slowmem[offset] = data; - } -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_main2000_w ) -{ - offset += 0x002000; - m_rambase[offset] = data; - - if (!(m_shadow & 0x02)) - { - m_slowmem[offset] = data; - } -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_aux2000_w ) -{ - offset += 0x012000; - m_rambase[offset] = data; - - if (!(m_shadow & 0x12) || !(m_shadow & 0x08)) - { - m_slowmem[offset] = data; - } -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_main4000_w ) -{ - offset += 0x004000; - m_rambase[offset] = data; - - if ((offset >= 0x004000) && (offset <= 0x005FFF)) - { - if (!(m_shadow & 0x04)) - m_slowmem[offset] = data; - } -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_aux4000_w ) -{ - offset += 0x014000; - m_rambase[offset] = data; - - if ((offset >= 0x014000) && (offset <= 0x015FFF)) - { - if (!(m_shadow & 0x14) || !(m_shadow & 0x08)) - m_slowmem[offset] = data; - } - else if ((offset >= 0x016000) && (offset <= 0x019FFF)) - { - if (!(m_shadow & 0x08)) - { - m_slowmem[offset] = data; - - if (offset >= 0x19e00) - { - int color = (offset - 0x19e00) >> 1; - - m_shr_palette[color] = rgb_t( - ((m_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17, - ((m_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17, - ((m_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17); - } - } - } -} - - - -static void apple2gs_mem_000000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - meminfo->read_mem = (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000; - meminfo->write_mem = (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000; -} - -static void apple2gs_mem_000200(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x010200 : 0x000200; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x010200 : 0x000200; -} - -static void apple2gs_mem_000400(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_flags & VAR_80STORE) - { - meminfo->read_mem = (state->m_flags & VAR_PAGE2) ? 0x010400 : 0x000400; - meminfo->write_mem = (state->m_flags & VAR_PAGE2) ? 0x010400 : 0x000400; - meminfo->write_handler = (state->m_flags & VAR_PAGE2) ? &state->write_delegates_2gs0400[0] : &state->write_delegates_2gs0400[1]; - } - else - { - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x010400 : 0x000400; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x010400 : 0x000400; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs0400[0] : &state->write_delegates_2gs0400[1]; - } -} - -static void apple2gs_mem_000800(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x010800 : 0x000800; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x010800 : 0x000800; -} - -static void apple2gs_mem_002000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if ((state->m_flags & (VAR_80STORE|VAR_HIRES)) == (VAR_80STORE|VAR_HIRES)) - { - meminfo->read_mem = (state->m_flags & VAR_PAGE2) ? 0x012000 : 0x002000; - meminfo->write_mem = (state->m_flags & VAR_PAGE2) ? 0x012000 : 0x002000; - meminfo->write_handler = (state->m_flags & VAR_PAGE2) ? &state->write_delegates_2gs2000[0] : &state->write_delegates_2gs2000[1]; - } - else - { - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x012000 : 0x002000; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x012000 : 0x002000; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs2000[0] : &state->write_delegates_2gs2000[1]; - } -} - -static void apple2gs_mem_004000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x014000 : 0x004000; - meminfo->write_handler = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs4000[0] : &state->write_delegates_2gs4000[1]; -} - -static void apple2gs_mem_xxD000(running_machine &machine,apple2_meminfo *meminfo, uint32_t lcmem) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_flags & VAR_LCRAM) - { - if (state->m_flags & VAR_LCRAM2) - meminfo->read_mem = lcmem | 0x00C000; - else - meminfo->read_mem = lcmem | 0x00D000; - } - else - { - meminfo->read_mem = 0x03D000 | APPLE2_MEM_ROM; - } - - if (state->m_flags & VAR_LCWRITE) - { - if (state->m_flags & VAR_LCRAM2) - meminfo->write_mem = lcmem | 0x00C000; - else - meminfo->write_mem = lcmem | 0x00D000; - } - else - { - meminfo->write_mem = APPLE2_MEM_FLOATING; - } -} - -static void apple2gs_mem_xxE000(running_machine &machine,apple2_meminfo *meminfo, uint32_t lcmem) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_flags & VAR_LCRAM) - meminfo->read_mem = lcmem | 0x00E000; - else - meminfo->read_mem = 0x03E000 | APPLE2_MEM_ROM; - - if (state->m_flags & VAR_LCWRITE) - meminfo->write_mem = lcmem | 0x00E000; - else - meminfo->write_mem = APPLE2_MEM_FLOATING; -} - -static void apple2gs_mem_00D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_shadow & 0x40) - { - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x01D000 : 0x00D000; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x01D000 : 0x00D000; - } - else - { - apple2gs_mem_xxD000(machine,meminfo, (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000); - } -} - -static void apple2gs_mem_00E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_shadow & 0x40) - { - meminfo->read_mem = (state->m_flags & VAR_RAMRD) ? 0x01E000 : 0x00E000; - meminfo->write_mem = (state->m_flags & VAR_RAMWRT) ? 0x01E000 : 0x00E000; - } - else - { - apple2gs_mem_xxE000(machine,meminfo, (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000); - } -} - -static void apple2gs_mem_01D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_shadow & 0x40) - { - meminfo->read_mem = 0x01D000; - meminfo->write_mem = 0x01D000; - } - else - { - apple2gs_mem_xxD000(machine,meminfo, 0x010000); - } -} - -static void apple2gs_mem_01E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_state *state = machine.driver_data<apple2gs_state>(); - if (state->m_shadow & 0x40) - { - meminfo->read_mem = 0x01E000; - meminfo->write_mem = 0x01E000; - } - else - { - apple2gs_mem_xxE000(machine,meminfo, 0x010000); - } -} - -static void apple2gs_mem_E0D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_mem_xxD000(machine,meminfo, 0x000000 | APPLE2_MEM_AUX); -} - -static void apple2gs_mem_E0E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_mem_xxE000(machine,meminfo, 0x000000 | APPLE2_MEM_AUX); -} - -static void apple2gs_mem_E1D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_mem_xxD000(machine,meminfo, 0x010000 | APPLE2_MEM_AUX); -} - -static void apple2gs_mem_E1E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo) -{ - apple2gs_mem_xxE000(machine,meminfo, 0x010000 | APPLE2_MEM_AUX); -} - - - -static const apple2_memmap_entry apple2gs_memmap_entries[] = -{ - { 0x000000, 0x0001FF, apple2gs_mem_000000, A2MEM_MONO }, - { 0x000200, 0x0003FF, apple2gs_mem_000200, A2MEM_DUAL }, - { 0x000400, 0x0007FF, apple2gs_mem_000400, A2MEM_DUAL }, - { 0x000800, 0x001FFF, apple2gs_mem_000800, A2MEM_DUAL }, - { 0x002000, 0x003FFF, apple2gs_mem_002000, A2MEM_DUAL }, - { 0x004000, 0x00BFFF, apple2gs_mem_004000, A2MEM_DUAL }, - { 0x00D000, 0x00DFFF, apple2gs_mem_00D000, A2MEM_DUAL }, - { 0x00E000, 0x00FFFF, apple2gs_mem_00E000, A2MEM_DUAL }, - - { 0x01D000, 0x01DFFF, apple2gs_mem_01D000, A2MEM_DUAL }, - { 0x01E000, 0x01FFFF, apple2gs_mem_01E000, A2MEM_DUAL }, - { 0xE0D000, 0xE0DFFF, apple2gs_mem_E0D000, A2MEM_DUAL }, - { 0xE0E000, 0xE0FFFF, apple2gs_mem_E0E000, A2MEM_DUAL }, - { 0xE1D000, 0xE1DFFF, apple2gs_mem_E1D000, A2MEM_DUAL }, - { 0xE1E000, 0xE1FFFF, apple2gs_mem_E1E000, A2MEM_DUAL }, - - { 0 } -}; - - - -uint8_t *apple2gs_state::apple2gs_getslotmem(offs_t address) -{ - uint8_t *rom; - - address %= 0x00FFFF; - assert(address >= 0xC000); - assert(address <= 0xCFFF); - - rom = m_rom; - rom += 0x030000 % memregion("maincpu")->bytes(); - return &rom[address]; -} - - - -uint8_t apple2gs_state::apple2gs_xxCxxx_r(address_space &space, offs_t address) -{ - uint8_t result; - int slot; - - if ((m_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) // shadow all banks and C0xx? - { - result = m_ram->pointer()[address]; - } - else if ((address & 0x000F00) == 0x000000) // accessing C0xx? - { - result = apple2gs_c0xx_r(m_maincpu->space(AS_PROGRAM), address, 0); - } - else - { - device_a2bus_card_interface *slotdevice; - - slot = (address & 0x000F00) / 0x100; - if (slot <= 7) // slots 1-7, it's the slot - { - slotdevice = m_a2bus->get_a2bus_card(slot); - - // is this slot internal or "Your Card"? - if ((m_sltromsel & (1 << slot)) == 0) - { - // accessing a slot mapped to internal, let's put back the internal ROM - m_a2_cnxx_slot = -1; - apple2_update_memory(); - result = *apple2gs_getslotmem(address); - } - else - { - // accessing a slot mapped to "Your Card", C800 should belong to that card - if (slotdevice != nullptr) - { - if (slotdevice->take_c800()) - { - m_a2_cnxx_slot = slot; - apple2_update_memory(); - } - result = slotdevice->read_cnxx(address&0xff); - } - else - { - result = apple2_getfloatingbusvalue(); - } - } - } - else // C800-CFFF, not cards - { - slotdevice = nullptr; - - // if CFFF accessed, reset C800 area to internal ROM - if(!machine().side_effects_disabled()) - { - if ((address & 0xfff) == 0xfff) - { - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } - } - - if ( m_a2_cnxx_slot >= 0 && m_a2_cnxx_slot <= 7 ) - { - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - } - - if (slotdevice) - { - result = slotdevice->read_c800(address&0x7ff); - } - else - { - result = *apple2gs_getslotmem(address); - } - } - } - return result; -} - - - -void apple2gs_state::apple2gs_xxCxxx_w(address_space &space, offs_t address, uint8_t data) -{ - int slot; - - // if CFFF accessed, reset C800 area to internal ROM - if(!machine().side_effects_disabled()) - { - if ((address & 0xfff) == 0xfff) - { - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } - } - - if ((m_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) - { - m_ram->pointer()[address] = data; - } - else if ((address & 0x000F00) == 0x000000) - { - apple2gs_c0xx_w(m_maincpu->space(AS_PROGRAM), address, data, 0); - } - else - { - device_a2bus_card_interface *slotdevice; - - slot = (address & 0x000F00) / 0x100; - - if (slot <= 7) // slots 1-7, it's the slot - { - slotdevice = m_a2bus->get_a2bus_card(slot); - - // is this slot internal or "Your Card"? - if ((m_sltromsel & (1 << slot)) == 0) - { - // accessing a slot mapped to internal, let's put back the internal ROM - m_a2_cnxx_slot = -1; - apple2_update_memory(); - *apple2gs_getslotmem(address) = data; - } - else - { - // accessing a slot mapped to "Your Card", C800 should belong to that card if it can take it - if (slotdevice != nullptr) - { - if (slotdevice->take_c800()) - { - m_a2_cnxx_slot = slot; - apple2_update_memory(); - } - slotdevice->write_cnxx(address&0xff, data); - } - // (else slot is your card but there's no card inserted so the write goes nowhere) - } - } - else // C800-CFFF, not cards - { - slotdevice = nullptr; - - // if CFFF accessed, reset C800 area to internal ROM - if ((address & 0xfff) == 0xfff) - { - m_a2_cnxx_slot = -1; - apple2_update_memory(); - } - - if ( m_a2_cnxx_slot >= 0 && m_a2_cnxx_slot <= 7 ) - { - slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot); - } - - if (slotdevice) - { - slotdevice->write_c800(address&0x7ff, data); - } - else - { - *apple2gs_getslotmem(address) = data; - } - } - } -} - - - -READ8_MEMBER( apple2gs_state::apple2gs_00Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0x00C000); } -READ8_MEMBER( apple2gs_state::apple2gs_01Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0x01C000); } -READ8_MEMBER( apple2gs_state::apple2gs_E0Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0xE0C000); } -READ8_MEMBER( apple2gs_state::apple2gs_E1Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0xE1C000); } - -WRITE8_MEMBER( apple2gs_state::apple2gs_00Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0x00C000, data); } -WRITE8_MEMBER( apple2gs_state::apple2gs_01Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0x01C000, data); } -WRITE8_MEMBER( apple2gs_state::apple2gs_E0Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0xE0C000, data); } -WRITE8_MEMBER( apple2gs_state::apple2gs_E1Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0xE1C000, data); } - -WRITE8_MEMBER( apple2gs_state::apple2gs_Exxxxx_w ) -{ - m_slowmem[offset] = data; -} - -WRITE8_MEMBER( apple2gs_state::apple2gs_E004xx_w ) { apple2gs_Exxxxx_w(space, offset + 0x00400, data, mem_mask); } -WRITE8_MEMBER( apple2gs_state::apple2gs_E02xxx_w ) { apple2gs_Exxxxx_w(space, offset + 0x02000, data, mem_mask); } -WRITE8_MEMBER( apple2gs_state::apple2gs_E104xx_w ) { apple2gs_Exxxxx_w(space, offset + 0x10400, data, mem_mask); } -WRITE8_MEMBER( apple2gs_state::apple2gs_E12xxx_w ) { apple2gs_Exxxxx_w(space, offset + 0x12000, data, mem_mask); } - -WRITE8_MEMBER( apple2gs_state::apple2gs_slowmem_w ) -{ - m_slowmem[offset] = data; - - if ((offset >= 0x19e00) && (offset < 0x19fff)) - { - int color = (offset - 0x19e00) >> 1; - - m_shr_palette[color] = rgb_t( - ((m_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17, - ((m_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17, - ((m_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17); - } -} - -// Because the bank address multiplexes on the 65816 data bus, reading a memory area -// which doesn't drive the bus results in reading back the bank number. -READ8_MEMBER(apple2gs_state::apple2gs_bank_echo_r) -{ - return m_echo_bank + (offset>>16); -} - -void apple2gs_state::apple2gs_setup_memory() -{ - address_space& space = m_maincpu->space(AS_PROGRAM); - offs_t begin, end; - apple2_memmap_config cfg; - - /* allocate memory for E00000-E1FFFF */ - m_slowmem = make_unique_clear<uint8_t[]>(128*1024); - save_pointer(m_slowmem, "APPLE2GS_SLOWMEM", 128*1024); - - // install expanded memory - // fair warning: other code assumes banks 0 and 1 are the first 128k of the RAM device, so you must install bank 1 at 0x10000 - // otherwise nothing works :) - if (m_is_rom3) - { - int ramsize = m_ram->size(); - - // ROM 03 hardware: the quoted "1 MB" for a base machine doesn't include banks e0/e1, so map accordingly - space.install_readwrite_bank(0x010000, ramsize - 1, "bank1"); - membank("bank1")->set_base(m_ram->pointer() + 0x010000); - - space.install_read_handler( ramsize, 0xdfffff, read8_delegate(FUNC(apple2gs_state::apple2gs_bank_echo_r),this)); - m_echo_bank = (ramsize >> 16); - } - else - { - int ramsize = m_ram->size()-0x30000; - - // ROM 00/01 hardware: the quoted "256K" for a base machine *does* include banks e0/e1. - space.install_readwrite_bank(0x010000, ramsize - 1 + 0x10000, "bank1"); - membank("bank1")->set_base(m_ram->pointer() + 0x010000); - - space.install_read_handler( ramsize + 0x10000, 0xdfffff, read8_delegate(FUNC(apple2gs_state::apple2gs_bank_echo_r),this)); - m_echo_bank = (ramsize+0x10000) >> 16; - } - - /* install hi memory */ - space.install_read_bank(0xe00000, 0xe1ffff, "bank2"); - space.install_write_handler(0xe00000, 0xe1ffff, write8_delegate(FUNC(apple2gs_state::apple2gs_slowmem_w),this)); - space.install_write_handler(0xe00400, 0xe007ff, write8_delegate(FUNC(apple2gs_state::apple2gs_E004xx_w),this)); - space.install_write_handler(0xe02000, 0xe03fff, write8_delegate(FUNC(apple2gs_state::apple2gs_E02xxx_w),this)); - space.install_write_handler(0xe10400, 0xe107ff, write8_delegate(FUNC(apple2gs_state::apple2gs_E104xx_w),this)); - space.install_write_handler(0xe12000, 0xe13fff, write8_delegate(FUNC(apple2gs_state::apple2gs_E12xxx_w),this)); - membank("bank2")->set_base(m_slowmem.get()); - - /* install alternate ROM bank */ - begin = 0x1000000 - memregion("maincpu")->bytes(); - end = 0xffffff; - space.install_read_bank(begin, end, "bank3"); - membank("bank3")->set_base(m_rom); - - /* install new xxC000-xxCFFF handlers */ - space.install_read_handler(0x00c000, 0x00cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_00Cxxx_r),this)); - space.install_write_handler(0x00c000, 0x00cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_00Cxxx_w),this)); - space.install_read_handler(0x01c000, 0x01cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_01Cxxx_r),this)); - space.install_write_handler(0x01c000, 0x01cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_01Cxxx_w),this)); - space.install_read_handler(0xe0c000, 0xe0cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_E0Cxxx_r),this)); - space.install_write_handler(0xe0c000, 0xe0cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_E0Cxxx_w),this)); - space.install_read_handler(0xe1c000, 0xe1cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_E1Cxxx_r),this)); - space.install_write_handler(0xe1c000, 0xe1cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_E1Cxxx_w),this)); - - - /* install aux memory writes (for shadowing) */ - space.install_write_handler(0x010400, 0x0107FF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux0400_w), this)); - space.install_write_handler(0x012000, 0x013FFF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux2000_w), this)); - space.install_write_handler(0x014000, 0x019FFF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux4000_w), this)); - - /* setup the Apple II memory system */ - memset(&cfg, 0, sizeof(cfg)); - cfg.first_bank = 4; - cfg.memmap = apple2gs_memmap_entries; - cfg.auxmem = m_slowmem.get(); - cfg.auxmem_length = 0x20000; - apple2_setup_memory(&cfg); -} - - - -/* ----------------------------------------------------------------------- - * Driver Init - * ----------------------------------------------------------------------- */ - -READ8_MEMBER(apple2gs_state::apple2gs_read_vector) -{ - return m_maincpu->space(AS_PROGRAM).read_byte(offset | 0xFFFFE0); -} - -MACHINE_RESET_MEMBER(apple2gs_state,apple2gs) -{ - apple2gs_refresh_delegates(); - - // call "base class" machine reset to set up m_rambase and the language card - machine_reset(); - - m_cur_slot6_image = nullptr; - m_newvideo = 0x00; - m_vgcint = 0x00; - m_langsel = 0x00; - m_sltromsel = 0x00; - m_cyareg = 0x80; - m_inten = 0x00; - m_intflag = 0x00; - m_shadow = 0x00; - m_pending_irqs = 0x00; - m_mouse_x = 0x00; - m_mouse_y = 0x00; - m_mouse_dx = 0x00; - m_mouse_dy = 0x00; - #if !RUN_ADB_MICRO - m_adb_state = ADBSTATE_IDLE; - m_adb_kmstatus = 0x00; - m_adb_command = 0; - m_adb_mode = 0; - m_adb_latent_result = 0; - m_adb_command_length = 0; - m_adb_command_pos = 0; - memset(m_adb_command_bytes, 0, sizeof(m_adb_command_bytes)); - memset(m_adb_response_bytes, 0, sizeof(m_adb_response_bytes)); - m_adb_response_length = 0; - m_adb_response_pos = 0; - memset(m_adb_memory, 0, sizeof(m_adb_memory)); - m_adb_address_keyboard = 2; - m_adb_address_mouse = 3; - #endif - - /* init time */ - m_clock_data = 0; - m_clock_control =0; - m_clock_read = 0; - m_clock_reg1 = 0; - m_clock_mode = CLOCKMODE_IDLE; - m_clock_curtime = 0; - m_clock_curtime_interval = 0; - - m_sndglu_ctrl = 0x00; - m_sndglu_addr = 0; - m_sndglu_dummy_read = 0; - - m_adb_dtime = 0; - m_last_adb_time = 0; -} - -MACHINE_START_MEMBER(apple2gs_state,apple2gscommon) -{ - apple2gs_refresh_delegates(); - - m_machinetype = APPLE_IIGS; - apple2eplus_init_common(nullptr); - - /* setup globals */ - m_is_rom3 = true; - - subdevice<nvram_device>("nvram")->set_base(m_clock_bram, sizeof(m_clock_bram)); - - /* save state stuff. note that the driver takes care of docram. */ - uint8_t* ram = m_ram->pointer(); - save_pointer(ram, "APPLE2GS_RAM", m_ram->size()); - - save_item(m_newvideo, "NEWVIDEO"); - save_item(m_bordercolor, "BORDERCOLOR"); - save_item(m_vgcint, "VGCINT"); - save_item(m_langsel, "LANGSEL"); - save_item(m_sltromsel, "SLTROMSEL"); - save_item(m_cyareg, "CYAREG"); - save_item(m_inten, "INTEN"); - save_item(m_intflag, "INTFLAG"); - save_item(m_shadow, "SHADOW"); - save_item(m_pending_irqs, "PENDIRQ"); - save_item(m_mouse_x, "MX"); - save_item(m_mouse_y, "MY"); - save_item(m_mouse_dx, "MDX"); - save_item(m_mouse_dy, "MDY"); - - save_item(m_clock_data, "CLKDATA"); - save_item(m_clock_control, "CLKCTRL"); - save_item(m_clock_read, "CLKRD"); - save_item(m_clock_reg1, "CLKREG1"); - save_item(m_clock_curtime, "CLKCURTIME"); - save_item(m_clock_curtime_interval, "CLKCURTIMEINT"); -// save_item(m_clock_mode, "CLKMODE"); - save_item(NAME(m_clock_bram)); -#if !RUN_ADB_MICRO - save_item(NAME(m_adb_memory)); - save_item(NAME(m_adb_command_bytes)); - save_item(NAME(m_adb_response_bytes)); -// save_item(m_adb_state, "ADB/m_adb_state"); - save_item(m_adb_command, "ADB/m_adb_command"); - save_item(m_adb_mode, "ADB/m_adb_mode"); - save_item(m_adb_kmstatus, "ADB/m_adb_kmstatus"); - save_item(m_adb_latent_result, "ADB/m_adb_latent_result"); - save_item(m_adb_command_length, "ADB/m_adb_command_length"); - save_item(m_adb_command_pos, "ADB/m_adb_command_pos"); - save_item(m_adb_response_length, "ADB/m_adb_response_length"); - save_item(m_adb_response_pos, "ADB/m_adb_response_pos"); - save_item(m_adb_address_keyboard, "ADB/m_adb_address_keyboard"); - save_item(m_adb_address_mouse, "ADB/m_adb_address_mouse"); -#endif - save_item(m_sndglu_ctrl, "SNDGLUCTRL"); - save_item(m_sndglu_addr, "SNDGLUADDR"); - save_item(m_sndglu_dummy_read, "SNDGLUDUMMYRD"); - - save_item(m_echo_bank, "ECHOBANK"); - - m_clock_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_clock_tick),this)); - m_clock_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1)); - - m_qsecond_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_qsecond_tick),this)); - m_qsecond_timer->adjust(attotime::from_usec(266700), 0, attotime::from_usec(266700)); - - m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_scanline_tick),this)); - m_scanline_timer->adjust(attotime::never); - - // fire on scanline zero - m_scanline_timer->adjust(m_screen->time_until_pos(0, 0)); -} - -MACHINE_START_MEMBER(apple2gs_state,apple2gs) -{ - MACHINE_START_CALL_MEMBER(apple2gscommon); - apple2gs_setup_memory(); -} - -MACHINE_START_MEMBER(apple2gs_state,apple2gsr1) -{ - MACHINE_START_CALL_MEMBER(apple2gscommon); - - m_is_rom3 = false; - apple2gs_setup_memory(); -} - -void apple2gs_state::apple2gs_refresh_delegates() -{ - write_delegates_2gs0400[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux0400_w), this); - write_delegates_2gs0400[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main0400_w), this); - write_delegates_2gs2000[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux2000_w), this); - write_delegates_2gs2000[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main2000_w), this); - write_delegates_2gs4000[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux4000_w), this); - write_delegates_2gs4000[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main4000_w), this); -} - -/* ----------------------------------------------------------------------- - * Keym_glu / low-level ADB emulation - * ----------------------------------------------------------------------- */ -#if RUN_ADB_MICRO -uint8_t apple2gs_state::keyglu_mcu_read(uint8_t offset) -{ - uint8_t rv = m_glu_regs[offset]; - -// printf("MCU reads reg %x\n", offset); - - // the command full flag is cleared by the MCU reading - // first the KGS register and then the command register - if ((offset == GLU_COMMAND) && (m_glu_mcu_read_kgs)) - { - m_glu_regs[GLU_KG_STATUS] &= ~KGS_COMMAND_FULL; - m_glu_mcu_read_kgs = false; -// printf("MCU reads COMMAND = %02x (drop command full)\n", rv); - } - - // prime for the next command register read to clear the command full flag - if (offset == GLU_KG_STATUS) - { - m_glu_mcu_read_kgs = true; - } - - return rv; -} - -void apple2gs_state::keyglu_mcu_write(uint8_t offset, uint8_t data) -{ - m_glu_regs[offset] = data; - -// printf("MCU writes %02x to reg %x\n", data, offset); - - switch (offset) - { - case GLU_MOUSEX: - case GLU_MOUSEY: - m_glu_regs[GLU_KG_STATUS] |= KGS_MOUSEX_FULL; - m_glu_mouse_read_stat = false; // signal next read will be mouse X - break; - - case GLU_ANY_KEY_DOWN: // bit 7 is the actual flag here; both MCU programs write either 0x7f or 0xff -// printf("%d to ANY_KEY_DOWN (PC=%x)\n", data, m_adbmicro->pc()); - if (data & 0x80) - { - m_glu_regs[GLU_KG_STATUS] |= KGS_ANY_KEY_DOWN | KGS_KEYSTROBE; - } - break; - - case GLU_DATA: - m_glu_regs[GLU_KG_STATUS] |= KGS_DATA_FULL; - m_glu_816_read_dstat = false; -// printf("MCU writes %02x to DATA\n", data); - break; - } -} - -/* - Keym_glu registers map as follows on the 816: - - C000 = key data + any key down, clears strobe - C010 = clears keystrobe - - C024 MOUSEDATA = reads GLU mouseX and mouseY - C025 KEYMODREG = reads GLU keymod register - C026 DATAREG = writes from the 816 go to COMMAND, reads from DATA - C027 KMSTATUS = GLU system status register - -*/ -uint8_t apple2gs_state::keyglu_816_read(uint8_t offset) -{ - switch (offset) - { - case GLU_C000: - { - uint8_t rv; - rv = m_glu_regs[GLU_KEY_DATA] & 0x7f; - if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) - { - rv |= 0x80; - } - return rv; - } - break; - - case GLU_C010: - { - uint8_t rv; - rv = m_glu_regs[GLU_KEY_DATA] & 0x7f; - if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) - { - rv |= 0x80; - } - m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE; - return rv; - } - break; - - case GLU_MOUSEX: - case GLU_MOUSEY: - if (!m_glu_mouse_read_stat) - { - m_glu_mouse_read_stat = 1; - return m_glu_regs[GLU_MOUSEY]; - } - return m_glu_regs[GLU_MOUSEX]; - - case GLU_SYSSTAT: - // regenerate sysstat bits - m_glu_sysstat &= ~0xab; // mask off read/write bits - if (m_glu_regs[GLU_KG_STATUS] & KGS_COMMAND_FULL) - { - m_glu_sysstat |= 1; - } - if (m_glu_regs[GLU_KG_STATUS] & m_glu_mouse_read_stat) - { - m_glu_sysstat |= 2; - } - if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE) - { - m_glu_sysstat |= 8; - } - if (m_glu_regs[GLU_KG_STATUS] & KGS_DATA_FULL) - { - m_glu_sysstat |= 0x20; - } - if (m_glu_regs[GLU_KG_STATUS] & KGS_MOUSEX_FULL) - { - m_glu_sysstat |= 0x80; - } - m_glu_816_read_dstat = true; -// printf("816 gets %02x in sysstat (data avail %02x)\n", m_glu_sysstat, m_glu_sysstat & 0x20); - return m_glu_sysstat; - - case GLU_DATA: - if (m_glu_816_read_dstat) - { - m_glu_816_read_dstat = false; - m_glu_regs[GLU_KG_STATUS] &= ~KGS_DATA_FULL; -// printf("816 reads %02x from DATA\n", m_glu_regs[GLU_DATA]); - } - return m_glu_regs[GLU_DATA]; - - default: - return m_glu_regs[offset]; - break; - } - - return 0xff; -} - -void apple2gs_state::keyglu_816_write(uint8_t offset, uint8_t data) -{ - if (offset < GLU_C000) - { - m_glu_regs[offset&7] = data; - } - - switch (offset) - { - case GLU_C010: - m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE; - break; - - case GLU_COMMAND: -// printf("816 sets COMMAND to %02x (raise command full)\n", data); - m_glu_regs[GLU_KG_STATUS] |= KGS_COMMAND_FULL; - break; - - case GLU_SYSSTAT: - m_glu_sysstat &= 0xab; // clear the non-read-only fields - m_glu_sysstat |= (data & ~0xab); - break; - } -} -#endif diff --git a/src/mame/video/apple2.cpp b/src/mame/video/apple2.cpp index 180ee08aaa0..3b59b09b463 100644 --- a/src/mame/video/apple2.cpp +++ b/src/mame/video/apple2.cpp @@ -193,7 +193,48 @@ inline void apple2_state::apple2_plot_text_character(bitmap_ind16 &bitmap, int x } } +void a2_video_device::plot_text_characterGS(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 (!m_altcharset) + { + if ((code >= 0x40) && (code <= 0x7f)) + { + code &= 0x3f; + + if (m_flash) + { + i = fg; + fg = bg; + bg = i; + } + } + } + else + { + code |= 0x100; + } + + /* 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 << x)) ? bg : fg; + + for (i = 0; i < xscale; i++) + { + bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color; + } + } + } +} /*------------------------------------------------- apple2_text_draw - renders text (either 40 @@ -1637,3 +1678,263 @@ PALETTE_INIT_MEMBER(a2_video_device, apple2) { palette.set_pen_colors(0, apple2_palette, ARRAY_LENGTH(apple2_palette)); } + +uint32_t a2_video_device::screen_update_GS(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const uint8_t *vram; + uint32_t *scanline; + uint8_t scb, b; + int col, palette; + uint32_t last_pixel = 0, pixel; + int beamy; + uint16_t *a2pixel; + + beamy = cliprect.min_y; + + if (m_newvideo & 0x80) + { + // in top or bottom border? + if ((beamy < BORDER_TOP) || (beamy >= 200+BORDER_TOP)) + { + // don't draw past the bottom border + if (beamy >= 231+BORDER_TOP) + { + return 0; + } + + scanline = &bitmap.pix32(beamy); + for (col = 0; col < BORDER_LEFT+BORDER_RIGHT+640; col++) + { + scanline[col] = m_GSborder_colors[m_GSborder]; + } + } + else // regular screen area + { + int shrline = beamy - BORDER_TOP; + + scb = m_aux_ptr[0x9D00 + shrline]; + palette = ((scb & 0x0f) << 4); + + vram = &m_aux_ptr[0x2000 + (shrline * 160)]; + scanline = &bitmap.pix32(beamy); + + // draw left and right borders + for (col = 0; col < BORDER_LEFT; col++) + { + scanline[col] = m_GSborder_colors[m_GSborder]; + scanline[col+BORDER_LEFT+640] = m_GSborder_colors[m_GSborder]; + } + + if (scb & 0x80) // 640 mode + { + for (col = 0; col < 160; col++) + { + b = vram[col]; + scanline[col * 4 + 0 + BORDER_LEFT] = m_shr_palette[palette + 0 + ((b >> 6) & 0x03)]; + scanline[col * 4 + 1 + BORDER_LEFT] = m_shr_palette[palette + 4 + ((b >> 4) & 0x03)]; + scanline[col * 4 + 2 + BORDER_LEFT] = m_shr_palette[palette + 8 + ((b >> 2) & 0x03)]; + scanline[col * 4 + 3 + BORDER_LEFT] = m_shr_palette[palette + 12 + ((b >> 0) & 0x03)]; + } + } + else // 320 mode + { + for (col = 0; col < 160; col++) + { + b = vram[col]; + pixel = (b >> 4) & 0x0f; + + if ((scb & 0x20) && !pixel) + pixel = last_pixel; + else + last_pixel = pixel; + pixel += palette; + scanline[col * 4 + 0 + BORDER_LEFT] = m_shr_palette[pixel]; + scanline[col * 4 + 1 + BORDER_LEFT] = m_shr_palette[pixel]; + + b = vram[col]; + pixel = (b >> 0) & 0x0f; + + if ((scb & 0x20) && !pixel) + pixel = last_pixel; + else + last_pixel = pixel; + pixel += palette; + scanline[col * 4 + 2 + BORDER_LEFT] = m_shr_palette[pixel]; + scanline[col * 4 + 3 + BORDER_LEFT] = m_shr_palette[pixel]; + } + } + } + } + else + { + /* call legacy Apple II video rendering at scanline 0 to draw into the off-screen buffer */ + if (beamy == 0) + { + rectangle new_cliprect(0, 559, 0, 191); + screen_update_GS_8bit(screen, *m_8bit_graphics, new_cliprect); + } + + if ((beamy < (BORDER_TOP+4)) || (beamy >= (192+4+BORDER_TOP))) + { + if (beamy >= (231+BORDER_TOP)) + { + return 0; + } + + scanline = &bitmap.pix32(beamy); + for (col = 0; col < BORDER_LEFT+BORDER_RIGHT+640; col++) + { + scanline[col] = m_GSborder_colors[m_GSborder]; + } + } + else + { + scanline = &bitmap.pix32(beamy); + + // draw left and right borders + for (col = 0; col < BORDER_LEFT + 40; col++) + { + scanline[col] = m_GSborder_colors[m_GSborder]; + scanline[col+BORDER_LEFT+600] = m_GSborder_colors[m_GSborder]; + } + + a2pixel = &m_8bit_graphics->pix16(beamy-(BORDER_TOP+4)); + for (int x = 0; x < 560; x++) + { + scanline[40 + BORDER_LEFT + x] = m_GSborder_colors[*a2pixel++]; + } + } + } + return 0; +} + +uint32_t a2_video_device::screen_update_GS_8bit(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + bool old_page2 = m_page2; + + // don't display page2 if 80store is set (we just saved the previous value, don't worry) + if (m_80store) + { + m_page2 = false; + } + + // 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_hires) + { + if (m_mix) + { + if ((m_dhires) && (m_80col)) + { + dhgr_update(screen, bitmap, cliprect, 0, 159); + } + else + { + hgr_update(screen, bitmap, cliprect, 0, 159); + } + text_updateGS(screen, bitmap, cliprect, 160, 191); + } + else + { + if ((m_dhires) && (m_80col)) + { + dhgr_update(screen, bitmap, cliprect, 0, 191); + } + else + { + hgr_update(screen, bitmap, cliprect, 0, 191); + } + } + } + else // lo-res + { + if (m_mix) + { + if ((m_dhires) && (m_80col)) + { + dlores_update(screen, bitmap, cliprect, 0, 159); + } + else + { + lores_update(screen, bitmap, cliprect, 0, 159); + } + + text_updateGS(screen, bitmap, cliprect, 160, 191); + } + else + { + if ((m_dhires) && (m_80col)) + { + dlores_update(screen, bitmap, cliprect, 0, 191); + } + else + { + lores_update(screen, bitmap, cliprect, 0, 191); + } + } + } + } + else + { + text_updateGS(screen, bitmap, cliprect, 0, 191); + } + + m_page2 = old_page2; + + return 0; +} + +void a2_video_device::text_updateGS(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col; + uint32_t start_address; + uint32_t address; + uint8_t *aux_page = m_ram_ptr; + + if (m_80col) + { + start_address = 0x400; + if (m_aux_ptr) + { + aux_page = m_aux_ptr; + } + } + else + { + start_address = m_page2 ? 0x800 : 0x400; + } + + 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) + { + if (m_80col) + { + for (col = 0; col < 40; col++) + { + /* calculate address */ + address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)); + + plot_text_characterGS(bitmap, col * 14, row, 1, aux_page[address], + m_char_ptr, m_char_size, m_GSfg, m_GSbg); + plot_text_characterGS(bitmap, col * 14 + 7, row, 1, m_ram_ptr[address], + m_char_ptr, m_char_size, m_GSfg, m_GSbg); + } + } + else + { + for (col = 0; col < 40; col++) + { + /* calculate address */ + address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)); + plot_text_characterGS(bitmap, col * 14, row, 2, m_ram_ptr[address], + m_char_ptr, m_char_size, m_GSfg, m_GSbg); + } + } + } +} + diff --git a/src/mame/video/apple2.h b/src/mame/video/apple2.h index 83d7128ebe6..93326c1cd43 100644 --- a/src/mame/video/apple2.h +++ b/src/mame/video/apple2.h @@ -11,6 +11,10 @@ #include "emupal.h" +#define BORDER_LEFT (32) +#define BORDER_RIGHT (32) +#define BORDER_TOP (16) // (plus bottom) + class a2_video_device : public device_t { @@ -29,8 +33,11 @@ public: bool m_80col; bool m_altcharset; bool m_an2; + bool m_80store; bool m_monohgr; - + uint8_t m_GSfg, m_GSbg, m_GSborder, m_newvideo, m_monochrome; + uint32_t m_GSborder_colors[16], m_shr_palette[256]; + std::unique_ptr<bitmap_ind16> m_8bit_graphics; std::unique_ptr<uint16_t[]> m_hires_artifact_map; std::unique_ptr<uint16_t[]> m_dhires_artifact_map; @@ -43,12 +50,16 @@ public: void text_update_ultr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); void text_update_orig(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); void text_update_jplus(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + void text_updateGS(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); void lores_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); void dlores_update(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); void hgr_update_tk2000(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); void dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + uint32_t screen_update_GS(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t screen_update_GS_8bit(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + protected: virtual void device_reset() override; virtual void device_start() override; @@ -58,6 +69,7 @@ private: void plot_text_character_ultr(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_orig(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_jplus(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_characterGS(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); }; // device type definition diff --git a/src/mame/video/apple2gs.cpp b/src/mame/video/apple2gs.cpp deleted file mode 100644 index 2f10133e7e3..00000000000 --- a/src/mame/video/apple2gs.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods,R. Belmont -/********************************************************************* - - video/apple2gs.c - - Apple IIgs video code - -*********************************************************************/ - - -#include "emu.h" -#include "includes/apple2.h" -#include "includes/apple2gs.h" - - - -VIDEO_START_MEMBER(apple2gs_state,apple2gs) -{ - m_bordercolor = 0; - apple2_video_start(m_slowmem.get(), m_slowmem.get()+0x10000, 0, 8); - m_legacy_gfx = std::make_unique<bitmap_ind16>(560, 192); - - save_item(m_bordercolor, "BORDERCLR"); - save_item(NAME(m_fgcolor)); - save_item(NAME(m_bgcolor)); -} - - - -uint32_t apple2gs_state::screen_update_apple2gs(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - const uint8_t *vram; - uint32_t *scanline; - uint8_t scb, b; - int col, palette; - uint32_t last_pixel = 0, pixel; - int beamy; - uint16_t *a2pixel; - - beamy = cliprect.min_y; - - if (m_newvideo & 0x80) - { - // in top or bottom border? - if ((beamy < BORDER_TOP) || (beamy >= 200+BORDER_TOP)) - { - // don't draw past the bottom border - if (beamy >= 231+BORDER_TOP) - { - return 0; - } - - scanline = &bitmap.pix32(beamy); - for (col = 0; col < BORDER_LEFT+BORDER_RIGHT+640; col++) - { - scanline[col] = m_a2_palette[m_bordercolor]; - } - } - else // regular screen area - { - int shrline = beamy - BORDER_TOP; - - scb = m_slowmem[0x19D00 + shrline]; - palette = ((scb & 0x0f) << 4); - - vram = &m_slowmem[0x12000 + (shrline * 160)]; - scanline = &bitmap.pix32(beamy); - - // draw left and right borders - for (col = 0; col < BORDER_LEFT; col++) - { - scanline[col] = m_a2_palette[m_bordercolor]; - scanline[col+BORDER_LEFT+640] = m_a2_palette[m_bordercolor]; - } - - if (scb & 0x80) // 640 mode - { - for (col = 0; col < 160; col++) - { - b = vram[col]; - scanline[col * 4 + 0 + BORDER_LEFT] = m_shr_palette[palette + 0 + ((b >> 6) & 0x03)]; - scanline[col * 4 + 1 + BORDER_LEFT] = m_shr_palette[palette + 4 + ((b >> 4) & 0x03)]; - scanline[col * 4 + 2 + BORDER_LEFT] = m_shr_palette[palette + 8 + ((b >> 2) & 0x03)]; - scanline[col * 4 + 3 + BORDER_LEFT] = m_shr_palette[palette + 12 + ((b >> 0) & 0x03)]; - } - } - else // 320 mode - { - for (col = 0; col < 160; col++) - { - b = vram[col]; - pixel = (b >> 4) & 0x0f; - - if ((scb & 0x20) && !pixel) - pixel = last_pixel; - else - last_pixel = pixel; - pixel += palette; - scanline[col * 4 + 0 + BORDER_LEFT] = m_shr_palette[pixel]; - scanline[col * 4 + 1 + BORDER_LEFT] = m_shr_palette[pixel]; - - b = vram[col]; - pixel = (b >> 0) & 0x0f; - - if ((scb & 0x20) && !pixel) - pixel = last_pixel; - else - last_pixel = pixel; - pixel += palette; - scanline[col * 4 + 2 + BORDER_LEFT] = m_shr_palette[pixel]; - scanline[col * 4 + 3 + BORDER_LEFT] = m_shr_palette[pixel]; - } - } - } - } - else - { - /* call legacy Apple II video rendering at scanline 0 to draw into the off-screen buffer */ - if (beamy == 0) - { - // check if DHR should be monochrome 560x192 - if (m_newvideo & 0x20) - { - m_monochrome_dhr = true; - } - else - { - m_monochrome_dhr = false; - } - - rectangle new_cliprect(0, 559, 0, 191); - screen_update_apple2(screen, *m_legacy_gfx, new_cliprect); - } - - if ((beamy < (BORDER_TOP+4)) || (beamy >= (192+4+BORDER_TOP))) - { - if (beamy >= (231+BORDER_TOP)) - { - return 0; - } - - scanline = &bitmap.pix32(beamy); - for (col = 0; col < BORDER_LEFT+BORDER_RIGHT+640; col++) - { - scanline[col] = m_a2_palette[m_bordercolor]; - } - } - else - { - scanline = &bitmap.pix32(beamy); - - // draw left and right borders - for (col = 0; col < BORDER_LEFT + 40; col++) - { - scanline[col] = m_a2_palette[m_bordercolor]; - scanline[col+BORDER_LEFT+600] = m_a2_palette[m_bordercolor]; - } - - a2pixel = &m_legacy_gfx->pix16(beamy-(BORDER_TOP+4)); - for (int x = 0; x < 560; x++) - { - scanline[40 + BORDER_LEFT + x] = m_a2_palette[*a2pixel++]; - } - } - } - return 0; -} |