/********************************************************************* 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 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 bit 7 - set if mouse register full bit 6 - mouse interupt 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 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 #include "driver.h" #include "includes/apple2gs.h" #include "includes/apple2.h" #include "machine/ay3600.h" #include "machine/applefdc.h" #include "devices/sonydriv.h" #include "machine/8530scc.h" #include "devices/flopdrv.h" #include "cpu/g65816/g65816.h" #include "sound/es5503.h" #define LOG_C0XX 0 #define LOG_ADB 0 #define LOG_IRQ 0 #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 UINT8 *apple2gs_slowmem; UINT8 apple2gs_newvideo; static UINT8 apple2gs_vgcint; static UINT8 apple2gs_langsel; static UINT8 apple2gs_sltromsel; static UINT8 apple2gs_cyareg; static UINT8 apple2gs_inten; static UINT8 apple2gs_intflag; static UINT8 apple2gs_shadow; static UINT8 apple2gs_pending_irqs; static UINT8 apple2gs_mouse_x; static UINT8 apple2gs_mouse_y; static INT8 apple2gs_mouse_dx; static INT8 apple2gs_mouse_dy; static mess_image *apple2gs_cur_slot6_image; static mame_timer *apple2gs_scanline_timer; /* ----------------------------------------------------------------------- * Apple IIgs clock * ----------------------------------------------------------------------- */ typedef enum { CLOCKMODE_IDLE, CLOCKMODE_TIME, CLOCKMODE_INTERNALREGS, CLOCKMODE_BRAM1, CLOCKMODE_BRAM2 } apple2gs_clock_mode; static UINT8 clock_data; static UINT8 clock_control; static UINT8 clock_read; static UINT8 clock_reg1; static apple2gs_clock_mode clock_mode; static UINT32 clock_curtime; /* number of seconds since 1-Jan-1904 */ static seconds_t clock_curtime_interval; /* second index at which clock_curtime is valid */ static UINT8 clock_bram[256]; static void process_clock(void) { UINT8 operation; seconds_t current_interval; /* update clock_curtime */ current_interval = mame_timer_get_time().seconds; clock_curtime += current_interval - clock_curtime_interval; clock_curtime_interval = current_interval; switch(clock_mode) { case CLOCKMODE_IDLE: clock_read = (clock_data >> 7); clock_reg1 = (clock_data >> 2) & 0x03; operation = (clock_data >> 4) & 0x07; if ((clock_data & 0x40) == 0x00) { switch(operation) { case 0x00: /* read/write seconds register */ clock_mode = CLOCKMODE_TIME; break; case 0x03: /* internal registers */ if (clock_reg1 & 0x02) { clock_mode = CLOCKMODE_BRAM2; clock_reg1 = (clock_data & 0x07) << 5; } else { clock_mode = CLOCKMODE_INTERNALREGS; } break; default: //fatalerror("NYI"); break; } } break; case CLOCKMODE_BRAM1: if (clock_read) clock_data = clock_bram[clock_reg1]; else clock_bram[clock_reg1] = clock_data; clock_mode = CLOCKMODE_IDLE; break; case CLOCKMODE_BRAM2: clock_reg1 |= (clock_data >> 2) & 0x1F; clock_mode = CLOCKMODE_BRAM1; break; case CLOCKMODE_INTERNALREGS: switch (clock_reg1) { case 0x00: /* test register */ break; case 0x01: /* write protect register */ break; } clock_mode = CLOCKMODE_IDLE; break; case CLOCKMODE_TIME: if (clock_data & 0x40) { clock_data = clock_curtime >> (clock_reg1 * 8); } else { clock_curtime &= ~(0xFF << (clock_reg1 * 8)); clock_curtime |= clock_data << (clock_reg1 * 8); } clock_mode = CLOCKMODE_IDLE; break; default: //fatalerror("NYI"); break; } } NVRAM_HANDLER( apple2gs ) { if (read_or_write) { mame_fwrite(file, clock_bram, sizeof(clock_bram)); } else if (file) { mame_fread(file, clock_bram, sizeof(clock_bram)); } else { memset(clock_bram, 0x00, sizeof(clock_bram)); } } /* ----------------------------------------------------------------------- * Interrupts * ----------------------------------------------------------------------- */ static const char *apple2gs_irq_name(UINT8 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"; } return NULL; } static void apple2gs_add_irq(UINT8 irq_mask) { if ((apple2gs_pending_irqs & irq_mask) == 0x00) { if (LOG_IRQ) logerror("apple2gs_add_irq(): adding %s\n", apple2gs_irq_name(irq_mask)); apple2gs_pending_irqs |= irq_mask; cpunum_set_input_line(0, G65816_LINE_IRQ, apple2gs_pending_irqs ? ASSERT_LINE : CLEAR_LINE); } } static void apple2gs_remove_irq(UINT8 irq_mask) { if (apple2gs_pending_irqs & irq_mask) { if (LOG_IRQ) logerror("apple2gs_remove_irq(): removing %s\n", apple2gs_irq_name(irq_mask)); apple2gs_pending_irqs &= ~irq_mask; cpunum_set_input_line(0, G65816_LINE_IRQ, apple2gs_pending_irqs ? ASSERT_LINE : CLEAR_LINE); } } void apple2gs_doc_irq(int state) { if (state) { apple2gs_add_irq(IRQ_DOC); } else { apple2gs_remove_irq(IRQ_DOC); } } /* ----------------------------------------------------------------------- * ADB * ----------------------------------------------------------------------- */ typedef enum { ADBSTATE_IDLE, ADBSTATE_INCOMMAND, ADBSTATE_INRESPONSE } adbstate_t; static adbstate_t adb_state; static UINT8 adb_command; static UINT8 adb_mode; static UINT8 adb_kmstatus; static UINT8 adb_latent_result; static size_t adb_command_length; static size_t adb_command_pos; static UINT8 adb_command_bytes[8]; static UINT8 adb_response_bytes[8]; static UINT8 adb_response_length; static size_t adb_response_pos; static UINT8 adb_memory[0x100]; static int adb_address_keyboard; static int adb_address_mouse; static UINT8 adb_read_memory(UINT32 address) { if (address < (sizeof(adb_memory) / sizeof(adb_memory[0]))) return adb_memory[address]; else return 0x00; } static void adb_write_memory(UINT32 address, UINT8 data) { if (address < (sizeof(adb_memory) / sizeof(adb_memory[0]))) adb_memory[address] = data; } static void adb_set_mode(UINT8 mode) { adb_mode = mode; } static void adb_set_config(UINT8 b1, UINT8 b2, UINT8 b3) { /* ignore for now */ } static void adb_post_response(const UINT8 *bytes, size_t length) { assert(length < (sizeof(adb_response_bytes) / sizeof(adb_response_bytes[0]))); memcpy(adb_response_bytes, bytes, length); adb_state = ADBSTATE_INRESPONSE; adb_response_length = length; adb_response_pos = 0; } static void adb_post_response_1(UINT8 b) { adb_post_response(&b, 1); } static void adb_post_response_2(UINT8 b1, UINT8 b2) { UINT8 b[2]; b[0] = b1; b[1] = b2; adb_post_response(b, 2); } static void adb_do_command(void) { int device; UINT32 address; UINT8 val; adb_state = ADBSTATE_IDLE; if (LOG_ADB) logerror("adb_do_command(): adb_command=0x%02x\n", adb_command); switch(adb_command) { case 0x00: /* ??? */ break; case 0x03: /* flush keyboard buffer */ break; case 0x04: /* set modes */ adb_set_mode(adb_mode | adb_command_bytes[0]); break; case 0x05: /* clear modes */ adb_set_mode(adb_mode & ~adb_command_bytes[0]); break; case 0x06: /* set config */ adb_set_config(adb_command_bytes[0], adb_command_bytes[1], adb_command_bytes[2]); break; case 0x07: /* synchronize */ adb_set_mode(adb_command_bytes[0]); adb_set_config(adb_command_bytes[1], adb_command_bytes[2], adb_command_bytes[3]); break; case 0x08: /* write memory */ address = adb_command_bytes[0]; val = adb_command_bytes[1]; adb_write_memory(address, val); break; case 0x09: /* read memory */ address = (adb_command_bytes[1] << 8) | adb_command_bytes[0]; adb_post_response_1(adb_read_memory(address)); 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 = adb_command & 0x0f; if (device == adb_address_keyboard) { } else if (device == adb_address_mouse) { } break; default: fatalerror("ADB command 0x%02x unimplemented", adb_command); break; } adb_kmstatus |= 0x20; } static UINT8 adb_read_datareg(void) { UINT8 result; switch(adb_state) { case ADBSTATE_INRESPONSE: result = adb_response_bytes[adb_response_pos++]; if (adb_response_pos >= adb_response_length) { adb_state = ADBSTATE_IDLE; adb_latent_result = result; adb_kmstatus &= ~0x20; } break; default: result = adb_latent_result; break; } if (LOG_ADB) logerror("adb_read_datareg(): result=0x%02x\n", result); return result; } static void adb_write_datareg(UINT8 data) { if (LOG_ADB) logerror("adb_write_datareg(): data=0x%02x\n", data); switch(adb_state) { case ADBSTATE_IDLE: adb_command = data; adb_command_length = 0; adb_command_pos = 0; switch(data) { case 0x00: /* ??? */ case 0x01: /* abort */ /* do nothing for now */ break; case 0x03: /* flush keyboard buffer */ adb_command_length = 0; break; case 0x04: /* set modes */ case 0x05: /* clear modes */ adb_command_length = 1; break; case 0x06: /* set config */ adb_command_length = 3; break; case 0x07: /* synchronize */ if (memory_region_length(REGION_CPU1) == 0x40000) /* HACK */ adb_command_length = 8; else adb_command_length = 4; break; case 0x08: /* write memory */ case 0x09: /* read memory */ adb_command_length = 2; break; case 0x0d: /* get version */ adb_command_length = 0; break; case 0x0e: /* read available charsets */ adb_command_length = 0; adb_state = ADBSTATE_INCOMMAND; /* HACK */ break; case 0x0f: /* read available layouts */ adb_command_length = 0; adb_state = ADBSTATE_INCOMMAND; /* HACK */ break; case 0x12: /* mystery command 0x12 */ case 0x13: /* mystery command 0x13 */ 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 */ adb_command_length = 2; break; default: fatalerror("ADB command 0x%02x unimplemented", data); break; } if (adb_command_length > 0) { adb_state = ADBSTATE_INCOMMAND; if (LOG_ADB) logerror("adb_write_datareg(): in command length %u\n", (unsigned) adb_command_length); } break; case ADBSTATE_INCOMMAND: assert(adb_command_pos < (sizeof(adb_command_bytes) / sizeof(adb_command_bytes[0]))); adb_command_bytes[adb_command_pos++] = data; break; case ADBSTATE_INRESPONSE: adb_state = ADBSTATE_IDLE; break; } /* do command if necessary */ if ((adb_state == ADBSTATE_INCOMMAND) && (adb_command_pos >= adb_command_length)) adb_do_command(); } static UINT8 adb_read_kmstatus(void) { return adb_kmstatus; } static void adb_write_kmstatus(UINT8 data) { adb_kmstatus &= ~0x54; adb_kmstatus |= data & 0x54; } static UINT8 adb_read_mousedata(void) { UINT8 result = 0x00; UINT8 absolute; INT8 delta; if (adb_kmstatus & 0x80) { if (adb_kmstatus & 0x02) { absolute = apple2gs_mouse_y; delta = apple2gs_mouse_dy; adb_kmstatus &= ~0x82; apple2gs_remove_irq(IRQ_ADB_MOUSE); } else { absolute = apple2gs_mouse_x; delta = apple2gs_mouse_dx; adb_kmstatus |= 0x02; } if (delta > 63) delta = 63; else if (delta < -64) delta = -64; result = (absolute & 0x80) | (delta & 0x7F); } return result; } static INT8 seven_bit_diff(UINT8 v1, UINT8 v2) { v1 -= v2; if (v1 & 0x40) v1 |= 0x80; else v1 &= ~0x80; return v1; } static void adb_check_mouse(void) { UINT8 new_mouse_x, new_mouse_y; /* read mouse values */ if ((adb_kmstatus & 0x80) == 0x00) { new_mouse_x = readinputportbytag("adb_mouse_x"); new_mouse_y = readinputportbytag("adb_mouse_y"); if ((apple2gs_mouse_x != new_mouse_x) || (apple2gs_mouse_y != new_mouse_y)) { apple2gs_mouse_dx = seven_bit_diff(new_mouse_x, apple2gs_mouse_x); apple2gs_mouse_dy = seven_bit_diff(new_mouse_y, apple2gs_mouse_y); apple2gs_mouse_x = new_mouse_x; apple2gs_mouse_y = new_mouse_y; adb_kmstatus |= 0x80; adb_kmstatus &= ~0x02; if (adb_kmstatus & 0x40) apple2gs_add_irq(IRQ_ADB_MOUSE); } } } static void apple2gs_set_scanint(UINT8 data) { /* second interrupt */ if ((apple2gs_vgcint & 0x40) && !(data & 0x40)) { apple2gs_remove_irq(IRQ_VGC_SECOND); apple2gs_vgcint &= ~0xC0; } /* scanline interrupt */ if ((apple2gs_vgcint & 0x20) && !(data & 0x20)) { apple2gs_remove_irq(IRQ_VGC_SCANLINE); apple2gs_vgcint &= ~0xA0; } if (apple2gs_pending_irqs & (IRQ_VGC_SECOND | IRQ_VGC_SCANLINE)) apple2gs_vgcint |= 0x80; } static TIMER_CALLBACK(apple2gs_scanline_tick) { int scanline; int current_frame; // make sure we're in the 65816's context cpuintrf_push_context(0); scanline = video_screen_get_vpos(0); video_screen_update_partial(0, scanline); /* scanline interrupt */ if ((apple2gs_newvideo & 0x80) && (apple2gs_vgcint & 0x02) && (scanline >= (BORDER_TOP-1)) && (scanline < (200+BORDER_TOP-1))) { UINT8 scb; scb = apple2gs_slowmem[0x19D00 + scanline - BORDER_TOP + 1]; if (scb & 0x40) { apple2gs_vgcint |= 0xa0; apple2gs_add_irq(IRQ_VGC_SCANLINE); } } if (scanline == BORDER_TOP) { current_frame = cpu_getcurrentframe(); /* quarter second interrupt */ if ((apple2gs_inten & 0x10) && !(apple2gs_intflag & 0x10) && ((current_frame % 15) == 0)) { apple2gs_intflag |= 0x10; apple2gs_add_irq(IRQ_INTEN_QSECOND); } /* one second interrupt */ if ((apple2gs_vgcint & 0x04) && !(apple2gs_vgcint & 0x40) && ((current_frame % 60) == 0)) { apple2gs_vgcint |= 0xc0; apple2gs_add_irq(IRQ_VGC_SECOND); } } else if (scanline == (192+BORDER_TOP)) { /* VBL interrupt */ if ((apple2gs_inten & 0x08) && !(apple2gs_intflag & 0x08)) { apple2gs_intflag |= 0x08; apple2gs_add_irq(IRQ_INTEN_VBL); } } /* check the mouse status */ if ((scanline % 8) == 0) { adb_check_mouse(); /* call Apple II interrupt handler */ if ((video_screen_get_vpos(0) % 8) == 7) apple2_interrupt(); } mame_timer_adjust(apple2gs_scanline_timer, video_screen_get_time_until_pos(0, (scanline+1)%262, 0), 0, time_never); cpuintrf_pop_context(); } /* ----------------------------------------------------------------------- * Sound handlers * ----------------------------------------------------------------------- */ static UINT8 sndglu_ctrl; static int sndglu_addr, sndglu_dummy_read; static READ8_HANDLER( gssnd_r ) { UINT8 ret = 0; switch (offset) { case 0: // control ret = sndglu_ctrl; break; case 1: // data read ret = sndglu_dummy_read; if (sndglu_ctrl & 0x40) // docram access { sndglu_dummy_read = apple2gs_docram[sndglu_addr]; } else { sndglu_dummy_read = ES5503_reg_0_r(sndglu_addr); } if (sndglu_ctrl & 0x20) // auto-increment { sndglu_addr++; } break; case 2: // addr l ret = sndglu_addr & 0xff; break; case 3: // addr h ret = (sndglu_addr >> 8) & 0xff; break; } return ret; } static WRITE8_HANDLER( gssnd_w ) { switch (offset) { case 0: // control sndglu_ctrl = data & 0x7f; // make sure DOC is never busy if (!(sndglu_ctrl & 0x40)) // clear hi byte of address pointer on DOC access { sndglu_addr &= 0xff; } break; case 1: // data write if (sndglu_ctrl & 0x40) // docram access { apple2gs_docram[sndglu_addr] = data; } else { ES5503_reg_0_w(sndglu_addr, data); } if (sndglu_ctrl & 0x20) // auto-increment { sndglu_addr++; } break; case 2: // addr l sndglu_addr &= 0xff00; sndglu_addr |= data; break; case 3: // addr h sndglu_addr &= 0x00ff; sndglu_addr |= data<<8; break; } } /* ----------------------------------------------------------------------- * IO handlers * ----------------------------------------------------------------------- */ // apple2gs_get_vpos - return the correct vertical counter value for the current scanline, // keeping borders in mind. static int apple2gs_get_vpos(void) { int result, scan; static UINT8 top_border_vert[BORDER_TOP] = { 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, }; scan = video_screen_get_vpos(0); if (scan < BORDER_TOP) { result = top_border_vert[scan]; } else { result = scan - BORDER_TOP + 0x100 + 1; } return result; } static READ8_HANDLER( apple2gs_c0xx_r ) { UINT8 result; offset &= 0xFF; switch(offset) { case 0x19: /* C019 - RDVBLBAR */ result = (video_screen_get_vpos(0) >= (192+BORDER_TOP)) ? 0x80 : 0x00; break; case 0x22: /* C022 - TBCOLOR */ result = (apple2_get_fgcolor() << 4) | apple2_get_bgcolor(); break; case 0x23: /* C023 - VGCINT */ result = apple2gs_vgcint; break; case 0x24: /* C024 - MOUSEDATA */ result = adb_read_mousedata(); break; case 0x25: /* C025 - KEYMODREG */ result = AY3600_keymod_r(); break; case 0x26: /* C026 - DATAREG */ result = adb_read_datareg(); break; case 0x27: /* C027 - KMSTATUS */ result = adb_read_kmstatus(); break; case 0x29: /* C029 - NEWVIDEO */ result = apple2gs_newvideo; break; case 0x2B: /* C02B - LANGSEL */ result = apple2gs_langsel; break; case 0x2D: /* C02D - SLTROMSEL */ result = apple2gs_sltromsel; break; case 0x2E: /* C02E - VERTCNT */ result = apple2gs_get_vpos() >> 1; break; case 0x2F: /* C02F - HORIZCNT */ result = video_screen_get_hpos(0) / 11; if (result > 0) { result += 0x40; } if (apple2gs_get_vpos() & 1) { result |= 0x80; } break; case 0x31: /* C031 - DISKREG */ result = apple2_iwm_getdiskreg(); break; case 0x33: /* C033 - CLOCKDATA */ result = clock_data; break; case 0x34: /* C034 - CLOCKCTL */ result = clock_control; break; case 0x35: /* C035 - SHADOW */ result = apple2gs_shadow; break; case 0x36: /* C036 - CYAREG */ result = apple2gs_cyareg; break; case 0x38: /* C038 - SCCBREG */ case 0x39: /* C039 - SCCAREG */ case 0x3A: /* C03A - SCCBDATA */ case 0x3B: /* C03B - SCCADATA */ result = scc_r(offset & 0x03); break; case 0x3C: /* C03C - SOUNDCTL */ case 0x3D: /* C03D - SOUNDDATA */ case 0x3E: /* C03E - SOUNDADRL */ case 0x3F: /* C03F - SOUNDADRH */ result = gssnd_r(offset & 0x03); break; case 0x41: /* C041 - INTEN */ result = apple2gs_inten; break; case 0x46: /* C046 - INTFLAG */ result = apple2gs_intflag; break; case 0x68: /* C068 - STATEREG */ result = ((a2 & VAR_ALTZP) ? 0x80 : 0x00) | ((a2 & VAR_PAGE2) ? 0x40 : 0x00) | ((a2 & VAR_RAMRD) ? 0x20 : 0x00) | ((a2 & VAR_RAMWRT) ? 0x10 : 0x00) | ((a2 & VAR_LCRAM) ? 0x00 : 0x08) | ((a2 & VAR_LCRAM2) ? 0x04 : 0x00) | ((a2 & 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 |= (memory_region_length(REGION_CPU1) - 1) & ~0x3FFF; result = memory_region(REGION_CPU1)[offset]; break; case 0x21: /* C021 - MONOCOLOR */ case 0x2C: /* C02C - CHARROM */ result = 0x00; default: result = apple2_c0xx_r(offset); break; } if (LOG_C0XX) logerror("apple2gs_c0xx_r(): offset=0x%02x result=0x%02x\n", offset, result); return result; } static WRITE8_HANDLER( apple2gs_c0xx_w ) { offset &= 0xFF; if (LOG_C0XX) logerror("apple2gs_c0xx_w(): offset=0x%02x data=0x%02x\n", offset, data); switch(offset) { case 0x22: /* C022 - TBCOLOR */ apple2_set_fgcolor((data >> 4) & 0x0F); apple2_set_bgcolor((data >> 0) & 0x0F); break; case 0x23: /* C023 - VGCINT */ apple2gs_vgcint &= ~0x0F; apple2gs_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 */ adb_write_datareg(data); break; case 0x27: /* C027 - KMSTATUS */ adb_write_kmstatus(data); break; case 0x29: /* C029 - NEWVIDEO */ apple2gs_newvideo = data; break; case 0x2B: /* C02B - LANGSEL */ apple2gs_langsel = data; break; case 0x2D: /* C02D - SLTROMSEL */ apple2gs_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 */ clock_data = data; break; case 0x34: /* C034 - CLOCKCTL */ clock_control = data & 0x7F; apple2gs_bordercolor = data & 0x0F; if (data & 0x80) process_clock(); break; case 0x35: /* C035 - SHADOW */ if (apple2gs_shadow != data) { apple2gs_shadow = data; apple2_update_memory(); } break; case 0x36: /* C036 - CYAREG */ apple2gs_cyareg = data & ~0x20; cpunum_set_clock(0, (data & 0x80) ? APPLE2GS_14M/5 : APPLE2GS_7M/7); break; case 0x38: /* C038 - SCCBREG */ case 0x39: /* C039 - SCCAREG */ case 0x3A: /* C03A - SCCBDATA */ case 0x3B: /* C03B - SCCADATA */ scc_w(offset & 0x03, data); break; case 0x3C: /* C03C - SOUNDCTL */ case 0x3D: /* C03D - SOUNDDATA */ case 0x3E: /* C03E - SOUNDADRL */ case 0x3F: /* C03F - SOUNDADRH */ gssnd_w(offset & 0x03, data); break; case 0x41: /* C041 - INTEN */ apple2gs_inten = data & 0x1F; if ((apple2gs_inten & 0x10) == 0x00) apple2gs_remove_irq(IRQ_INTEN_QSECOND); if ((apple2gs_inten & 0x08) == 0x00) apple2gs_remove_irq(IRQ_INTEN_VBL); break; case 0x47: /* C047 - CLRVBLINT */ apple2gs_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; default: apple2_c0xx_w(offset, data); break; } } /* ----------------------------------------------------------------------- * Memory management * ----------------------------------------------------------------------- */ static WRITE8_HANDLER( apple2gs_main0400_w ) { offset += 0x000400; mess_ram[offset] = data; if (!(apple2gs_shadow & 0x01)) { apple2gs_slowmem[offset] = data; apple2_video_touch(offset); } } static WRITE8_HANDLER( apple2gs_aux0400_w ) { offset += 0x010400; mess_ram[offset] = data; if (!(apple2gs_shadow & 0x01)) { apple2gs_slowmem[offset] = data; apple2_video_touch(offset); } } static WRITE8_HANDLER( apple2gs_main2000_w ) { offset += 0x002000; mess_ram[offset] = data; if (!(apple2gs_shadow & 0x02)) { apple2gs_slowmem[offset] = data; apple2_video_touch(offset); } } static WRITE8_HANDLER( apple2gs_aux2000_w ) { offset += 0x012000; mess_ram[offset] = data; if (!(apple2gs_shadow & 0x12) || !(apple2gs_shadow & 0x08)) { apple2gs_slowmem[offset] = data; apple2_video_touch(offset); } } static WRITE8_HANDLER( apple2gs_main4000_w ) { offset += 0x004000; mess_ram[offset] = data; if ((offset >= 0x004000) && (offset <= 0x005FFF)) { if (!(apple2gs_shadow & 0x04)) apple2gs_slowmem[offset] = data; } } static WRITE8_HANDLER( apple2gs_aux4000_w ) { offset += 0x014000; mess_ram[offset] = data; if ((offset >= 0x014000) && (offset <= 0x015FFF)) { if (!(apple2gs_shadow & 0x14) || !(apple2gs_shadow & 0x08)) apple2gs_slowmem[offset] = data; } else if ((offset >= 0x016000) && (offset <= 0x019FFF)) { if (!(apple2gs_shadow & 0x08)) { apple2gs_slowmem[offset] = data; if (offset >= 0x19e00) { int color = (offset - 0x19e00) >> 1; palette_set_color_rgb(Machine, color + 16, ((apple2gs_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17, ((apple2gs_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17, ((apple2gs_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17); } } } } static void apple2gs_mem_000000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { meminfo->read_mem = (a2 & VAR_ALTZP) ? 0x010000 : 0x000000; meminfo->write_mem = (a2 & VAR_ALTZP) ? 0x010000 : 0x000000; } static void apple2gs_mem_000200(offs_t begin, offs_t end, apple2_meminfo *meminfo) { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x010200 : 0x000200; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x010200 : 0x000200; } static void apple2gs_mem_000400(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if (a2 & VAR_80STORE) { meminfo->read_mem = (a2 & VAR_PAGE2) ? 0x010400 : 0x000400; meminfo->write_mem = (a2 & VAR_PAGE2) ? 0x010400 : 0x000400; meminfo->write_handler = (a2 & VAR_PAGE2) ? apple2gs_aux0400_w : apple2gs_main0400_w; } else { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x010400 : 0x000400; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x010400 : 0x000400; meminfo->write_handler = (a2 & VAR_RAMWRT) ? apple2gs_aux0400_w : apple2gs_main0400_w; } } static void apple2gs_mem_000800(offs_t begin, offs_t end, apple2_meminfo *meminfo) { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x010800 : 0x000800; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x010800 : 0x000800; } static void apple2gs_mem_002000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if ((a2 & (VAR_80STORE|VAR_HIRES)) == (VAR_80STORE|VAR_HIRES)) { meminfo->read_mem = (a2 & VAR_PAGE2) ? 0x012000 : 0x002000; meminfo->write_mem = (a2 & VAR_PAGE2) ? 0x012000 : 0x002000; meminfo->write_handler = (a2 & VAR_PAGE2) ? apple2gs_aux2000_w : apple2gs_main2000_w; } else { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x012000 : 0x002000; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x012000 : 0x002000; meminfo->write_handler = (a2 & VAR_RAMWRT) ? apple2gs_aux2000_w : apple2gs_main2000_w; } } static void apple2gs_mem_004000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x014000 : 0x004000; meminfo->write_handler = (a2 & VAR_RAMWRT) ? apple2gs_aux4000_w : apple2gs_main4000_w; } static void apple2gs_mem_xxD000(apple2_meminfo *meminfo, UINT32 lcmem) { if (a2 & VAR_LCRAM) { if (a2 & VAR_LCRAM2) meminfo->read_mem = lcmem | 0x00C000; else meminfo->read_mem = lcmem | 0x00D000; } else { meminfo->read_mem = 0x03D000 | APPLE2_MEM_ROM; } if (a2 & VAR_LCWRITE) { if (a2 & 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(apple2_meminfo *meminfo, UINT32 lcmem) { if (a2 & VAR_LCRAM) meminfo->read_mem = lcmem | 0x00E000; else meminfo->read_mem = 0x03E000 | APPLE2_MEM_ROM; if (a2 & VAR_LCWRITE) meminfo->write_mem = lcmem | 0x00E000; else meminfo->write_mem = APPLE2_MEM_FLOATING; } static void apple2gs_mem_00D000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if (apple2gs_shadow & 0x40) { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x01D000 : 0x00D000; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x01D000 : 0x00D000; } else { apple2gs_mem_xxD000(meminfo, (a2 & VAR_ALTZP) ? 0x010000 : 0x000000); } } static void apple2gs_mem_00E000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if (apple2gs_shadow & 0x40) { meminfo->read_mem = (a2 & VAR_RAMRD) ? 0x01E000 : 0x00E000; meminfo->write_mem = (a2 & VAR_RAMWRT) ? 0x01E000 : 0x00E000; } else { apple2gs_mem_xxE000(meminfo, (a2 & VAR_ALTZP) ? 0x010000 : 0x000000); } } static void apple2gs_mem_01D000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if (apple2gs_shadow & 0x40) { meminfo->read_mem = 0x01D000; meminfo->write_mem = 0x01D000; } else { apple2gs_mem_xxD000(meminfo, 0x010000); } } static void apple2gs_mem_01E000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { if (apple2gs_shadow & 0x40) { meminfo->read_mem = 0x01E000; meminfo->write_mem = 0x01E000; } else { apple2gs_mem_xxE000(meminfo, 0x010000); } } static void apple2gs_mem_E0D000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { apple2gs_mem_xxD000(meminfo, 0x000000 | APPLE2_MEM_AUX); } static void apple2gs_mem_E0E000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { apple2gs_mem_xxE000(meminfo, 0x000000 | APPLE2_MEM_AUX); } static void apple2gs_mem_E1D000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { apple2gs_mem_xxD000(meminfo, 0x010000 | APPLE2_MEM_AUX); } static void apple2gs_mem_E1E000(offs_t begin, offs_t end, apple2_meminfo *meminfo) { apple2gs_mem_xxE000(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 } }; static UINT8 *apple2gs_getslotmem(offs_t address) { UINT8 *rom; address %= 0x00FFFF; assert(address >= 0xC000); assert(address <= 0xCFFF); rom = memory_region(REGION_CPU1); rom += 0x030000 % memory_region_length(REGION_CPU1); return &rom[address]; } static UINT8 apple2gs_xxCxxx_r(offs_t address) { UINT8 result; int slot; if ((apple2gs_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) { result = mess_ram[address]; } else if ((address & 0x000F00) == 0x000000) { result = apple2gs_c0xx_r(address); } else { slot = (address & 0x000F00) / 0x100; if ((slot > 7) || ((apple2gs_sltromsel & (1 << slot)) == 0)) result = *apple2gs_getslotmem(address); else result = apple2_getfloatingbusvalue(); } return result; } static void apple2gs_xxCxxx_w(offs_t address, UINT8 data) { int slot; if ((apple2gs_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) { mess_ram[address] = data; } else if ((address & 0x000F00) == 0x000000) { apple2gs_c0xx_w(address, data); } else { slot = (address & 0x000F00) / 0x100; if ((slot > 7) || ((apple2gs_sltromsel & (1 << slot)) == 0)) *apple2gs_getslotmem(address) = data; } } static OPBASE_HANDLER( apple2gs_opbase ) { UINT8 *opptr = NULL; int slot; if (((address & 0xFEF000) == 0x00C000) || ((address & 0xFEF000) == 0xE0C000)) { if ((apple2gs_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) { opptr = &mess_ram[address]; } else if ((address & 0x000F00) == 0x000000) { if (((address & 0xFF) >= 0x71) && ((address & 0xFF) <= 0x7F)) opptr = apple2gs_getslotmem(address); } else { slot = (address & 0x000F00) / 0x100; if ((slot > 7) || ((apple2gs_sltromsel & (1 << slot)) == 0)) opptr = apple2gs_getslotmem(address); } if (opptr) { opcode_mask = ~0; opcode_base = opcode_arg_base = opptr - address; opcode_memory_min = address; opcode_memory_max = address; address = ~0; } } return address; } static READ8_HANDLER( apple2gs_00Cxxx_r ) { return apple2gs_xxCxxx_r(offset | 0x00C000); } static READ8_HANDLER( apple2gs_01Cxxx_r ) { return apple2gs_xxCxxx_r(offset | 0x01C000); } static READ8_HANDLER( apple2gs_E0Cxxx_r ) { return apple2gs_xxCxxx_r(offset | 0xE0C000); } static READ8_HANDLER( apple2gs_E1Cxxx_r ) { return apple2gs_xxCxxx_r(offset | 0xE1C000); } static WRITE8_HANDLER( apple2gs_00Cxxx_w) { apple2gs_xxCxxx_w(offset | 0x00C000, data); } static WRITE8_HANDLER( apple2gs_01Cxxx_w) { apple2gs_xxCxxx_w(offset | 0x01C000, data); } static WRITE8_HANDLER( apple2gs_E0Cxxx_w) { apple2gs_xxCxxx_w(offset | 0xE0C000, data); } static WRITE8_HANDLER( apple2gs_E1Cxxx_w) { apple2gs_xxCxxx_w(offset | 0xE1C000, data); } static WRITE8_HANDLER( apple2gs_Exxxxx_w ) { apple2gs_slowmem[offset] = data; apple2_video_touch(offset); } static WRITE8_HANDLER( apple2gs_E004xx_w ) { apple2gs_Exxxxx_w(offset + 0x00400, data); } static WRITE8_HANDLER( apple2gs_E02xxx_w ) { apple2gs_Exxxxx_w(offset + 0x02000, data); } static WRITE8_HANDLER( apple2gs_E104xx_w ) { apple2gs_Exxxxx_w(offset + 0x10400, data); } static WRITE8_HANDLER( apple2gs_E12xxx_w ) { apple2gs_Exxxxx_w(offset + 0x12000, data); } static WRITE8_HANDLER( apple2gs_slowmem_w ) { apple2gs_slowmem[offset] = data; if ((offset >= 0x19e00) && (offset < 0x19fff)) { int color = (offset - 0x19e00) >> 1; palette_set_color_rgb(Machine, color + 16, ((apple2gs_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17, ((apple2gs_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17, ((apple2gs_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17); } } static void apple2gs_setup_memory(void) { offs_t begin, end; apple2_memmap_config cfg; /* allocate memory for E00000-E1FFFF */ apple2gs_slowmem = auto_malloc(128*1024); memset(apple2gs_slowmem, 0, 128*1024); /* install expanded memory */ memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x010000, mess_ram_size - 1, 0, 0, MRA8_BANK1); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x010000, mess_ram_size - 1, 0, 0, MWA8_BANK1); memory_set_bankptr(1, mess_ram + 0x010000); /* install hi memory */ memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe00000, 0xe1ffff, 0, 0, MRA8_BANK2); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe00000, 0xe1ffff, 0, 0, apple2gs_slowmem_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe00400, 0xe007ff, 0, 0, apple2gs_E004xx_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe02000, 0xe03fff, 0, 0, apple2gs_E02xxx_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe10400, 0xe107ff, 0, 0, apple2gs_E104xx_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe12000, 0xe13fff, 0, 0, apple2gs_E12xxx_w); memory_set_bankptr(2, apple2gs_slowmem); /* install alternate ROM bank */ begin = 0x1000000 - memory_region_length(REGION_CPU1); end = 0xffffff; memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, begin, end, 0, 0, MRA8_BANK3); memory_set_bankptr(3, memory_region(REGION_CPU1)); /* install new xxC000-xxCFFF handlers */ memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x00c000, 0x00cfff, 0, 0, apple2gs_00Cxxx_r); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x00c000, 0x00cfff, 0, 0, apple2gs_00Cxxx_w); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x01c000, 0x01cfff, 0, 0, apple2gs_01Cxxx_r); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x01c000, 0x01cfff, 0, 0, apple2gs_01Cxxx_w); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe0c000, 0xe0cfff, 0, 0, apple2gs_E0Cxxx_r); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe0c000, 0xe0cfff, 0, 0, apple2gs_E0Cxxx_w); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe1c000, 0xe1cfff, 0, 0, apple2gs_E1Cxxx_r); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xe1c000, 0xe1cfff, 0, 0, apple2gs_E1Cxxx_w); memory_set_opbase_handler(0, apple2gs_opbase); /* install aux memory writes (for shadowing) */ memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x010400, 0x0107FF, 0, 0, apple2gs_aux0400_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x012000, 0x013FFF, 0, 0, apple2gs_aux2000_w); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x014000, 0x019FFF, 0, 0, apple2gs_aux4000_w); /* setup the Apple II memory system */ memset(&cfg, 0, sizeof(cfg)); cfg.first_bank = 4; cfg.memmap = apple2gs_memmap_entries; cfg.auxmem = apple2gs_slowmem; cfg.auxmem_length = 0x20000; apple2_setup_memory(&cfg); } /* ----------------------------------------------------------------------- * Driver Init * ----------------------------------------------------------------------- */ static READ8_HANDLER( apple2gs_read_vector ) { return program_read_byte(offset | 0xFF0000); } MACHINE_RESET( apple2gs ) { apple2gs_scanline_timer = mame_timer_alloc(apple2gs_scanline_tick); mame_timer_adjust(apple2gs_scanline_timer, time_never, 0, time_never); // fire on scanline zero mame_timer_adjust(apple2gs_scanline_timer, video_screen_get_time_until_pos(0, 0, 0), 0, time_never); } MACHINE_START( apple2gs ) { apple2_config cfg; memset(&cfg, 0, sizeof(cfg)); cfg.slots[0] = &apple2_slot_langcard; cfg.slots[4] = &apple2_slot_mockingboard; cfg.slots[6] = &apple2_slot_iwm; apple2_init_common(machine, &cfg); /* set up Apple IIgs vectoring */ cpunum_set_info_fct(0, CPUINFO_PTR_G65816_READVECTOR_CALLBACK, (genf *) apple2gs_read_vector); /* setup globals */ apple2gs_cur_slot6_image = NULL; apple2gs_newvideo = 0x00; apple2gs_vgcint = 0x00; apple2gs_langsel = 0x00; apple2gs_sltromsel = 0x00; apple2gs_cyareg = 0x80; apple2gs_inten = 0x00; apple2gs_intflag = 0x00; apple2gs_shadow = 0x00; apple2gs_pending_irqs = 0x00; apple2gs_mouse_x = 0x00; apple2gs_mouse_y = 0x00; apple2gs_mouse_dx = 0x00; apple2gs_mouse_dy = 0x00; adb_state = ADBSTATE_IDLE; adb_kmstatus = 0x00; adb_command = 0; adb_mode = 0; adb_latent_result = 0; adb_command_length = 0; adb_command_pos = 0; memset(adb_command_bytes, 0, sizeof(adb_command_bytes)); memset(adb_response_bytes, 0, sizeof(adb_response_bytes)); adb_response_length = 0; adb_response_pos = 0; memset(adb_memory, 0, sizeof(adb_memory)); adb_address_keyboard = 2; adb_address_mouse = 3; /* init time */ clock_data = 0; clock_control =0; clock_read = 0; clock_reg1 = 0; clock_mode = CLOCKMODE_IDLE; clock_curtime = 0; clock_curtime_interval = 0; sndglu_ctrl = 0x00; sndglu_addr = 0; sndglu_dummy_read = 0; /* init the various subsystems */ scc_init(NULL); apple2gs_setup_memory(); }