src/mess/machine/a2scsi.c
| r0 | r14867 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | a2scsi.c |
| 4 | |
| 5 | Implementation of the Apple II SCSI Card |
| 6 | |
| 7 | Schematic at: |
| 8 | http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/SCSI%20Controllers/Apple%20II%20SCSI%20Card/Schematics/Rev.%20C%20SCSI%20Schematic%20-%20Updated%202-23-6.jpg |
| 9 | |
| 10 | |
| 11 | Notes: |
| 12 | |
| 13 | PAL U3C: |
| 14 | I1 = A0 |
| 15 | I2 = A1 |
| 16 | I3 = A2 |
| 17 | I4 = A3 |
| 18 | I5 = O2 of PAL U3D |
| 19 | I6 = (logic maze) |
| 20 | I7 = R/W (also I7 of PAL U3D) |
| 21 | I8 = PHI0 (via flip flops) |
| 22 | I9 = RESET |
| 23 | I10 = GND |
| 24 | |
| 25 | O1 = P on flip-flops U6DA/U6DB, I8 on PAL U3D |
| 26 | O2 = N/C |
| 27 | O3 = I6 on PAL U3D |
| 28 | O4 = N/C |
| 29 | O5 = /CS on NCR 5380 |
| 30 | O6 = /WR on NCR 5380 |
| 31 | O7 = /RD on NCR 5380 |
| 32 | O8 = /DACK on NCR 5380 |
| 33 | |
| 34 | PAL U3D: |
| 35 | I1 = A0-A10 NANDed together (goes low on CFFF access, i.e.) |
| 36 | I2 = /IOSTB |
| 37 | I3 = /IOSEL |
| 38 | I4 = RESET |
| 39 | I5 = A10 (splits C800 space at C800/CC00) |
| 40 | I6 = O3 of PAL U3C |
| 41 | I7 = R/W |
| 42 | I8 = O1 of PAL U3C |
| 43 | I9 = DRQ from 5380 |
| 44 | I10 = Y6 from 74LS138 at U3D (C0n6 access) |
| 45 | |
| 46 | O1 = G on 74LS245 main data bus buffer |
| 47 | O2 = I5 of PAL U3C |
| 48 | O3 = D to flip-flop at U6DB |
| 49 | O4 = CLK to flip-flop at U6DA |
| 50 | O5 = D7 (?) |
| 51 | O6 = CS1 on RAM |
| 52 | O7 = EPROM CE |
| 53 | O8 = EPROM OE |
| 54 | |
| 55 | *********************************************************************/ |
| 56 | |
| 57 | #include "a2scsi.h" |
| 58 | #include "includes/apple2.h" |
| 59 | |
| 60 | |
| 61 | /*************************************************************************** |
| 62 | PARAMETERS |
| 63 | ***************************************************************************/ |
| 64 | |
| 65 | //************************************************************************** |
| 66 | // GLOBAL VARIABLES |
| 67 | //************************************************************************** |
| 68 | |
| 69 | const device_type A2BUS_SCSI = &device_creator<a2bus_scsi_device>; |
| 70 | |
| 71 | #define SCSI_ROM_REGION "scsi_rom" |
| 72 | #define SCSI_5380_TAG "ncr5380" |
| 73 | |
| 74 | static const SCSIConfigTable dev_table = |
| 75 | { |
| 76 | 0, /* 2 SCSI devices */ |
| 77 | { |
| 78 | // { SCSI_ID_6, "harddisk1", SCSI_DEVICE_HARDDISK }, /* SCSI ID 6, using disk1, and it's a harddisk */ |
| 79 | // { SCSI_ID_5, "harddisk2", SCSI_DEVICE_HARDDISK } /* SCSI ID 5, using disk2, and it's a harddisk */ |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | static const struct NCR5380interface a2scsi_5380_intf = |
| 84 | { |
| 85 | &dev_table, // SCSI device table |
| 86 | NULL // IRQ handler (unconnected according to schematic) |
| 87 | }; |
| 88 | |
| 89 | MACHINE_CONFIG_FRAGMENT( scsi ) |
| 90 | MCFG_NCR5380_ADD(SCSI_5380_TAG, (XTAL_28_63636MHz/4), a2scsi_5380_intf) |
| 91 | MACHINE_CONFIG_END |
| 92 | |
| 93 | ROM_START( scsi ) |
| 94 | ROM_REGION(0x4000, SCSI_ROM_REGION, 0) // this is the Rev. C ROM |
| 95 | ROM_LOAD( "341-0437-a.bin", 0x0000, 0x4000, CRC(5aff85d3) SHA1(451c85c46b92e6ad2ad930f055ccf0fe3049936d) ) |
| 96 | ROM_END |
| 97 | |
| 98 | /*************************************************************************** |
| 99 | FUNCTION PROTOTYPES |
| 100 | ***************************************************************************/ |
| 101 | |
| 102 | //------------------------------------------------- |
| 103 | // machine_config_additions - device-specific |
| 104 | // machine configurations |
| 105 | //------------------------------------------------- |
| 106 | |
| 107 | machine_config_constructor a2bus_scsi_device::device_mconfig_additions() const |
| 108 | { |
| 109 | return MACHINE_CONFIG_NAME( scsi ); |
| 110 | } |
| 111 | |
| 112 | //------------------------------------------------- |
| 113 | // rom_region - device-specific ROM region |
| 114 | //------------------------------------------------- |
| 115 | |
| 116 | const rom_entry *a2bus_scsi_device::device_rom_region() const |
| 117 | { |
| 118 | return ROM_NAME( scsi ); |
| 119 | } |
| 120 | |
| 121 | //************************************************************************** |
| 122 | // LIVE DEVICE |
| 123 | //************************************************************************** |
| 124 | |
| 125 | a2bus_scsi_device::a2bus_scsi_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 126 | device_t(mconfig, type, name, tag, owner, clock), |
| 127 | device_a2bus_card_interface(mconfig, *this) |
| 128 | { |
| 129 | m_shortname = "a2scsi"; |
| 130 | } |
| 131 | |
| 132 | a2bus_scsi_device::a2bus_scsi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 133 | device_t(mconfig, A2BUS_SCSI, "Apple II SCSI Card", tag, owner, clock), |
| 134 | device_a2bus_card_interface(mconfig, *this) |
| 135 | { |
| 136 | m_shortname = "a2scsi"; |
| 137 | } |
| 138 | |
| 139 | //------------------------------------------------- |
| 140 | // device_start - device-specific startup |
| 141 | //------------------------------------------------- |
| 142 | |
| 143 | void a2bus_scsi_device::device_start() |
| 144 | { |
| 145 | // set_a2bus_device makes m_slot valid |
| 146 | set_a2bus_device(); |
| 147 | |
| 148 | astring tempstring; |
| 149 | m_rom = device().machine().region(this->subtag(tempstring, SCSI_ROM_REGION))->base(); |
| 150 | |
| 151 | memset(m_ram, 0, 8192); |
| 152 | } |
| 153 | |
| 154 | void a2bus_scsi_device::device_reset() |
| 155 | { |
| 156 | m_rambank = m_rombank = 0; // CLR on 74LS273 at U3E is connected to RES, so these clear on reset |
| 157 | } |
| 158 | |
| 159 | |
| 160 | /*------------------------------------------------- |
| 161 | read_c0nx - called for reads from this card's c0nx space |
| 162 | -------------------------------------------------*/ |
| 163 | |
| 164 | /* |
| 165 | |
| 166 | From schematic (decoded by 74LS138 at U2D) |
| 167 | |
| 168 | C0n1/9 = DIP switches |
| 169 | C0n2/a = clock to 74LS273 bank switcher (so data here should be the bank) |
| 170 | C0n3/b = reset 5380 |
| 171 | C0n6/e = into the PAL stuff |
| 172 | |
| 173 | */ |
| 174 | |
| 175 | UINT8 a2bus_scsi_device::read_c0nx(address_space &space, UINT8 offset) |
| 176 | { |
| 177 | printf("Read c0n%x (PC=%x)\n", offset, cpu_get_pc(&space.device())); |
| 178 | |
| 179 | return 0xff; |
| 180 | } |
| 181 | |
| 182 | |
| 183 | /*------------------------------------------------- |
| 184 | write_c0nx - called for writes to this card's c0nx space |
| 185 | -------------------------------------------------*/ |
| 186 | |
| 187 | void a2bus_scsi_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data) |
| 188 | { |
| 189 | printf("Write %02x to c0n%x (PC=%x)\n", data, offset, cpu_get_pc(&space.device())); |
| 190 | |
| 191 | switch (offset & 7) |
| 192 | { |
| 193 | case 0x2: // ROM and RAM banking (74LS273 at U3E) |
| 194 | /* |
| 195 | ROM banking: |
| 196 | (bits EA8-EA13 are all zeroed when /IOSEL is asserted, so CnXX always gets the first page of the ROM) |
| 197 | EA10 = bit 0 |
| 198 | EA11 = bit 1 |
| 199 | EA12 = bit 2 |
| 200 | EA13 = bit 3 (N/C) |
| 201 | |
| 202 | RAM banking: |
| 203 | RA10 = bit 4 |
| 204 | RA11 = bit 5 |
| 205 | RA12 = bit 6 |
| 206 | */ |
| 207 | |
| 208 | m_rambank = ((data>>4) & 0x7) * 0x400; |
| 209 | m_rombank = (data & 0xf) * 0x400; |
| 210 | printf("RAM bank to %x, ROM bank to %x\n", m_rambank, m_rombank); |
| 211 | break; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | /*------------------------------------------------- |
| 216 | read_cnxx - called for reads from this card's cnxx space |
| 217 | -------------------------------------------------*/ |
| 218 | |
| 219 | UINT8 a2bus_scsi_device::read_cnxx(address_space &space, UINT8 offset) |
| 220 | { |
| 221 | // one slot image at the start of the ROM, it appears |
| 222 | return m_rom[offset]; |
| 223 | } |
| 224 | |
| 225 | void a2bus_scsi_device::write_cnxx(address_space &space, UINT8 offset, UINT8 data) |
| 226 | { |
| 227 | printf("Write %02x to cn%02x (PC=%x)\n", data, offset, cpu_get_pc(&space.device())); |
| 228 | } |
| 229 | |
| 230 | /*------------------------------------------------- |
| 231 | read_c800 - called for reads from this card's c800 space |
| 232 | -------------------------------------------------*/ |
| 233 | |
| 234 | UINT8 a2bus_scsi_device::read_c800(address_space &space, UINT16 offset) |
| 235 | { |
| 236 | // bankswitched RAM at c800-cbff |
| 237 | // bankswitched ROM at cc00-cfff |
| 238 | if (offset < 0x400) |
| 239 | { |
| 240 | printf("Read RAM at %x = %02x\n", offset+m_rambank, m_ram[offset + m_rambank]); |
| 241 | return m_ram[offset + m_rambank]; |
| 242 | } |
| 243 | else |
| 244 | { |
| 245 | return m_rom[(offset-0x400) + m_rombank]; |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | /*------------------------------------------------- |
| 250 | write_c800 - called for writes to this card's c800 space |
| 251 | -------------------------------------------------*/ |
| 252 | void a2bus_scsi_device::write_c800(address_space &space, UINT16 offset, UINT8 data) |
| 253 | { |
| 254 | if (offset < 0x400) |
| 255 | { |
| 256 | printf("%02x to RAM at %x\n", data, offset+m_rambank); |
| 257 | m_ram[offset + m_rambank] = data; |
| 258 | } |
| 259 | } |
src/mess/machine/a2scsi.h
| r0 | r14867 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | a2scsi.h |
| 4 | |
| 5 | Implementation of the Apple II Memory Expansion Card |
| 6 | |
| 7 | *********************************************************************/ |
| 8 | |
| 9 | #ifndef __A2BUS_SCSI__ |
| 10 | #define __A2BUS_SCSI__ |
| 11 | |
| 12 | #include "emu.h" |
| 13 | #include "machine/a2bus.h" |
| 14 | #include "machine/ncr5380.h" |
| 15 | |
| 16 | //************************************************************************** |
| 17 | // TYPE DEFINITIONS |
| 18 | //************************************************************************** |
| 19 | |
| 20 | class a2bus_scsi_device: |
| 21 | public device_t, |
| 22 | public device_a2bus_card_interface |
| 23 | { |
| 24 | public: |
| 25 | // construction/destruction |
| 26 | a2bus_scsi_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 27 | a2bus_scsi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 28 | |
| 29 | // optional information overrides |
| 30 | virtual machine_config_constructor device_mconfig_additions() const; |
| 31 | virtual const rom_entry *device_rom_region() const; |
| 32 | |
| 33 | protected: |
| 34 | virtual void device_start(); |
| 35 | virtual void device_reset(); |
| 36 | |
| 37 | // overrides of standard a2bus slot functions |
| 38 | virtual UINT8 read_c0nx(address_space &space, UINT8 offset); |
| 39 | virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data); |
| 40 | virtual UINT8 read_cnxx(address_space &space, UINT8 offset); |
| 41 | virtual void write_cnxx(address_space &space, UINT8 offset, UINT8 data); |
| 42 | virtual UINT8 read_c800(address_space &space, UINT16 offset); |
| 43 | virtual void write_c800(address_space &space, UINT16 offset, UINT8 data); |
| 44 | |
| 45 | private: |
| 46 | UINT8 *m_rom; |
| 47 | UINT8 m_ram[8192]; // 8 banks of 1024 bytes |
| 48 | int m_rambank, m_rombank; |
| 49 | }; |
| 50 | |
| 51 | // device type definition |
| 52 | extern const device_type A2BUS_SCSI; |
| 53 | |
| 54 | #endif /* __A2BUS_SCSI__ */ |
| 55 | |
src/mess/machine/a2bus.c
| r14866 | r14867 | |
| 3 | 3 | a2bus.c - Apple II slot bus and card emulation |
| 4 | 4 | |
| 5 | 5 | by R. Belmont |
| 6 | | |
| 6 | |
| 7 | Pinout (/ indicates an inverted signal, ie, one that would have a bar over it |
| 8 | on a schematic diagram) |
| 9 | |
| 10 | (rear of computer) |
| 11 | |
| 12 | GND 26 25 +5V |
| 13 | DMA IN 27 24 DMA OUT |
| 14 | INT IN 28 23 INT OUT |
| 15 | /NMI 29 22 /DMA |
| 16 | /IRQ 30 21 RDY |
| 17 | /RES 31 20 /IOSTB |
| 18 | /INH 32 19 N.C. |
| 19 | -12V 33 18 R/W |
| 20 | -5V 34 17 A15 |
| 21 | N.C. 35 16 A14 |
| 22 | 7M 36 15 A13 |
| 23 | Q3 37 14 A12 |
| 24 | PH1 38 13 A11 |
| 25 | USER 1 39 12 A10 |
| 26 | PH0 40 11 A9 |
| 27 | /DEVSEL 41 10 A8 |
| 28 | D7 42 9 A7 |
| 29 | D6 43 8 A6 |
| 30 | D5 44 7 A5 |
| 31 | D4 45 6 A4 |
| 32 | D3 46 5 A3 |
| 33 | D2 47 4 A2 |
| 34 | D1 48 3 A1 |
| 35 | D0 49 2 A0 |
| 36 | -12V 50 1 /IOSEL |
| 37 | |
| 38 | (front of computer) |
| 39 | |
| 40 | Signal descriptions: |
| 41 | GND - power supply ground |
| 42 | DMA IN - daisy chain of DMA signal from higher priority devices. usually connected to DMA OUT. |
| 43 | INT IN - similar to DMA IN but for INT instead of DMA. |
| 44 | /NMI - non-maskable interrupt input to the 6502 |
| 45 | /IRQ - maskable interrupt input to the 6502 |
| 46 | /RES - system reset signal |
| 47 | /INH - On the II and II+, inhibits the motherboard ROMs, allowing a card to replace them. |
| 48 | On the IIe, inhibits all motherboard RAM/ROM for both CPU and DMA accesses. |
| 49 | On the IIgs, works like the IIe except for the address range 0x6000 to 0x9FFF where |
| 50 | it will cause bus contention. |
| 51 | -12V - negative 12 volts DC power |
| 52 | -5V - negative 5 volts DC power |
| 53 | 7M - 7 MHz clock (1/4th of the master clock on the IIgs, 1/2 on 8-bit IIs) |
| 54 | Q3 - 2 MHz asymmetrical clock |
| 55 | PH1 - 6502 phase 1 clock |
| 56 | /DEVSEL - asserted on an access to C0nX, where n = the slot number plus 8. |
| 57 | D0-D7 - 8-bit data bus |
| 58 | +5V - 5 volts DC power |
| 59 | DMA OUT - see DMA IN |
| 60 | INT OUT - see INT IN |
| 61 | /DMA - pulling this low disconnects the 6502 from the bus and halts it |
| 62 | RDY - 6502 RDY input. Pulling this low when PH1 is active will halt the |
| 63 | 6502 and latch the current address bus value. |
| 64 | /IOSTB - asserted on an access between C800 and CFFF. |
| 65 | A0-A15 - 16-bit address bus |
| 66 | /IOSEL - asserted on accesses to CnXX where n is the slot number. |
| 67 | Not present on slot 0. |
| 68 | |
| 7 | 69 | ***************************************************************************/ |
| 8 | 70 | |
| 9 | 71 | #include "emu.h" |
src/mess/machine/a2bus.h
| r14866 | r14867 | |
| 3 | 3 | a2bus.h - Apple II slot bus and card emulation |
| 4 | 4 | |
| 5 | 5 | by R. Belmont |
| 6 | | |
| 6 | |
| 7 | 7 | ***************************************************************************/ |
| 8 | 8 | |
| 9 | 9 | #pragma once |
| r14866 | r14867 | |
| 126 | 126 | device_a2bus_card_interface(const machine_config &mconfig, device_t &device); |
| 127 | 127 | virtual ~device_a2bus_card_interface(); |
| 128 | 128 | |
| 129 | | virtual UINT8 read_c0nx(address_space &space, UINT8 offset) { return 0; } |
| 130 | | virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data) {} |
| 131 | | virtual UINT8 read_cnxx(address_space &space, UINT8 offset) { return 0; } |
| 132 | | virtual void write_cnxx(address_space &space, UINT8 offset, UINT8 data) {} |
| 133 | | virtual UINT8 read_c800(address_space &space, UINT16 offset) { return 0; } |
| 134 | | virtual void write_c800(address_space &space, UINT16 offset, UINT8 data) {} |
| 129 | virtual UINT8 read_c0nx(address_space &space, UINT8 offset) { return 0; } // C0nX - /DEVSEL |
| 130 | virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data) { printf("a2bus: unhandled write %02x to C0n%x\n", data, offset); } |
| 131 | virtual UINT8 read_cnxx(address_space &space, UINT8 offset) { return 0; } // CnXX - /IOSEL |
| 132 | virtual void write_cnxx(address_space &space, UINT8 offset, UINT8 data) { printf("a2bus: unhandled write %02x to Cn%02x\n", data, offset); } |
| 133 | virtual UINT8 read_c800(address_space &space, UINT16 offset) { return 0; } // C800 - /IOSTB |
| 134 | virtual void write_c800(address_space &space, UINT16 offset, UINT8 data) { printf("a2bus: unhandled write %02x to %04x\n", data, offset + 0xc800); } |
| 135 | 135 | |
| 136 | 136 | device_a2bus_card_interface *next() const { return m_next; } |
| 137 | 137 | |
src/mess/machine/a2memexp.c
| r0 | r14867 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | a2memexp.c |
| 4 | |
| 5 | Implementation of the Apple II Memory Expansion Card |
| 6 | |
| 7 | *********************************************************************/ |
| 8 | |
| 9 | #include "a2memexp.h" |
| 10 | #include "includes/apple2.h" |
| 11 | |
| 12 | |
| 13 | /*************************************************************************** |
| 14 | PARAMETERS |
| 15 | ***************************************************************************/ |
| 16 | |
| 17 | //************************************************************************** |
| 18 | // GLOBAL VARIABLES |
| 19 | //************************************************************************** |
| 20 | |
| 21 | const device_type A2BUS_MEMEXP = &device_creator<a2bus_memexpapple_device>; |
| 22 | |
| 23 | #define MEMEXP_ROM_REGION "memexp_rom" |
| 24 | |
| 25 | MACHINE_CONFIG_FRAGMENT( memexp2 ) |
| 26 | MACHINE_CONFIG_END |
| 27 | |
| 28 | ROM_START( memexp2 ) |
| 29 | ROM_REGION(0x1000, MEMEXP_ROM_REGION, 0) |
| 30 | ROM_LOAD( "341-0344a.bin", 0x0000, 0x1000, CRC(1e994e17) SHA1(6e823a1fa40ed37eeddcef23f5df24da2ea1463e) ) |
| 31 | ROM_END |
| 32 | |
| 33 | /*************************************************************************** |
| 34 | FUNCTION PROTOTYPES |
| 35 | ***************************************************************************/ |
| 36 | |
| 37 | //------------------------------------------------- |
| 38 | // machine_config_additions - device-specific |
| 39 | // machine configurations |
| 40 | //------------------------------------------------- |
| 41 | |
| 42 | machine_config_constructor a2bus_memexp_device::device_mconfig_additions() const |
| 43 | { |
| 44 | return MACHINE_CONFIG_NAME( memexp2 ); |
| 45 | } |
| 46 | |
| 47 | //------------------------------------------------- |
| 48 | // rom_region - device-specific ROM region |
| 49 | //------------------------------------------------- |
| 50 | |
| 51 | const rom_entry *a2bus_memexp_device::device_rom_region() const |
| 52 | { |
| 53 | return ROM_NAME( memexp2 ); |
| 54 | } |
| 55 | |
| 56 | //************************************************************************** |
| 57 | // LIVE DEVICE |
| 58 | //************************************************************************** |
| 59 | |
| 60 | a2bus_memexp_device::a2bus_memexp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 61 | device_t(mconfig, type, name, tag, owner, clock), |
| 62 | device_a2bus_card_interface(mconfig, *this) |
| 63 | { |
| 64 | } |
| 65 | |
| 66 | a2bus_memexpapple_device::a2bus_memexpapple_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 67 | a2bus_memexp_device(mconfig, A2BUS_MEMEXP, "Apple II Memory Expansion Card", tag, owner, clock) |
| 68 | { |
| 69 | m_shortname = "a2memexp"; |
| 70 | } |
| 71 | |
| 72 | //------------------------------------------------- |
| 73 | // device_start - device-specific startup |
| 74 | //------------------------------------------------- |
| 75 | |
| 76 | void a2bus_memexp_device::device_start() |
| 77 | { |
| 78 | // set_a2bus_device makes m_slot valid |
| 79 | set_a2bus_device(); |
| 80 | |
| 81 | astring tempstring; |
| 82 | m_rom = device().machine().region(this->subtag(tempstring, MEMEXP_ROM_REGION))->base(); |
| 83 | |
| 84 | memset(m_ram, 0xff, 1024*1024*sizeof(UINT8)); |
| 85 | } |
| 86 | |
| 87 | void a2bus_memexp_device::device_reset() |
| 88 | { |
| 89 | memset(m_regs, 0, sizeof(UINT8) * 0x10); |
| 90 | m_wptr = m_liveptr = 0; |
| 91 | } |
| 92 | |
| 93 | |
| 94 | /*------------------------------------------------- |
| 95 | read_c0nx - called for reads from this card's c0nx space |
| 96 | -------------------------------------------------*/ |
| 97 | |
| 98 | UINT8 a2bus_memexp_device::read_c0nx(address_space &space, UINT8 offset) |
| 99 | { |
| 100 | UINT8 retval = m_regs[offset]; |
| 101 | |
| 102 | if (offset == 3) |
| 103 | { |
| 104 | retval = m_ram[m_liveptr&0xfffff]; |
| 105 | // printf("Read RAM[%x] = %02x\n", m_liveptr, retval); |
| 106 | m_liveptr++; |
| 107 | m_regs[0] = m_liveptr & 0xff; |
| 108 | m_regs[1] = (m_liveptr>>8) & 0xff; |
| 109 | m_regs[2] = ((m_liveptr>>16) & 0xff) | 0xf0; |
| 110 | } |
| 111 | |
| 112 | // printf("Read c0n%x (PC=%x) = %02x\n", offset, cpu_get_pc(&space.device()), retval); |
| 113 | |
| 114 | return retval; |
| 115 | } |
| 116 | |
| 117 | |
| 118 | /*------------------------------------------------- |
| 119 | write_c0nx - called for writes to this card's c0nx space |
| 120 | -------------------------------------------------*/ |
| 121 | |
| 122 | void a2bus_memexp_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data) |
| 123 | { |
| 124 | // printf("Write %02x to c0n%x (PC=%x)\n", data, offset, cpu_get_pc(&space.device())); |
| 125 | |
| 126 | switch (offset) |
| 127 | { |
| 128 | case 0: |
| 129 | m_wptr &= ~0xff; |
| 130 | m_wptr |= data; |
| 131 | m_regs[0] = m_wptr & 0xff; |
| 132 | m_regs[1] = (m_wptr>>8) & 0xff; |
| 133 | m_regs[2] = ((m_wptr>>16) & 0xff) | 0xf0; |
| 134 | m_liveptr = m_wptr; |
| 135 | break; |
| 136 | |
| 137 | case 1: |
| 138 | m_wptr &= ~0xff00; |
| 139 | m_wptr |= (data<<8); |
| 140 | m_regs[0] = m_wptr & 0xff; |
| 141 | m_regs[1] = (m_wptr>>8) & 0xff; |
| 142 | m_regs[2] = ((m_wptr>>16) & 0xff) | 0xf0; |
| 143 | m_liveptr = m_wptr; |
| 144 | break; |
| 145 | |
| 146 | case 2: |
| 147 | m_wptr &= ~0xff0000; |
| 148 | m_wptr |= (data<<16); |
| 149 | m_regs[0] = m_wptr & 0xff; |
| 150 | m_regs[1] = (m_wptr>>8) & 0xff; |
| 151 | m_regs[2] = ((m_wptr>>16) & 0xff) | 0xf0; |
| 152 | m_liveptr = m_wptr; |
| 153 | break; |
| 154 | |
| 155 | case 3: |
| 156 | // printf("Write %02x to RAM[%x]\n", data, m_liveptr); |
| 157 | m_ram[(m_liveptr&0xfffff)] = data; |
| 158 | m_liveptr++; |
| 159 | m_regs[0] = m_liveptr & 0xff; |
| 160 | m_regs[1] = (m_liveptr>>8) & 0xff; |
| 161 | m_regs[2] = ((m_liveptr>>16) & 0xff) | 0xf0; |
| 162 | break; |
| 163 | |
| 164 | default: |
| 165 | m_regs[offset] = data; |
| 166 | break; |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | /*------------------------------------------------- |
| 171 | read_cnxx - called for reads from this card's cnxx space |
| 172 | -------------------------------------------------*/ |
| 173 | |
| 174 | UINT8 a2bus_memexp_device::read_cnxx(address_space &space, UINT8 offset) |
| 175 | { |
| 176 | int slotimg = m_slot * 0x100; |
| 177 | |
| 178 | // first 0x400 of ROM contains a CnXX image for each of slots 1-7, last 0x400 is c800 image |
| 179 | return m_rom[offset+slotimg]; |
| 180 | } |
| 181 | |
| 182 | /*------------------------------------------------- |
| 183 | read_c800 - called for reads from this card's c800 space |
| 184 | -------------------------------------------------*/ |
| 185 | |
| 186 | UINT8 a2bus_memexp_device::read_c800(address_space &space, UINT16 offset) |
| 187 | { |
| 188 | return m_rom[offset+0x800]; |
| 189 | } |
src/mess/machine/a2memexp.h
| r0 | r14867 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | a2memexp.h |
| 4 | |
| 5 | Implementation of the Apple II Memory Expansion Card |
| 6 | |
| 7 | *********************************************************************/ |
| 8 | |
| 9 | #ifndef __A2BUS_MEMEXP__ |
| 10 | #define __A2BUS_MEMEXP__ |
| 11 | |
| 12 | #include "emu.h" |
| 13 | #include "machine/a2bus.h" |
| 14 | |
| 15 | //************************************************************************** |
| 16 | // TYPE DEFINITIONS |
| 17 | //************************************************************************** |
| 18 | |
| 19 | class a2bus_memexp_device: |
| 20 | public device_t, |
| 21 | public device_a2bus_card_interface |
| 22 | { |
| 23 | public: |
| 24 | // construction/destruction |
| 25 | a2bus_memexp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 26 | |
| 27 | // optional information overrides |
| 28 | virtual machine_config_constructor device_mconfig_additions() const; |
| 29 | virtual const rom_entry *device_rom_region() const; |
| 30 | |
| 31 | protected: |
| 32 | virtual void device_start(); |
| 33 | virtual void device_reset(); |
| 34 | |
| 35 | // overrides of standard a2bus slot functions |
| 36 | virtual UINT8 read_c0nx(address_space &space, UINT8 offset); |
| 37 | virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data); |
| 38 | virtual UINT8 read_cnxx(address_space &space, UINT8 offset); |
| 39 | virtual UINT8 read_c800(address_space &space, UINT16 offset); |
| 40 | |
| 41 | private: |
| 42 | UINT8 *m_rom; |
| 43 | UINT8 m_regs[0x10]; |
| 44 | UINT8 m_ram[1*1024*1024]; // 1 MB |
| 45 | int m_wptr, m_liveptr; |
| 46 | }; |
| 47 | |
| 48 | class a2bus_memexpapple_device : public a2bus_memexp_device |
| 49 | { |
| 50 | public: |
| 51 | a2bus_memexpapple_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 52 | }; |
| 53 | |
| 54 | // device type definition |
| 55 | extern const device_type A2BUS_MEMEXP; |
| 56 | |
| 57 | #endif /* __A2BUS_MEMEXP__ */ |
| 58 | |
src/mess/machine/apple2.c
| r14866 | r14867 | |
| 4 | 4 | |
| 5 | 5 | Machine file to handle emulation of the Apple II series. |
| 6 | 6 | |
| 7 | | TODO: Make a standard set of peripherals work. |
| 8 | | TODO: Allow swappable peripherals in each slot. |
| 9 | 7 | TODO: Verify correctness of C08X switches. |
| 10 | 8 | - need to do double-read before write-enable RAM |
| 11 | 9 | |
| r14866 | r14867 | |
| 23 | 21 | #include "imagedev/cassette.h" |
| 24 | 22 | #include "machine/ram.h" |
| 25 | 23 | #include "sound/speaker.h" |
| 24 | #include "debugger.h" |
| 26 | 25 | |
| 27 | 26 | #ifdef MAME_DEBUG |
| 28 | 27 | #define VERBOSE 1 |
| r14866 | r14867 | |
| 358 | 357 | |
| 359 | 358 | if (offset < 0x80) |
| 360 | 359 | { |
| 361 | | if (state->m_a2_cnxx_slot != -1) |
| 362 | | { |
| 363 | | state->m_a2_cnxx_slot = -1; |
| 364 | | apple2_update_memory(space->machine()); |
| 365 | | } |
| 366 | | |
| 367 | 360 | /* normal handler */ |
| 368 | 361 | if (handlers[offset / 0x10]) |
| 369 | 362 | result = handlers[offset / 0x10](space, offset % 0x10); |
| r14866 | r14867 | |
| 409 | 402 | |
| 410 | 403 | if (offset < 0x80) |
| 411 | 404 | { |
| 412 | | if (state->m_a2_cnxx_slot != -1) |
| 413 | | { |
| 414 | | state->m_a2_cnxx_slot = -1; |
| 415 | | apple2_update_memory(space->machine()); |
| 416 | | } |
| 417 | | |
| 418 | 405 | /* normal handler */ |
| 419 | 406 | if (handlers[offset / 0x10]) |
| 420 | 407 | handlers[offset / 0x10](space, offset % 0x10, data); |
| r14866 | r14867 | |
| 448 | 435 | |
| 449 | 436 | if (slot_ram) |
| 450 | 437 | { |
| 451 | | if (state->m_a2_cnxx_slot == -1) |
| 438 | if (1) //state->m_a2_cnxx_slot == -1) |
| 452 | 439 | { |
| 440 | // printf("slotram_r: cnxx_slot now %d\n", slotnum); |
| 453 | 441 | state->m_a2_cnxx_slot = slotnum; |
| 454 | 442 | apple2_update_memory(machine); |
| 455 | 443 | } |
| r14866 | r14867 | |
| 472 | 460 | |
| 473 | 461 | if (state->m_a2_cnxx_slot == -1) |
| 474 | 462 | { |
| 463 | // printf("c1xx_r: cnxx_slot now %d\n", slotnum); |
| 475 | 464 | state->m_a2_cnxx_slot = slotnum; |
| 476 | 465 | apple2_update_memory(space->machine()); |
| 477 | 466 | } |
| r14866 | r14867 | |
| 530 | 519 | if (state->m_a2_cnxx_slot == -1) |
| 531 | 520 | { |
| 532 | 521 | state->m_a2_cnxx_slot = slotnum; |
| 522 | // printf("c4xx_r: cnxx_slot now %d\n", slotnum); |
| 533 | 523 | apple2_update_memory(space->machine()); |
| 534 | 524 | } |
| 535 | 525 | |
| r14866 | r14867 | |
| 566 | 556 | |
| 567 | 557 | if (state->m_a2_cnxx_slot == -1) |
| 568 | 558 | { |
| 559 | // printf("c4xx_w: cnxx_slot now %d\n", slotnum); |
| 569 | 560 | state->m_a2_cnxx_slot = slotnum; |
| 570 | 561 | apple2_update_memory(space->machine()); |
| 571 | 562 | } |
| r14866 | r14867 | |
| 583 | 574 | |
| 584 | 575 | static READ8_HANDLER(apple2_cfff_r) |
| 585 | 576 | { |
| 586 | | apple2_state *state = space->machine().driver_data<apple2_state>(); |
| 587 | 577 | // debugger guard |
| 588 | | if(!space->debugger_access()) |
| 578 | if (!space->debugger_access()) |
| 589 | 579 | { |
| 580 | apple2_state *state = space->machine().driver_data<apple2_state>(); |
| 581 | // printf("cfff_r: cnxx_slot now %d\n", -1); |
| 590 | 582 | state->m_a2_cnxx_slot = -1; |
| 591 | 583 | apple2_update_memory(space->machine()); |
| 592 | 584 | } |
| r14866 | r14867 | |
| 596 | 588 | |
| 597 | 589 | static WRITE8_HANDLER(apple2_cfff_w) |
| 598 | 590 | { |
| 599 | | apple2_state *state = space->machine().driver_data<apple2_state>(); |
| 600 | | state->m_a2_cnxx_slot = -1; |
| 601 | | apple2_update_memory(space->machine()); |
| 591 | if (!space->debugger_access()) |
| 592 | { |
| 593 | apple2_state *state = space->machine().driver_data<apple2_state>(); |
| 594 | // printf("cfff_w: cnxx_slot now %d\n", -1); |
| 595 | state->m_a2_cnxx_slot = -1; |
| 596 | apple2_update_memory(space->machine()); |
| 597 | } |
| 602 | 598 | } |
| 603 | 599 | |
| 604 | 600 | static READ8_HANDLER ( apple2_c800_r ) |
| r14866 | r14867 | |
| 891 | 887 | state->m_flags &= ~mask; |
| 892 | 888 | state->m_flags |= val; |
| 893 | 889 | |
| 890 | if (state->m_flags & VAR_INTCXROM) |
| 891 | { |
| 892 | state->m_a2_cnxx_slot = -1; |
| 893 | } |
| 894 | |
| 894 | 895 | apple2_update_memory(machine); |
| 895 | 896 | } |
| 896 | 897 | |
| r14866 | r14867 | |
| 1072 | 1073 | |
| 1073 | 1074 | state->m_a2_speaker_state = 0; |
| 1074 | 1075 | |
| 1076 | state->m_a2_cnxx_slot = -1; // bank in ROM at C800 on reset |
| 1077 | |
| 1075 | 1078 | state->m_joystick_x1_time = state->m_joystick_y1_time = 0; |
| 1076 | 1079 | state->m_joystick_x2_time = state->m_joystick_y2_time = 0; |
| 1077 | 1080 | } |
| r14866 | r14867 | |
| 1141 | 1144 | g_profiler.stop(); |
| 1142 | 1145 | } |
| 1143 | 1146 | |
| 1147 | |
| 1148 | |
| 1144 | 1149 | return result; |
| 1145 | 1150 | } |
| 1146 | 1151 | |
| r14866 | r14867 | |
| 1170 | 1175 | WRITE8_HANDLER ( apple2_c00x_w ) |
| 1171 | 1176 | { |
| 1172 | 1177 | UINT32 mask; |
| 1178 | |
| 1173 | 1179 | mask = 1 << (offset / 2); |
| 1174 | 1180 | apple2_setvar(space->machine(), (offset & 1) ? mask : 0, mask); |
| 1175 | 1181 | } |
| r14866 | r14867 | |
| 1585 | 1591 | } |
| 1586 | 1592 | |
| 1587 | 1593 | |
| 1588 | | |
| 1589 | 1594 | void apple2_iwm_setdiskreg(running_machine &machine, UINT8 data) |
| 1590 | 1595 | { |
| 1591 | 1596 | apple2_state *state = machine.driver_data<apple2_state>(); |
| 1592 | | state->m_fdc_diskreg = data & 0xC0; |
| 1597 | state->m_fdc_diskreg = data & 0xC0; |
| 1593 | 1598 | if (apple2_fdc_has_35(machine)) |
| 1594 | 1599 | sony_set_sel_line( machine.device("fdc"),state->m_fdc_diskreg & 0x80); |
| 1595 | 1600 | } |
| 1596 | 1601 | |
| 1597 | 1602 | |
| 1598 | | |
| 1599 | | UINT8 apple2_iwm_getdiskreg(running_machine &machine) |
| 1600 | | { |
| 1601 | | apple2_state *state = machine.driver_data<apple2_state>(); |
| 1602 | | return state->m_fdc_diskreg; |
| 1603 | | } |
| 1604 | | |
| 1605 | | |
| 1606 | | |
| 1607 | | |
| 1608 | 1603 | const applefdc_interface apple2_fdc_interface = |
| 1609 | 1604 | { |
| 1610 | 1605 | apple2_fdc_set_lines, /* set_lines */ |
src/mess/drivers/apple2gs.c
| r14866 | r14867 | |
| 62 | 62 | #include "machine/a2diskii.h" |
| 63 | 63 | #include "machine/a2mockingboard.h" |
| 64 | 64 | #include "machine/a2cffa.h" |
| 65 | #include "machine/a2memexp.h" |
| 66 | #include "machine/a2scsi.h" |
| 65 | 67 | |
| 66 | 68 | static const gfx_layout apple2gs_text_layout = |
| 67 | 69 | { |
| r14866 | r14867 | |
| 186 | 188 | DEVCB_NULL |
| 187 | 189 | }; |
| 188 | 190 | |
| 191 | #if 0 |
| 192 | static SLOT_INTERFACE_START(apple2_cards) |
| 193 | SLOT_INTERFACE("diskii", A2BUS_DISKII) /* Disk II Controller Card */ |
| 194 | SLOT_INTERFACE("mockingboard", A2BUS_MOCKINGBOARD) /* Sweet Micro Systems Mockingboard */ |
| 195 | SLOT_INTERFACE("cffa2", A2BUS_CFFA2) /* CFFA2000 Compact Flash for Apple II (www.dreher.net), 65C02/65816 firmware */ |
| 196 | SLOT_INTERFACE("cffa202", A2BUS_CFFA2_6502) /* CFFA2000 Compact Flash for Apple II (www.dreher.net), 6502 firmware */ |
| 197 | SLOT_INTERFACE("memexp", A2BUS_MEMEXP) /* Apple II Memory Expansion Card */ |
| 198 | SLOT_INTERFACE("scsi", A2BUS_SCSI) /* Apple II SCSI Card */ |
| 199 | SLOT_INTERFACE_END |
| 200 | #endif |
| 201 | |
| 189 | 202 | static MACHINE_CONFIG_START( apple2gs, apple2gs_state ) |
| 190 | 203 | /* basic machine hardware */ |
| 191 | 204 | MCFG_CPU_ADD("maincpu", G65816, APPLE2GS_14M/5) |
| r14866 | r14867 | |
| 222 | 235 | /* slot devices */ |
| 223 | 236 | MCFG_A2BUS_BUS_ADD("a2bus", "maincpu", a2bus_intf) |
| 224 | 237 | MCFG_A2BUS_ONBOARD_ADD("a2bus", "sl0", A2BUS_LANG, NULL) |
| 238 | // MCFG_A2BUS_SLOT_ADD("a2bus", "sl7", apple2_cards, NULL, NULL) |
| 225 | 239 | |
| 226 | 240 | MCFG_IWM_ADD("fdc", apple2_fdc_interface) |
| 227 | 241 | |
| 228 | | /* slots */ |
| 229 | | // MCFG_APPLE2_SLOT_ADD(6, "fdc", applefdc_r, applefdc_w, 0, 0, 0, 0) |
| 230 | | |
| 231 | 242 | /* SCC */ |
| 232 | 243 | MCFG_SCC8530_ADD("scc", APPLE2GS_14M/2, line_cb_t()) |
| 233 | 244 | |