Previous | 199869 Revisions | Next |
r18114 Monday 24th September, 2012 at 14:43:01 UTC by Miodrag Milanović |
---|
modernization or timer callbacks part 2 (no whatsnew) |
[src/mess/drivers] | atarist.c beta.c coleco.c cxhumax.c fm7.c fmtowns.c gba.c gp32.c intv.c mpf1.c nc.c osi.c pcw.c pdp1.c samcoupe.c sg1000.c studio2.c svision.c tmc1800.c tx0.c x07.c x1.c x68k.c xerox820.c |
[src/mess/includes] | aim65.h amstrad.h apple1.h apple2gs.h atarist.h bbc.h bebox.h beta.h bk.h cgenie.h coleco.h compis.h cxhumax.h dai.h electron.h fm7.h fmtowns.h galaxy.h gamecom.h gb.h gba.h gp32.h hec2hrp.h hp48.h intv.h irisha.h kaypro.h kc.h lisa.h lviv.h lynx.h mac.h macpci.h mbc55x.h mbee.h microtan.h mikro80.h mpf1.h nc.h nes.h odyssey2.h ondra.h oric.h osborne1.h osi.h pc.h pc1251.h pc1350.h pc1401.h pc1403.h pce.h pcw.h pdp1.h pecom.h pet.h pmd85.h pokemini.h poly88.h radio86.h rm380z.h rmnimbus.h samcoupe.h sg1000.h sms.h sorcerer.h special.h studio2.h super80.h svision.h sym1.h ti85.h tmc1800.h trs80.h tx0.h ut88.h vector06.h wswan.h x07.h x1.h x68k.h xerox820.h z80ne.h zx.h |
[src/mess/machine] | aim65.c amstrad.c apple1.c apple2gs.c bbc.c bebox.c bk.c cgenie.c compis.c dai.c electron.c gamecom.c gb.c hec2hrp.c hp48.c intv.c irisha.c kaypro.c kc.c lisa.c lviv.c lynx.c mac.c macpci.c mbc55x.c mbee.c microtan.c mikro80.c nes.c ondra.c oric.c osborne1.c pc.c pc1251.c pc1350.c pc1401.c pc1403.c pce.c pecom.c pet.c pmd85.c pokemini.c poly88.c radio86.c rm380z.c rmnimbus.c samcoupe.c sms.c sorcerer.c special.c super80.c sym1.c ti85.c trs80.c ut88.c vector06.c wswan.c z80ne.c zx.c |
[src/mess/video] | atarist.c electron.c fm7.c fmtowns.c galaxy.c gamecom.c gb.c mac.c odyssey2.c oric.c samcoupe.c x68k.c zx.c |
r18113 | r18114 | |
---|---|---|
32 | 32 | |
33 | 33 | |
34 | 34 | |
35 | ||
35 | TIMER_CALLBACK_MEMBER(cgenie_state::handle_cassette_input) | |
36 | 36 | { |
37 | cgenie_state *state = machine.driver_data<cgenie_state>(); | |
38 | UINT8 new_level = ( (machine.device<cassette_image_device>(CASSETTE_TAG)->input()) > 0.0 ) ? 1 : 0; | |
37 | UINT8 new_level = ( (machine().device<cassette_image_device>(CASSETTE_TAG)->input()) > 0.0 ) ? 1 : 0; | |
39 | 38 | |
40 | if ( new_level != | |
39 | if ( new_level != m_cass_level ) | |
41 | 40 | { |
42 | state->m_cass_level = new_level; | |
43 | state->m_cass_bit ^= 1; | |
41 | m_cass_level = new_level; | |
42 | m_cass_bit ^= 1; | |
44 | 43 | } |
45 | 44 | } |
46 | 45 | |
r18113 | r18114 | |
151 | 150 | space.install_legacy_write_handler(0x4000, 0x4000 + machine().device<ram_device>(RAM_TAG)->size() - 1, FUNC(cgenie_videoram_w)); |
152 | 151 | m_videoram = machine().device<ram_device>(RAM_TAG)->pointer(); |
153 | 152 | membank("bank1")->set_base(machine().device<ram_device>(RAM_TAG)->pointer()); |
154 | machine().scheduler().timer_pulse(attotime::from_hz(11025), FUNC(handle_cassette_input)); | |
153 | machine().scheduler().timer_pulse(attotime::from_hz(11025), timer_expired_delegate(FUNC(cgenie_state::handle_cassette_input),this)); | |
155 | 154 | } |
156 | 155 | |
157 | 156 | /************************************* |
r18113 | r18114 | |
---|---|---|
30 | 30 | static void setup_rom(address_space &space); |
31 | 31 | |
32 | 32 | |
33 | ||
33 | TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback) | |
34 | 34 | { |
35 | sms_state *state = machine.driver_data<sms_state>(); | |
36 | state->m_rapid_fire_state_1 ^= 0xff; | |
37 | state->m_rapid_fire_state_2 ^= 0xff; | |
35 | m_rapid_fire_state_1 ^= 0xff; | |
36 | m_rapid_fire_state_2 ^= 0xff; | |
38 | 37 | } |
39 | 38 | |
40 | 39 | |
r18113 | r18114 | |
487 | 486 | |
488 | 487 | // at each input port read we check if lightguns are enabled in one of the ports: |
489 | 488 | // if so, we turn on crosshair and the lightgun timer |
490 | ||
489 | TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick) | |
491 | 490 | { |
492 | sms_state *state = machine.driver_data<sms_state>(); | |
493 | 491 | |
494 | if (( | |
492 | if ((ioport("CTRLSEL")->read_safe(0x00) & 0x0f) == 0x01) | |
495 | 493 | { |
496 | 494 | /* enable crosshair */ |
497 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL); | |
498 | if (!state->m_lphaser_1_timer->enabled()) | |
499 | lphaser1_sensor_check(machine); | |
495 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); | |
496 | if (!m_lphaser_1_timer->enabled()) | |
497 | lphaser1_sensor_check(machine()); | |
500 | 498 | } |
501 | 499 | else |
502 | 500 | { |
503 | 501 | /* disable crosshair */ |
504 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE); | |
505 | state->m_lphaser_1_timer->enable(0); | |
502 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); | |
503 | m_lphaser_1_timer->enable(0); | |
506 | 504 | } |
507 | 505 | |
508 | if (( | |
506 | if ((ioport("CTRLSEL")->read_safe(0x00) & 0xf0) == 0x10) | |
509 | 507 | { |
510 | 508 | /* enable crosshair */ |
511 | crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_ALL); | |
512 | if (!state->m_lphaser_2_timer->enabled()) | |
513 | lphaser2_sensor_check(machine); | |
509 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); | |
510 | if (!m_lphaser_2_timer->enabled()) | |
511 | lphaser2_sensor_check(machine()); | |
514 | 512 | } |
515 | 513 | else |
516 | 514 | { |
517 | 515 | /* disable crosshair */ |
518 | crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_NONE); | |
519 | state->m_lphaser_2_timer->enable(0); | |
516 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE); | |
517 | m_lphaser_2_timer->enable(0); | |
520 | 518 | } |
521 | 519 | } |
522 | 520 | |
523 | 521 | |
524 | ||
522 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback) | |
525 | 523 | { |
526 | lphaser1_sensor_check(machine); | |
524 | lphaser1_sensor_check(machine()); | |
527 | 525 | } |
528 | 526 | |
529 | 527 | |
530 | ||
528 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback) | |
531 | 529 | { |
532 | lphaser2_sensor_check(machine); | |
530 | lphaser2_sensor_check(machine()); | |
533 | 531 | } |
534 | 532 | |
535 | 533 | |
r18113 | r18114 | |
571 | 569 | } |
572 | 570 | |
573 | 571 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ |
574 | machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); | |
572 | machine.scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),state)); | |
575 | 573 | |
576 | 574 | /* Player 1 */ |
577 | 575 | switch (machine.root_device().ioport("CTRLSEL")->read_safe(0x00) & 0x0f) |
r18113 | r18114 | |
1926 | 1924 | { |
1927 | 1925 | |
1928 | 1926 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sms_machine_stop),&machine())); |
1929 | m_rapid_fire_timer = machine().scheduler().timer_alloc(FUNC(rapid_fire_callback)); | |
1927 | m_rapid_fire_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::rapid_fire_callback),this)); | |
1930 | 1928 | m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10)); |
1931 | 1929 | |
1932 | m_lphaser_1_timer = machine().scheduler().timer_alloc(FUNC(lphaser_1_callback)); | |
1933 | m_lphaser_2_timer = machine().scheduler().timer_alloc(FUNC(lphaser_2_callback)); | |
1930 | m_lphaser_1_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_1_callback),this)); | |
1931 | m_lphaser_2_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_2_callback),this)); | |
1934 | 1932 | |
1935 | 1933 | m_main_cpu = machine().device("maincpu"); |
1936 | 1934 | m_control_cpu = machine().device("control"); |
r18113 | r18114 | |
1943 | 1941 | m_space = &machine().device("maincpu")->memory().space(AS_PROGRAM); |
1944 | 1942 | |
1945 | 1943 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ |
1946 | machine().scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); | |
1944 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sms_state::lightgun_tick),this)); | |
1947 | 1945 | } |
1948 | 1946 | |
1949 | 1947 | MACHINE_RESET_MEMBER(sms_state,sms) |
r18113 | r18114 | |
---|---|---|
154 | 154 | { DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_HANDLER("i8275", i8275_dack_w), DEVCB_NULL } |
155 | 155 | }; |
156 | 156 | |
157 | ||
157 | TIMER_CALLBACK_MEMBER(radio86_state::radio86_reset) | |
158 | 158 | { |
159 | radio86_state *state = machine.driver_data<radio86_state>(); | |
160 | state->membank("bank1")->set_entry(0); | |
159 | membank("bank1")->set_entry(0); | |
161 | 160 | } |
162 | 161 | |
163 | 162 | |
r18113 | r18114 | |
178 | 177 | |
179 | 178 | MACHINE_RESET_MEMBER(radio86_state,radio86) |
180 | 179 | { |
181 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(radio86_reset)); | |
180 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(radio86_state::radio86_reset),this)); | |
182 | 181 | membank("bank1")->set_entry(1); |
183 | 182 | |
184 | 183 | m_keyboard_mask = 0; |
r18113 | r18114 | |
---|---|---|
650 | 650 | } |
651 | 651 | |
652 | 652 | |
653 | ||
653 | TIMER_CALLBACK_MEMBER(intv_state::intv_interrupt_complete) | |
654 | 654 | { |
655 | intv_state *state = machine.driver_data<intv_state>(); | |
656 | machine.device("maincpu")->execute().set_input_line(CP1610_INT_INTRM, CLEAR_LINE); | |
657 | state->m_bus_copy_mode = 0; | |
655 | machine().device("maincpu")->execute().set_input_line(CP1610_INT_INTRM, CLEAR_LINE); | |
656 | m_bus_copy_mode = 0; | |
658 | 657 | } |
659 | 658 | |
660 | ||
659 | TIMER_CALLBACK_MEMBER(intv_state::intv_btb_fill) | |
661 | 660 | { |
662 | intv_state *state = machine.driver_data<intv_state>(); | |
663 | 661 | UINT8 column; |
664 | UINT8 row = state->m_backtab_row; | |
665 | //machine.device("maincpu")->execute().adjust_icount(-STIC_ROW_FETCH); | |
662 | UINT8 row = m_backtab_row; | |
663 | //machine().device("maincpu")->execute().adjust_icount(-STIC_ROW_FETCH); | |
666 | 664 | for(column=0; column < STIC_BACKTAB_WIDTH; column++) |
667 | 665 | { |
668 | | |
666 | m_backtab_buffer[row][column] = m_ram16[column + row * STIC_BACKTAB_WIDTH]; | |
669 | 667 | } |
670 | 668 | |
671 | | |
669 | m_backtab_row += 1; | |
672 | 670 | } |
673 | 671 | |
674 | 672 | INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt) |
r18113 | r18114 | |
680 | 678 | UINT8 row; |
681 | 679 | machine().device("maincpu")->execute().adjust_icount(-(12*STIC_ROW_BUSRQ+STIC_FRAME_BUSRQ)); // Account for stic cycle stealing |
682 | 680 | machine().scheduler().timer_set(machine().device<cpu_device>("maincpu") |
683 | ->cycles_to_attotime(STIC_VBLANK_END), FUNC(intv_interrupt_complete)); | |
681 | ->cycles_to_attotime(STIC_VBLANK_END), timer_expired_delegate(FUNC(intv_state::intv_interrupt_complete),this)); | |
684 | 682 | for (row=0; row < STIC_BACKTAB_HEIGHT; row++) |
685 | 683 | { |
686 | 684 | machine().scheduler().timer_set(machine().device<cpu_device>("maincpu") |
687 | ->cycles_to_attotime(STIC_FIRST_FETCH-STIC_FRAME_BUSRQ+STIC_CYCLES_PER_SCANLINE*STIC_Y_SCALE*m_row_delay + (STIC_CYCLES_PER_SCANLINE*STIC_Y_SCALE*STIC_CARD_HEIGHT - STIC_ROW_BUSRQ)*row), FUNC(intv_btb_fill)); | |
685 | ->cycles_to_attotime(STIC_FIRST_FETCH-STIC_FRAME_BUSRQ+STIC_CYCLES_PER_SCANLINE*STIC_Y_SCALE*m_row_delay + (STIC_CYCLES_PER_SCANLINE*STIC_Y_SCALE*STIC_CARD_HEIGHT - STIC_ROW_BUSRQ)*row), timer_expired_delegate(FUNC(intv_state::intv_btb_fill),this)); | |
688 | 686 | } |
689 | 687 | |
690 | 688 | if (m_row_delay == 0) |
r18113 | r18114 | |
---|---|---|
210 | 210 | } |
211 | 211 | } |
212 | 212 | |
213 | ||
213 | TIMER_CALLBACK_MEMBER(kc_state::kc_cassette_oneshot_timer) | |
214 | 214 | { |
215 | kc_state *state = machine.driver_data<kc_state>(); | |
216 | 215 | |
217 | | |
216 | update_cassette(0); | |
218 | 217 | |
219 | | |
218 | m_cassette_oneshot_timer->reset(); | |
220 | 219 | } |
221 | 220 | |
222 | 221 | // timer used for polling data from cassette input |
223 | 222 | // enabled only when cassette motor is on |
224 | ||
223 | TIMER_CALLBACK_MEMBER(kc_state::kc_cassette_timer_callback) | |
225 | 224 | { |
226 | kc_state *state = machine.driver_data<kc_state>(); | |
227 | 225 | |
228 | 226 | // read cassette data |
229 | int bit = ( | |
227 | int bit = (m_cassette->input() > 0.0038) ? 1 : 0; | |
230 | 228 | |
231 | 229 | // generates a pulse when the cassette input changes state |
232 | if (bit ^ | |
230 | if (bit ^ m_cassette_in) | |
233 | 231 | { |
234 | state->update_cassette(1); | |
235 | state->m_cassette_in = bit; | |
236 | state->m_cassette_oneshot_timer->adjust(attotime::from_double(TIME_OF_74LS123(RES_K(10), CAP_N(1)))); | |
232 | update_cassette(1); | |
233 | m_cassette_in = bit; | |
234 | m_cassette_oneshot_timer->adjust(attotime::from_double(TIME_OF_74LS123(RES_K(10), CAP_N(1)))); | |
237 | 235 | } |
238 | 236 | } |
239 | 237 | |
r18113 | r18114 | |
759 | 757 | |
760 | 758 | void kc_state::machine_start() |
761 | 759 | { |
762 | m_cassette_timer = machine().scheduler().timer_alloc(FUNC(kc_cassette_timer_callback)); | |
763 | m_cassette_oneshot_timer = machine().scheduler().timer_alloc(FUNC(kc_cassette_oneshot_timer)); | |
760 | m_cassette_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kc_state::kc_cassette_timer_callback),this)); | |
761 | m_cassette_oneshot_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kc_state::kc_cassette_oneshot_timer),this)); | |
764 | 762 | |
765 | 763 | m_ram_base = m_ram->pointer(); |
766 | 764 |
r18113 | r18114 | |
---|---|---|
285 | 285 | } |
286 | 286 | } |
287 | 287 | |
288 | ||
288 | TIMER_CALLBACK_MEMBER(mbc55x_state::keyscan_callback) | |
289 | 289 | { |
290 | scan_keyboard(machine); | |
290 | scan_keyboard(machine()); | |
291 | 291 | } |
292 | 292 | |
293 | 293 | /* i8251 serial */ |
r18113 | r18114 | |
409 | 409 | m_debug_machine=DEBUG_NONE; |
410 | 410 | |
411 | 411 | // Allocate keyscan timer |
412 | m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(FUNC(keyscan_callback)); | |
412 | m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mbc55x_state::keyscan_callback),this)); | |
413 | 413 | } |
414 | 414 | |
415 | 415 |
r18113 | r18114 | |
---|---|---|
60 | 60 | DEVCB_NULL, |
61 | 61 | }; |
62 | 62 | |
63 | ||
63 | TIMER_CALLBACK_MEMBER(ut88_state::ut88_reset) | |
64 | 64 | { |
65 | ut88_state *state = machine.driver_data<ut88_state>(); | |
66 | state->membank("bank1")->set_entry(0); | |
65 | membank("bank1")->set_entry(0); | |
67 | 66 | } |
68 | 67 | |
69 | 68 | MACHINE_RESET_MEMBER(ut88_state,ut88) |
70 | 69 | { |
71 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(ut88_reset)); | |
70 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(ut88_state::ut88_reset),this)); | |
72 | 71 | membank("bank1")->set_entry(1); |
73 | 72 | m_keyboard_mask = 0; |
74 | 73 | } |
r18113 | r18114 | |
148 | 147 | 0x39, 0x5e, 0x79, 0x71 |
149 | 148 | }; |
150 | 149 | |
151 | ||
150 | TIMER_CALLBACK_MEMBER(ut88_state::update_display) | |
152 | 151 | { |
153 | ut88_state *state = machine.driver_data<ut88_state>(); | |
154 | 152 | int i; |
155 | 153 | for (i=0;i<6;i++) |
156 | output_set_digit_value(i, hex_to_7seg[ | |
154 | output_set_digit_value(i, hex_to_7seg[m_lcd_digit[i]]); | |
157 | 155 | } |
158 | 156 | |
159 | 157 | |
r18113 | r18114 | |
163 | 161 | |
164 | 162 | MACHINE_START_MEMBER(ut88_state,ut88mini) |
165 | 163 | { |
166 | machine().scheduler().timer_pulse(attotime::from_hz(60), FUNC(update_display)); | |
164 | machine().scheduler().timer_pulse(attotime::from_hz(60), timer_expired_delegate(FUNC(ut88_state::update_display),this)); | |
167 | 165 | } |
168 | 166 | |
169 | 167 | MACHINE_RESET_MEMBER(ut88_state,ut88mini) |
r18113 | r18114 | |
---|---|---|
152 | 152 | machine.device<nvram_device>("ram_nvram")->set_base(ram, 0x8000); |
153 | 153 | } |
154 | 154 | |
155 | ||
155 | TIMER_CALLBACK_MEMBER(pc1403_state::pc1403_power_up) | |
156 | 156 | { |
157 | pc1403_state *state = machine.driver_data<pc1403_state>(); | |
158 | state->m_power=0; | |
157 | m_power=0; | |
159 | 158 | } |
160 | 159 | |
161 | 160 | DRIVER_INIT_MEMBER(pc1403_state,pc1403) |
r18113 | r18114 | |
166 | 165 | for (i=0; i<128; i++) gfx[i]=i; |
167 | 166 | |
168 | 167 | m_power = 1; |
169 | machine().scheduler().timer_set(attotime::from_seconds(1), FUNC(pc1403_power_up)); | |
168 | machine().scheduler().timer_set(attotime::from_seconds(1), timer_expired_delegate(FUNC(pc1403_state::pc1403_power_up),this)); | |
170 | 169 | |
171 | 170 | membank("bank1")->set_base(memregion("user1")->base()); |
172 | 171 | } |
r18113 | r18114 | |
---|---|---|
51 | 51 | #include "imagedev/cassette.h" |
52 | 52 | #include "machine/ram.h" |
53 | 53 | |
54 | static TIMER_CALLBACK(apple1_kbd_poll); | |
55 | static TIMER_CALLBACK(apple1_kbd_strobe_end); | |
56 | 54 | |
55 | ||
56 | ||
57 | 57 | static DECLARE_READ8_DEVICE_HANDLER( apple1_pia0_kbdin ); |
58 | 58 | static DECLARE_WRITE8_DEVICE_HANDLER( apple1_pia0_dspout ); |
59 | 59 | static DECLARE_WRITE8_DEVICE_HANDLER( apple1_pia0_dsp_write_signal ); |
60 | 60 | |
61 | static TIMER_CALLBACK(apple1_dsp_ready_start); | |
62 | static TIMER_CALLBACK(apple1_dsp_ready_end); | |
63 | 61 | |
62 | ||
63 | ||
64 | 64 | /***************************************************************************** |
65 | 65 | ** Structures |
66 | 66 | *****************************************************************************/ |
r18113 | r18114 | |
158 | 158 | |
159 | 159 | A 120-Hz poll rate seems to be fast enough to ensure no |
160 | 160 | keystrokes are missed. */ |
161 | machine().scheduler().timer_pulse(attotime::from_hz(120), FUNC(apple1_kbd_poll)); | |
161 | machine().scheduler().timer_pulse(attotime::from_hz(120), timer_expired_delegate(FUNC(apple1_state::apple1_kbd_poll),this)); | |
162 | 162 | } |
163 | 163 | |
164 | 164 | |
r18113 | r18114 | |
277 | 277 | ** If multiple newly-pressed keys are found, the one closest to the |
278 | 278 | ** end of the input ports list is counted; the others are ignored. |
279 | 279 | *****************************************************************************/ |
280 | ||
280 | TIMER_CALLBACK_MEMBER(apple1_state::apple1_kbd_poll) | |
281 | 281 | { |
282 | apple1_state *state = machine.driver_data<apple1_state>(); | |
283 | 282 | int port, bit; |
284 | 283 | int key_pressed; |
285 | 284 | UINT32 shiftkeys, ctrlkeys; |
286 | pia6821_device *pia = machine.device<pia6821_device>("pia"); | |
285 | pia6821_device *pia = machine().device<pia6821_device>("pia"); | |
287 | 286 | static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3" }; |
288 | 287 | |
289 | 288 | /* This holds the values of all the input ports for ordinary keys |
r18113 | r18114 | |
292 | 291 | /* First we check the RESET and CLEAR SCREEN pushbutton switches. */ |
293 | 292 | |
294 | 293 | /* The RESET switch resets the CPU and the 6820 PIA. */ |
295 | if (machine.root_device().ioport("KEY5")->read() & 0x0001) | |
294 | if (machine().root_device().ioport("KEY5")->read() & 0x0001) | |
296 | 295 | { |
297 | if (!state->m_reset_flag) { | |
298 | state->m_reset_flag = 1; | |
296 | if (!m_reset_flag) { | |
297 | m_reset_flag = 1; | |
299 | 298 | /* using PULSE_LINE does not allow us to press and hold key */ |
300 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); | |
299 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); | |
301 | 300 | pia->reset(); |
302 | 301 | } |
303 | 302 | } |
304 | else if ( | |
303 | else if (m_reset_flag) { | |
305 | 304 | /* RESET released--allow the processor to continue. */ |
306 | state->m_reset_flag = 0; | |
307 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); | |
305 | m_reset_flag = 0; | |
306 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); | |
308 | 307 | } |
309 | 308 | |
310 | 309 | /* The CLEAR SCREEN switch clears the video hardware. */ |
311 | if (machine.root_device().ioport("KEY5")->read() & 0x0002) | |
310 | if (machine().root_device().ioport("KEY5")->read() & 0x0002) | |
312 | 311 | { |
313 | if (! | |
312 | if (!m_vh_clrscrn_pressed) | |
314 | 313 | { |
315 | 314 | /* Ignore further video writes, and clear the screen. */ |
316 | state->m_vh_clrscrn_pressed = 1; | |
317 | apple1_vh_dsp_clr(machine); | |
315 | m_vh_clrscrn_pressed = 1; | |
316 | apple1_vh_dsp_clr(machine()); | |
318 | 317 | } |
319 | 318 | } |
320 | else if ( | |
319 | else if (m_vh_clrscrn_pressed) | |
321 | 320 | { |
322 | 321 | /* CLEAR SCREEN released--pay attention to video writes again. */ |
323 | | |
322 | m_vh_clrscrn_pressed = 0; | |
324 | 323 | } |
325 | 324 | |
326 | 325 | /* Now we scan all the input ports for ordinary keys, recording |
327 | 326 | new keypresses while ignoring keys that were already pressed in |
328 | 327 | the last scan. */ |
329 | 328 | |
330 | | |
329 | m_kbd_data = 0; | |
331 | 330 | key_pressed = 0; |
332 | 331 | |
333 | 332 | /* The keyboard strobe line should always be low when a scan starts. */ |
334 | 333 | pia->ca1_w(0); |
335 | 334 | |
336 | shiftkeys = machine.root_device().ioport("KEY4")->read() & 0x0003; | |
337 | ctrlkeys = machine.root_device().ioport("KEY4")->read() & 0x000c; | |
335 | shiftkeys = machine().root_device().ioport("KEY4")->read() & 0x0003; | |
336 | ctrlkeys = machine().root_device().ioport("KEY4")->read() & 0x000c; | |
338 | 337 | |
339 | 338 | for (port = 0; port < 4; port++) |
340 | 339 | { |
341 | 340 | UINT32 portval, newkeys; |
342 | 341 | |
343 | portval = machine.root_device().ioport(keynames[port])->read(); | |
344 | newkeys = portval & ~(state->m_kbd_last_scan[port]); | |
342 | portval = machine().root_device().ioport(keynames[port])->read(); | |
343 | newkeys = portval & ~(m_kbd_last_scan[port]); | |
345 | 344 | |
346 | 345 | if (newkeys) |
347 | 346 | { |
r18113 | r18114 | |
349 | 348 | for (bit = 0; bit < 16; bit++) { |
350 | 349 | if (newkeys & 1) |
351 | 350 | { |
352 | | |
351 | m_kbd_data = (ctrlkeys) | |
353 | 352 | ? apple1_control_keymap[port*16 + bit] |
354 | 353 | : (shiftkeys) |
355 | 354 | ? apple1_shifted_keymap[port*16 + bit] |
r18113 | r18114 | |
358 | 357 | newkeys >>= 1; |
359 | 358 | } |
360 | 359 | } |
361 | | |
360 | m_kbd_last_scan[port] = portval; | |
362 | 361 | } |
363 | 362 | |
364 | 363 | if (key_pressed) |
r18113 | r18114 | |
366 | 365 | /* The keyboard will pulse its strobe line when a key is |
367 | 366 | pressed. A 10-usec pulse is typical. */ |
368 | 367 | pia->ca1_w(1); |
369 | machine.scheduler().timer_set(attotime::from_usec(10), FUNC(apple1_kbd_strobe_end)); | |
368 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(apple1_state::apple1_kbd_strobe_end),this)); | |
370 | 369 | } |
371 | 370 | } |
372 | 371 | |
373 | ||
372 | TIMER_CALLBACK_MEMBER(apple1_state::apple1_kbd_strobe_end) | |
374 | 373 | { |
375 | pia6821_device *pia = machine.device<pia6821_device>("pia"); | |
374 | pia6821_device *pia = machine().device<pia6821_device>("pia"); | |
376 | 375 | |
377 | 376 | /* End of the keyboard strobe pulse. */ |
378 | 377 | pia->ca1_w(0); |
r18113 | r18114 | |
412 | 411 | Only then will it assert \RDA to signal readiness for another |
413 | 412 | write. Thus the write delay depends on the cursor position and |
414 | 413 | where the display is in the refresh cycle. */ |
414 | apple1_state *state = space.machine().driver_data<apple1_state>(); | |
415 | 415 | if (!data) |
416 | space.machine().scheduler().timer_set(apple1_vh_dsp_time_to_ready(space.machine()), FUNC(apple1_dsp_ready_start)); | |
416 | space.machine().scheduler().timer_set(apple1_vh_dsp_time_to_ready(space.machine()), timer_expired_delegate(FUNC(apple1_state::apple1_dsp_ready_start),state)); | |
417 | 417 | } |
418 | 418 | |
419 | ||
419 | TIMER_CALLBACK_MEMBER(apple1_state::apple1_dsp_ready_start) | |
420 | 420 | { |
421 | pia6821_device *pia = machine.device<pia6821_device>("pia"); | |
421 | pia6821_device *pia = machine().device<pia6821_device>("pia"); | |
422 | 422 | |
423 | 423 | /* When the display asserts \RDA to signal it is ready, it |
424 | 424 | triggers a 74123 one-shot to send a 3.5-usec low pulse to PIA |
425 | 425 | input CB1. The end of this pulse will tell the PIA that the |
426 | 426 | display is ready for another write. */ |
427 | 427 | pia->cb1_w(0); |
428 | machine.scheduler().timer_set(attotime::from_nsec(3500), FUNC(apple1_dsp_ready_end)); | |
428 | machine().scheduler().timer_set(attotime::from_nsec(3500), timer_expired_delegate(FUNC(apple1_state::apple1_dsp_ready_end),this)); | |
429 | 429 | } |
430 | 430 | |
431 | ||
431 | TIMER_CALLBACK_MEMBER(apple1_state::apple1_dsp_ready_end) | |
432 | 432 | { |
433 | pia6821_device *pia = machine.device<pia6821_device>("pia"); | |
433 | pia6821_device *pia = machine().device<pia6821_device>("pia"); | |
434 | 434 | |
435 | 435 | /* The one-shot pulse has ended; return CB1 to high, so we can do |
436 | 436 | another display write. */ |
r18113 | r18114 | |
---|---|---|
22 | 22 | #define MODEL4_MASTER_CLOCK 20275200 |
23 | 23 | |
24 | 24 | |
25 | ||
25 | TIMER_CALLBACK_MEMBER(trs80_state::cassette_data_callback) | |
26 | 26 | { |
27 | trs80_state *state = machine.driver_data<trs80_state>(); | |
28 | 27 | /* This does all baud rates. 250 baud (trs80), and 500 baud (all others) set bit 7 of "cassette_data". |
29 | 28 | 1500 baud (trs80m3, trs80m4) is interrupt-driven and uses bit 0 of "cassette_data" */ |
30 | 29 | |
31 | double new_val = ( | |
30 | double new_val = (m_cass->input()); | |
32 | 31 | |
33 | 32 | /* Check for HI-LO transition */ |
34 | if ( | |
33 | if ( m_old_cassette_val > -0.2 && new_val < -0.2 ) | |
35 | 34 | { |
36 | state->m_cassette_data |= 0x80; /* 500 baud */ | |
37 | if (state->m_mask & CASS_FALL) /* see if 1500 baud */ | |
35 | m_cassette_data |= 0x80; /* 500 baud */ | |
36 | if (m_mask & CASS_FALL) /* see if 1500 baud */ | |
38 | 37 | { |
39 | state->m_cassette_data = 0; | |
40 | state->m_irq |= CASS_FALL; | |
41 | machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
38 | m_cassette_data = 0; | |
39 | m_irq |= CASS_FALL; | |
40 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
42 | 41 | } |
43 | 42 | } |
44 | 43 | else |
45 | if ( | |
44 | if ( m_old_cassette_val < -0.2 && new_val > -0.2 ) | |
46 | 45 | { |
47 | if ( | |
46 | if (m_mask & CASS_RISE) /* 1500 baud */ | |
48 | 47 | { |
49 | state->m_cassette_data = 1; | |
50 | state->m_irq |= CASS_RISE; | |
51 | machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
48 | m_cassette_data = 1; | |
49 | m_irq |= CASS_RISE; | |
50 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
52 | 51 | } |
53 | 52 | } |
54 | 53 | |
55 | | |
54 | m_old_cassette_val = new_val; | |
56 | 55 | } |
57 | 56 | |
58 | 57 | |
r18113 | r18114 | |
852 | 851 | m_reg_load=1; |
853 | 852 | m_nmi_data=0xff; |
854 | 853 | |
855 | m_cassette_data_timer = machine().scheduler().timer_alloc(FUNC(cassette_data_callback)); | |
854 | m_cassette_data_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(trs80_state::cassette_data_callback),this)); | |
856 | 855 | m_cassette_data_timer->adjust( attotime::zero, 0, attotime::from_hz(11025) ); |
857 | 856 | } |
858 | 857 |
r18113 | r18114 | |
---|---|---|
127 | 127 | |
128 | 128 | extern TIMER_CALLBACK(mac_adb_tick); // macadb.c |
129 | 129 | extern TIMER_CALLBACK(mac_pmu_tick); // macadb.c |
130 | static TIMER_CALLBACK(mac_scanline_tick); | |
131 | static TIMER_CALLBACK(mac_6015_tick); | |
130 | ||
131 | ||
132 | 132 | static int scan_keyboard(running_machine &machine); |
133 | ||
133 | ||
134 | 134 | static void keyboard_receive(running_machine &machine, int val); |
135 | 135 | static DECLARE_READ8_DEVICE_HANDLER(mac_via_in_a); |
136 | 136 | static DECLARE_READ8_DEVICE_HANDLER(mac_via_in_b); |
r18113 | r18114 | |
695 | 695 | |
696 | 696 | /******************* Keyboard <-> VIA communication ***********************/ |
697 | 697 | |
698 | ||
698 | TIMER_CALLBACK_MEMBER(mac_state::kbd_clock) | |
699 | 699 | { |
700 | 700 | int i; |
701 | mac_state *mac = machine.driver_data<mac_state>(); | |
702 | 701 | |
703 | if (m | |
702 | if (m_kbd_comm == TRUE) | |
704 | 703 | { |
705 | 704 | for (i=0; i<8; i++) |
706 | 705 | { |
707 | 706 | /* Put data on CB2 if we are sending*/ |
708 | if (mac->m_kbd_receive == FALSE) | |
709 | mac->m_via1->write_cb2(mac->m_kbd_shift_reg&0x80?1:0); | |
710 | mac->m_kbd_shift_reg <<= 1; | |
711 | mac->m_via1->write_cb1(0); | |
712 | mac->m_via1->write_cb1(1); | |
707 | if (m_kbd_receive == FALSE) | |
708 | m_via1->write_cb2(m_kbd_shift_reg&0x80?1:0); | |
709 | m_kbd_shift_reg <<= 1; | |
710 | m_via1->write_cb1(0); | |
711 | m_via1->write_cb1(1); | |
713 | 712 | } |
714 | if (m | |
713 | if (m_kbd_receive == TRUE) | |
715 | 714 | { |
716 | m | |
715 | m_kbd_receive = FALSE; | |
717 | 716 | /* Process the command received from mac */ |
718 | keyboard_receive(machine, | |
717 | keyboard_receive(machine(), m_kbd_shift_reg & 0xff); | |
719 | 718 | } |
720 | 719 | else |
721 | 720 | { |
722 | 721 | /* Communication is over */ |
723 | m | |
722 | m_kbd_comm = FALSE; | |
724 | 723 | } |
725 | 724 | } |
726 | 725 | } |
r18113 | r18114 | |
732 | 731 | if (mac->m_kbd_comm == TRUE) |
733 | 732 | { |
734 | 733 | mac->m_kbd_shift_reg = data; |
735 | machine.scheduler().timer_set(attotime::from_msec(1), FUNC(kbd_clock)); | |
734 | machine.scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(mac_state::kbd_clock),mac)); | |
736 | 735 | } |
737 | 736 | } |
738 | 737 | |
r18113 | r18114 | |
745 | 744 | /* Mac pulls CB2 down to initiate communication */ |
746 | 745 | mac->m_kbd_comm = TRUE; |
747 | 746 | mac->m_kbd_receive = TRUE; |
748 | space.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(kbd_clock)); | |
747 | space.machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(mac_state::kbd_clock),mac)); | |
749 | 748 | } |
750 | 749 | if (mac->m_kbd_comm == TRUE && mac->m_kbd_receive == TRUE) |
751 | 750 | { |
r18113 | r18114 | |
757 | 756 | /* |
758 | 757 | called when inquiry times out (1/4s) |
759 | 758 | */ |
760 | ||
759 | TIMER_CALLBACK_MEMBER(mac_state::inquiry_timeout_func) | |
761 | 760 | { |
762 | 761 | if (LOG_KEYBOARD) |
763 | 762 | logerror("keyboard enquiry timeout\n"); |
764 | kbd_shift_out(machine, 0x7B); /* always send NULL */ | |
763 | kbd_shift_out(machine(), 0x7B); /* always send NULL */ | |
765 | 764 | } |
766 | 765 | |
767 | 766 | /* |
r18113 | r18114 | |
1770 | 1769 | } |
1771 | 1770 | |
1772 | 1771 | // This signal is generated internally on RBV, V8, Sonora, VASP, Eagle, etc. |
1773 | ||
1772 | TIMER_CALLBACK_MEMBER(mac_state::mac_6015_tick) | |
1774 | 1773 | { |
1775 | mac_state *mac = machine.driver_data<mac_state>(); | |
1776 | ||
1777 | mac->m_via1->write_ca1(0); | |
1778 | mac->m_via1->write_ca1(1); | |
1774 | m_via1->write_ca1(0); | |
1775 | m_via1->write_ca1(1); | |
1779 | 1776 | } |
1780 | 1777 | |
1781 | 1778 | /* ************************************************************************* |
r18113 | r18114 | |
1798 | 1795 | } |
1799 | 1796 | |
1800 | 1797 | } |
1801 | this->m_scanline_timer = machine().scheduler().timer_alloc(FUNC(mac_scanline_tick)); | |
1798 | this->m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::mac_scanline_tick),this)); | |
1802 | 1799 | this->m_scanline_timer->adjust(machine().primary_screen->time_until_pos(0, 0)); |
1803 | 1800 | |
1804 | m_6015_timer = machine().scheduler().timer_alloc(FUNC(mac_6015_tick)); | |
1801 | m_6015_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::mac_6015_tick),this)); | |
1805 | 1802 | m_6015_timer->adjust(attotime::never); |
1806 | 1803 | } |
1807 | 1804 | |
r18113 | r18114 | |
2105 | 2102 | /* setup keyboard */ |
2106 | 2103 | keyboard_init(mac); |
2107 | 2104 | |
2108 | mac->m_inquiry_timeout = machine.scheduler().timer_alloc(FUNC(inquiry_timeout_func)); | |
2105 | mac->m_inquiry_timeout = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::inquiry_timeout_func),mac)); | |
2109 | 2106 | |
2110 | 2107 | /* save state stuff */ |
2111 | 2108 | machine.save().register_postload(save_prepost_delegate(FUNC(mac_state_load), mac)); |
r18113 | r18114 | |
2251 | 2248 | } |
2252 | 2249 | } |
2253 | 2250 | |
2254 | ||
2251 | TIMER_CALLBACK_MEMBER(mac_state::mac_scanline_tick) | |
2255 | 2252 | { |
2256 | 2253 | int scanline; |
2257 | mac_state *mac = machine.driver_data<mac_state>(); | |
2258 | 2254 | |
2259 | if (machine.device("custom") != NULL) | |
2255 | if (machine().device("custom") != NULL) | |
2260 | 2256 | { |
2261 | mac_sh_updatebuffer(machine.device("custom")); | |
2257 | mac_sh_updatebuffer(machine().device("custom")); | |
2262 | 2258 | } |
2263 | 2259 | |
2264 | if (m | |
2260 | if (m_rbv_vbltime > 0) | |
2265 | 2261 | { |
2266 | m | |
2262 | m_rbv_vbltime--; | |
2267 | 2263 | |
2268 | if (m | |
2264 | if (m_rbv_vbltime == 0) | |
2269 | 2265 | { |
2270 | mac->m_rbv_regs[2] |= 0x40; | |
2271 | mac->rbv_recalc_irqs(); | |
2266 | m_rbv_regs[2] |= 0x40; | |
2267 | rbv_recalc_irqs(); | |
2272 | 2268 | } |
2273 | 2269 | } |
2274 | 2270 | |
2275 | scanline = machine.primary_screen->vpos(); | |
2271 | scanline = machine().primary_screen->vpos(); | |
2276 | 2272 | if (scanline == MAC_V_VIS) |
2277 | | |
2273 | vblank_irq(); | |
2278 | 2274 | |
2279 | 2275 | /* check for mouse changes at 10 irqs per frame */ |
2280 | if (m | |
2276 | if (m_model <= MODEL_MAC_PLUS) | |
2281 | 2277 | { |
2282 | 2278 | if (!(scanline % 10)) |
2283 | m | |
2279 | mouse_callback(); | |
2284 | 2280 | } |
2285 | 2281 | |
2286 | m | |
2282 | m_scanline_timer->adjust(machine().primary_screen->time_until_pos((scanline+1) % MAC_V_TOTAL, 0)); | |
2287 | 2283 | } |
2288 | 2284 | |
2289 | 2285 | WRITE_LINE_MEMBER(mac_state::nubus_irq_9_w) |
r18113 | r18114 | |
---|---|---|
95 | 95 | #define RS232_DELAY attotime::from_usec( 300 ) |
96 | 96 | |
97 | 97 | /* end of receive event */ |
98 | ||
98 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_recv_cb) | |
99 | 99 | { |
100 | hp48_state *state = machine.driver_data<hp48_state>(); | |
101 | 100 | LOG_SERIAL(( "%f hp48_rs232_byte_recv_cb: end of receive, data=%02x\n", |
102 | machine.time().as_double(), param )); | |
101 | machine().time().as_double(), param )); | |
103 | 102 | |
104 | state->m_io[0x14] = param & 0xf; /* receive zone */ | |
105 | state->m_io[0x15] = param >> 4; | |
106 | state->m_io[0x11] &= ~2; /* clear byte receiving */ | |
107 | state->m_io[0x11] |= 1; /* set byte received */ | |
103 | m_io[0x14] = param & 0xf; /* receive zone */ | |
104 | m_io[0x15] = param >> 4; | |
105 | m_io[0x11] &= ~2; /* clear byte receiving */ | |
106 | m_io[0x11] |= 1; /* set byte received */ | |
108 | 107 | |
109 | 108 | /* interrupt */ |
110 | if ( | |
109 | if ( m_io[0x10] & 2 ) | |
111 | 110 | { |
112 | hp48_pulse_irq( machine, SATURN_IRQ_LINE ); | |
111 | hp48_pulse_irq( machine(), SATURN_IRQ_LINE ); | |
113 | 112 | } |
114 | 113 | } |
115 | 114 | |
r18113 | r18114 | |
129 | 128 | } |
130 | 129 | |
131 | 130 | /* schedule end of reception */ |
132 | machine.scheduler().timer_set( RS232_DELAY, FUNC(hp48_rs232_byte_recv_cb), data); | |
131 | machine.scheduler().timer_set( RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::hp48_rs232_byte_recv_cb),state), data); | |
133 | 132 | } |
134 | 133 | |
135 | 134 | |
136 | 135 | /* end of send event */ |
137 | ||
136 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_sent_cb) | |
138 | 137 | { |
139 | hp48_state *state = machine.driver_data<hp48_state>(); | |
140 | //device_image_interface *xmodem = dynamic_cast<device_image_interface *>(machine.device("rs232_x")); | |
141 | //device_image_interface *kermit = dynamic_cast<device_image_interface *>(machine.device("rs232_k")); | |
138 | //device_image_interface *xmodem = dynamic_cast<device_image_interface *>(machine().device("rs232_x")); | |
139 | //device_image_interface *kermit = dynamic_cast<device_image_interface *>(machine().device("rs232_k")); | |
142 | 140 | |
143 | 141 | LOG_SERIAL(( "%f hp48_rs232_byte_sent_cb: end of send, data=%02x\n", |
144 | machine.time().as_double(), param )); | |
142 | machine().time().as_double(), param )); | |
145 | 143 | |
146 | | |
144 | m_io[0x12] &= ~3; /* clear byte sending and buffer full */ | |
147 | 145 | |
148 | 146 | /* interrupt */ |
149 | if ( | |
147 | if ( m_io[0x10] & 4 ) | |
150 | 148 | { |
151 | hp48_pulse_irq( machine, SATURN_IRQ_LINE ); | |
149 | hp48_pulse_irq( machine(), SATURN_IRQ_LINE ); | |
152 | 150 | } |
153 | 151 | |
154 | 152 | /* protocol action */ |
155 | 153 | //if ( xmodem && xmodem->exists() ) xmodem_receive_byte( &xmodem->device(), param ); |
156 | 154 | //else if ( kermit && kermit->exists() ) kermit_receive_byte( &kermit->device(), param ); |
157 | 155 | //#ifdef CHARDEV |
158 | // else chardev_out( | |
156 | // else chardev_out( m_chardev, param ); | |
159 | 157 | //#endif |
160 | 158 | } |
161 | 159 | |
r18113 | r18114 | |
172 | 170 | state->m_io[0x12] |= 3; |
173 | 171 | |
174 | 172 | /* schedule transmission */ |
175 | machine.scheduler().timer_set( RS232_DELAY, FUNC(hp48_rs232_byte_sent_cb), data); | |
173 | machine.scheduler().timer_set( RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::hp48_rs232_byte_sent_cb),state), data); | |
176 | 174 | } |
177 | 175 | |
178 | 176 | |
179 | 177 | #ifdef CHARDEV |
180 | 178 | |
181 | ||
179 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_chardev_byte_recv_cb) | |
182 | 180 | { |
183 | hp48_state *state = machine.driver_data<hp48_state>(); | |
184 | UINT8 data = chardev_in( state->m_chardev ); | |
181 | UINT8 data = chardev_in( m_chardev ); | |
185 | 182 | |
186 | 183 | LOG_SERIAL(( "%f hp48_chardev_byte_recv_cb: end of receive, data=%02x\n", |
187 | machine.time().as_double(), data )); | |
184 | machine().time().as_double(), data )); | |
188 | 185 | |
189 | state->m_io[0x14] = data & 0xf; /* receive zone */ | |
190 | state->m_io[0x15] = data >> 4; | |
191 | state->m_io[0x11] &= ~2; /* clear byte receiving */ | |
192 | state->m_io[0x11] |= 1; /* set byte received */ | |
186 | m_io[0x14] = data & 0xf; /* receive zone */ | |
187 | m_io[0x15] = data >> 4; | |
188 | m_io[0x11] &= ~2; /* clear byte receiving */ | |
189 | m_io[0x11] |= 1; /* set byte received */ | |
193 | 190 | |
194 | 191 | /* interrupt */ |
195 | if ( | |
192 | if ( m_io[0x10] & 2 ) | |
196 | 193 | { |
197 | hp48_pulse_irq( machine, SATURN_IRQ_LINE ); | |
194 | hp48_pulse_irq( machine(), SATURN_IRQ_LINE ); | |
198 | 195 | } |
199 | 196 | } |
200 | 197 | |
r18113 | r18114 | |
215 | 212 | } |
216 | 213 | |
217 | 214 | /* schedule end of reception */ |
218 | machine.scheduler().timer_set( RS232_DELAY, FUNC(hp48_chardev_byte_recv_cb)); | |
215 | machine.scheduler().timer_set( RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::hp48_chardev_byte_recv_cb),this)); | |
219 | 216 | } |
220 | 217 | |
221 | 218 | static void hp48_chardev_ready_to_send( running_machine &machine ) |
r18113 | r18114 | |
305 | 302 | } |
306 | 303 | |
307 | 304 | /* periodic keyboard polling, generates an interrupt */ |
308 | ||
305 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_kbd_cb) | |
309 | 306 | { |
310 | hp48_state *state = machine.driver_data<hp48_state>(); | |
311 | 307 | /* NMI for ON key */ |
312 | if ( machine.root_device().ioport( "ON" )->read() ) | |
308 | if ( machine().root_device().ioport( "ON" )->read() ) | |
313 | 309 | { |
314 | 310 | LOG(( "%f hp48_kbd_cb: keyboard interrupt, on key\n", |
315 | machine.time().as_double() )); | |
316 | state->m_io[0x19] |= 8; /* set service request */ | |
317 | hp48_pulse_irq( machine, SATURN_WAKEUP_LINE ); | |
318 | hp48_pulse_irq( machine, SATURN_NMI_LINE ); | |
311 | machine().time().as_double() )); | |
312 | m_io[0x19] |= 8; /* set service request */ | |
313 | hp48_pulse_irq( machine(), SATURN_WAKEUP_LINE ); | |
314 | hp48_pulse_irq( machine(), SATURN_NMI_LINE ); | |
319 | 315 | return; |
320 | 316 | } |
321 | 317 | |
322 | 318 | /* regular keys */ |
323 | hp48_update_kdn( machine ); | |
319 | hp48_update_kdn( machine() ); | |
324 | 320 | } |
325 | 321 | |
326 | 322 | /* RSI opcode */ |
r18113 | r18114 | |
611 | 607 | |
612 | 608 | /* ---------------- timers --------------- */ |
613 | 609 | |
614 | ||
610 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer1_cb) | |
615 | 611 | { |
616 | hp48_state *state = machine.driver_data<hp48_state>(); | |
617 | if ( !(state->m_io[0x2f] & 1) ) return; /* timer enable */ | |
612 | if ( !(m_io[0x2f] & 1) ) return; /* timer enable */ | |
618 | 613 | |
619 | | |
614 | m_timer1 = (m_timer1 - 1) & 0xf; | |
620 | 615 | |
621 | 616 | /* wake-up on carry */ |
622 | if ( ( | |
617 | if ( (m_io[0x2e] & 4) && (m_timer1 == 0xf) ) | |
623 | 618 | { |
624 | 619 | LOG(( "wake-up on timer1\n" )); |
625 | state->m_io[0x2e] |= 8; /* set service request */ | |
626 | state->m_io[0x18] |= 4; /* set service request */ | |
627 | hp48_pulse_irq( machine, SATURN_WAKEUP_LINE ); | |
620 | m_io[0x2e] |= 8; /* set service request */ | |
621 | m_io[0x18] |= 4; /* set service request */ | |
622 | hp48_pulse_irq( machine(), SATURN_WAKEUP_LINE ); | |
628 | 623 | } |
629 | 624 | /* interrupt on carry */ |
630 | if ( ( | |
625 | if ( (m_io[0x2e] & 2) && (m_timer1 == 0xf) ) | |
631 | 626 | { |
632 | 627 | LOG(( "generate timer1 interrupt\n" )); |
633 | state->m_io[0x2e] |= 8; /* set service request */ | |
634 | state->m_io[0x18] |= 4; /* set service request */ | |
635 | hp48_pulse_irq( machine, SATURN_NMI_LINE ); | |
628 | m_io[0x2e] |= 8; /* set service request */ | |
629 | m_io[0x18] |= 4; /* set service request */ | |
630 | hp48_pulse_irq( machine(), SATURN_NMI_LINE ); | |
636 | 631 | } |
637 | 632 | } |
638 | 633 | |
639 | ||
634 | TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer2_cb) | |
640 | 635 | { |
641 | hp48_state *state = machine.driver_data<hp48_state>(); | |
642 | if ( !(state->m_io[0x2f] & 1) ) return; /* timer enable */ | |
636 | if ( !(m_io[0x2f] & 1) ) return; /* timer enable */ | |
643 | 637 | |
644 | | |
638 | m_timer2 = (m_timer2 - 1) & 0xffffffff; | |
645 | 639 | |
646 | 640 | /* wake-up on carry */ |
647 | if ( ( | |
641 | if ( (m_io[0x2f] & 4) && (m_timer2 == 0xffffffff) ) | |
648 | 642 | { |
649 | 643 | LOG(( "wake-up on timer2\n" )); |
650 | state->m_io[0x2f] |= 8; /* set service request */ | |
651 | state->m_io[0x18] |= 4; /* set service request */ | |
652 | hp48_pulse_irq( machine, SATURN_WAKEUP_LINE ); | |
644 | m_io[0x2f] |= 8; /* set service request */ | |
645 | m_io[0x18] |= 4; /* set service request */ | |
646 | hp48_pulse_irq( machine(), SATURN_WAKEUP_LINE ); | |
653 | 647 | } |
654 | 648 | /* interrupt on carry */ |
655 | if ( ( | |
649 | if ( (m_io[0x2f] & 2) && (m_timer2 == 0xffffffff) ) | |
656 | 650 | { |
657 | 651 | LOG(( "generate timer2 interrupt\n" )); |
658 | state->m_io[0x2f] |= 8; /* set service request */ | |
659 | state->m_io[0x18] |= 4; /* set service request */ | |
660 | hp48_pulse_irq( machine, SATURN_NMI_LINE ); | |
652 | m_io[0x2f] |= 8; /* set service request */ | |
653 | m_io[0x18] |= 4; /* set service request */ | |
654 | hp48_pulse_irq( machine(), SATURN_NMI_LINE ); | |
661 | 655 | } |
662 | 656 | } |
663 | 657 | |
r18113 | r18114 | |
1171 | 1165 | m_modules[5].data = rom; |
1172 | 1166 | |
1173 | 1167 | /* timers */ |
1174 | machine().scheduler().timer_pulse(attotime::from_hz( 16 ), FUNC(hp48_timer1_cb)); | |
1175 | machine().scheduler().timer_pulse(attotime::from_hz( 8192 ), FUNC(hp48_timer2_cb)); | |
1168 | machine().scheduler().timer_pulse(attotime::from_hz( 16 ), timer_expired_delegate(FUNC(hp48_state::hp48_timer1_cb),this)); | |
1169 | machine().scheduler().timer_pulse(attotime::from_hz( 8192 ), timer_expired_delegate(FUNC(hp48_state::hp48_timer2_cb),this)); | |
1176 | 1170 | |
1177 | 1171 | /* 1ms keyboard polling */ |
1178 | machine().scheduler().timer_pulse(attotime::from_msec( 1 ), FUNC(hp48_kbd_cb)); | |
1172 | machine().scheduler().timer_pulse(attotime::from_msec( 1 ), timer_expired_delegate(FUNC(hp48_state::hp48_kbd_cb),this)); | |
1179 | 1173 | |
1180 | 1174 | /* save state */ |
1181 | 1175 | save_item(NAME(m_out) ); |
r18113 | r18114 | |
---|---|---|
227 | 227 | |
228 | 228 | /* Some games set the 8255 to mode 1 and expect a strobe signal */ |
229 | 229 | /* on PC2. Apparently PC2 is always low on the CPC. ?!? */ |
230 | ||
230 | TIMER_CALLBACK_MEMBER(amstrad_state::amstrad_pc2_low) | |
231 | 231 | { |
232 | amstrad_state *state = machine.driver_data<amstrad_state>(); | |
233 | state->m_ppi->pc2_w(0); | |
232 | m_ppi->pc2_w(0); | |
234 | 233 | } |
235 | 234 | |
236 | 235 | |
r18113 | r18114 | |
578 | 577 | amstrad_plus_dma_parse( machine, 2 ); |
579 | 578 | } |
580 | 579 | |
581 | ||
580 | TIMER_CALLBACK_MEMBER(amstrad_state::amstrad_video_update_timer) | |
582 | 581 | { |
583 | 582 | if(param == 1) |
584 | amstrad_plus_update_video(machine); | |
583 | amstrad_plus_update_video(machine()); | |
585 | 584 | else |
586 | amstrad_update_video(machine); | |
585 | amstrad_update_video(machine()); | |
587 | 586 | } |
588 | 587 | |
589 | 588 | /* Set the new colour from the GateArray */ |
r18113 | r18114 | |
594 | 593 | { |
595 | 594 | int val; |
596 | 595 | |
597 | machine.scheduler().timer_set( attotime::from_usec(0), FUNC(amstrad_video_update_timer),1); | |
596 | machine.scheduler().timer_set( attotime::from_usec(0), timer_expired_delegate(FUNC(amstrad_state::amstrad_video_update_timer),state),1); | |
598 | 597 | |
599 | 598 | /* CPC+/GX4000 - normal palette changes through the Gate Array also makes the corresponding change in the ASIC palette */ |
600 | 599 | val = (amstrad_palette[hw_colour_index] & 0xf00000) >> 16; /* red */ |
r18113 | r18114 | |
605 | 604 | } |
606 | 605 | else |
607 | 606 | { |
608 | machine.scheduler().timer_set( attotime::from_usec(0), FUNC(amstrad_video_update_timer),0); | |
607 | machine.scheduler().timer_set( attotime::from_usec(0), timer_expired_delegate(FUNC(amstrad_state::amstrad_video_update_timer),state),0); | |
609 | 608 | } |
610 | 609 | state->m_GateArray_render_colours[PenIndex] = hw_colour_index; |
611 | 610 | } |
r18113 | r18114 | |
614 | 613 | static void aleste_vh_update_colour(running_machine &machine, int PenIndex, UINT16 hw_colour_index) |
615 | 614 | { |
616 | 615 | amstrad_state *state = machine.driver_data<amstrad_state>(); |
617 | machine.scheduler().timer_set( attotime::from_usec(0), FUNC(amstrad_video_update_timer),0); | |
616 | machine.scheduler().timer_set( attotime::from_usec(0), timer_expired_delegate(FUNC(amstrad_state::amstrad_video_update_timer),state),0); | |
618 | 617 | state->m_GateArray_render_colours[PenIndex] = hw_colour_index+32; |
619 | 618 | } |
620 | 619 | |
r18113 | r18114 | |
969 | 968 | drvstate->m_gate_array.vsync = state ? 1 : 0; |
970 | 969 | |
971 | 970 | /* Schedule a write to PC2 */ |
972 | device->machine().scheduler().timer_set( attotime::zero, FUNC(amstrad_pc2_low)); | |
971 | device->machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::amstrad_pc2_low),drvstate)); | |
973 | 972 | } |
974 | 973 | |
975 | 974 | |
r18113 | r18114 | |
992 | 991 | drvstate->m_gate_array.vsync = state ? 1 : 0; |
993 | 992 | |
994 | 993 | /* Schedule a write to PC2 */ |
995 | device->machine().scheduler().timer_set( attotime::zero, FUNC(amstrad_pc2_low)); | |
994 | device->machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::amstrad_pc2_low),drvstate)); | |
996 | 995 | } |
997 | 996 | |
998 | 997 | |
r18113 | r18114 | |
2041 | 2040 | break; |
2042 | 2041 | case 0x01: /* Write to selected internal 6845 register Write Only */ |
2043 | 2042 | if ( m_system_type == SYSTEM_PLUS || m_system_type == SYSTEM_GX4000 ) |
2044 | machine().scheduler().timer_set( attotime::from_usec(0), FUNC(amstrad_video_update_timer),1); | |
2043 | machine().scheduler().timer_set( attotime::from_usec(0), timer_expired_delegate(FUNC(amstrad_state::amstrad_video_update_timer),this),1); | |
2045 | 2044 | else |
2046 | machine().scheduler().timer_set( attotime::from_usec(0), FUNC(amstrad_video_update_timer),0); | |
2045 | machine().scheduler().timer_set( attotime::from_usec(0), timer_expired_delegate(FUNC(amstrad_state::amstrad_video_update_timer),this),0); | |
2047 | 2046 | mc6845->register_w( space, 0, data ); |
2048 | 2047 | |
2049 | 2048 | /* printer port bit 8 */ |
r18113 | r18114 | |
2582 | 2581 | |
2583 | 2582 | logerror("amstrad_ppi_portb_r\n"); |
2584 | 2583 | /* Schedule a write to PC2 */ |
2585 | space.machine().scheduler().timer_set( attotime::zero, FUNC(amstrad_pc2_low)); | |
2584 | space.machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::amstrad_pc2_low),state)); | |
2586 | 2585 | |
2587 | 2586 | return data; |
2588 | 2587 | } |
r18113 | r18114 | |
2912 | 2911 | state->m_maincpu->set_irq_acknowledge_callback(amstrad_cpu_acknowledge_int); |
2913 | 2912 | } |
2914 | 2913 | |
2915 | ||
2914 | TIMER_CALLBACK_MEMBER(amstrad_state::cb_set_resolution) | |
2916 | 2915 | { |
2917 | amstrad_state *state = machine.driver_data<amstrad_state>(); | |
2918 | // screen_device *screen = downcast<screen_device *>(state->m_screen); | |
2916 | // screen_device *screen = downcast<screen_device *>(m_screen); | |
2919 | 2917 | rectangle visarea; |
2920 | 2918 | attoseconds_t refresh; |
2921 | 2919 | int height; |
2922 | 2920 | |
2923 | if ( machine.root_device().ioport( "solder_links" )->read() & 0x10 ) | |
2921 | if ( machine().root_device().ioport( "solder_links" )->read() & 0x10 ) | |
2924 | 2922 | { |
2925 | 2923 | /* PAL */ |
2926 | 2924 | visarea.set(0, 64 + 640 + 64 - 1, 34, 34 + 15 + 242 + 15 - 1); |
r18113 | r18114 | |
2933 | 2931 | height = 262; |
2934 | 2932 | } |
2935 | 2933 | refresh = HZ_TO_ATTOSECONDS( XTAL_16MHz ) * 1024 * height; |
2936 | | |
2934 | m_screen->configure( 1024, height, visarea, refresh ); | |
2937 | 2935 | } |
2938 | 2936 | |
2939 | 2937 | |
r18113 | r18114 | |
2963 | 2961 | m_gate_array.hsync = 0; |
2964 | 2962 | m_gate_array.vsync = 0; |
2965 | 2963 | |
2966 | machine().scheduler().timer_set( attotime::zero, FUNC(cb_set_resolution)); | |
2964 | machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::cb_set_resolution),this)); | |
2967 | 2965 | } |
2968 | 2966 | |
2969 | 2967 | |
r18113 | r18114 | |
3015 | 3013 | space.install_write_handler(0x6000, 0x7fff, write8_delegate(FUNC(amstrad_state::amstrad_plus_asic_6000_w),this)); |
3016 | 3014 | |
3017 | 3015 | // multiface_init(); |
3018 | machine().scheduler().timer_set( attotime::zero, FUNC(cb_set_resolution)); | |
3016 | machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::cb_set_resolution),this)); | |
3019 | 3017 | } |
3020 | 3018 | |
3021 | 3019 | MACHINE_START_MEMBER(amstrad_state,gx4000) |
r18113 | r18114 | |
3064 | 3062 | space.install_write_handler(0x4000, 0x5fff, write8_delegate(FUNC(amstrad_state::amstrad_plus_asic_4000_w),this)); |
3065 | 3063 | space.install_write_handler(0x6000, 0x7fff, write8_delegate(FUNC(amstrad_state::amstrad_plus_asic_6000_w),this)); |
3066 | 3064 | |
3067 | machine().scheduler().timer_set( attotime::zero, FUNC(cb_set_resolution)); | |
3065 | machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::cb_set_resolution),this)); | |
3068 | 3066 | } |
3069 | 3067 | |
3070 | 3068 | MACHINE_START_MEMBER(amstrad_state,kccomp) |
r18113 | r18114 | |
3116 | 3114 | amstrad_common_init(machine()); |
3117 | 3115 | amstrad_reset_machine(machine()); |
3118 | 3116 | |
3119 | machine().scheduler().timer_set( attotime::zero, FUNC(cb_set_resolution)); | |
3117 | machine().scheduler().timer_set( attotime::zero, timer_expired_delegate(FUNC(amstrad_state::cb_set_resolution),this)); | |
3120 | 3118 | } |
3121 | 3119 | |
3122 | 3120 |
r18113 | r18114 | |
---|---|---|
24 | 24 | static const char *const wswan_sram_str[] = { "none", "64Kbit SRAM", "256Kbit SRAM", "512Kbit SRAM", "1Mbit SRAM", "2Mbit SRAM", "1Kbit EEPROM", "16Kbit EEPROM", "8Kbit EEPROM", "Unknown" }; |
25 | 25 | static const int wswan_sram_size[] = { 0, 64*1024/8, 256*1024/8, 512*1024/8, 1024*1024/8, 2*1024*1024/8, 1024/8, 16*1024/8, 8*1024/8, 0 }; |
26 | 26 | |
27 | static TIMER_CALLBACK(wswan_scanline_interrupt); | |
28 | 27 | |
29 | 28 | |
29 | ||
30 | 30 | static const UINT8 ws_portram_init[256] = |
31 | 31 | { |
32 | 32 | 0x00, 0x00, 0x00/*?*/, 0xbb, 0x00, 0x00, 0x00, 0x26, 0xfe, 0xde, 0xf9, 0xfb, 0xdb, 0xd7, 0x7f, 0xf5, |
r18113 | r18114 | |
123 | 123 | wswan_handle_irqs( machine() ); |
124 | 124 | } |
125 | 125 | |
126 | ||
126 | TIMER_CALLBACK_MEMBER(wswan_state::wswan_rtc_callback) | |
127 | 127 | { |
128 | wswan_state *state = machine.driver_data<wswan_state>(); | |
129 | 128 | /* A second passed */ |
130 | state->m_rtc.second = state->m_rtc.second + 1; | |
131 | if ( ( state->m_rtc.second & 0x0F ) > 9 ) | |
129 | m_rtc.second = m_rtc.second + 1; | |
130 | if ( ( m_rtc.second & 0x0F ) > 9 ) | |
132 | 131 | { |
133 | | |
132 | m_rtc.second = ( m_rtc.second & 0xF0 ) + 0x10; | |
134 | 133 | } |
135 | 134 | |
136 | 135 | /* Check for minute passed */ |
137 | if ( | |
136 | if ( m_rtc.second >= 0x60 ) | |
138 | 137 | { |
139 | state->m_rtc.second = 0; | |
140 | state->m_rtc.minute = state->m_rtc.minute + 1; | |
141 | if ( ( state->m_rtc.minute & 0x0F ) > 9 ) | |
138 | m_rtc.second = 0; | |
139 | m_rtc.minute = m_rtc.minute + 1; | |
140 | if ( ( m_rtc.minute & 0x0F ) > 9 ) | |
142 | 141 | { |
143 | | |
142 | m_rtc.minute = ( m_rtc.minute & 0xF0 ) + 0x10; | |
144 | 143 | } |
145 | 144 | } |
146 | 145 | |
147 | 146 | /* Check for hour passed */ |
148 | if ( | |
147 | if ( m_rtc.minute >= 0x60 ) | |
149 | 148 | { |
150 | state->m_rtc.minute = 0; | |
151 | state->m_rtc.hour = state->m_rtc.hour + 1; | |
152 | if ( ( state->m_rtc.hour & 0x0F ) > 9 ) | |
149 | m_rtc.minute = 0; | |
150 | m_rtc.hour = m_rtc.hour + 1; | |
151 | if ( ( m_rtc.hour & 0x0F ) > 9 ) | |
153 | 152 | { |
154 | | |
153 | m_rtc.hour = ( m_rtc.hour & 0xF0 ) + 0x10; | |
155 | 154 | } |
156 | if ( | |
155 | if ( m_rtc.hour == 0x12 ) | |
157 | 156 | { |
158 | | |
157 | m_rtc.hour |= 0x80; | |
159 | 158 | } |
160 | 159 | } |
161 | 160 | |
162 | 161 | /* Check for day passed */ |
163 | if ( | |
162 | if ( m_rtc.hour >= 0x24 ) | |
164 | 163 | { |
165 | state->m_rtc.hour = 0; | |
166 | state->m_rtc.day = state->m_rtc.day + 1; | |
164 | m_rtc.hour = 0; | |
165 | m_rtc.day = m_rtc.day + 1; | |
167 | 166 | } |
168 | 167 | } |
169 | 168 | |
r18113 | r18114 | |
192 | 191 | m_ws_bios_bank = NULL; |
193 | 192 | m_system_type = TYPE_WSWAN; |
194 | 193 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_machine_stop),&machine())); |
195 | m_vdp.timer = machine().scheduler().timer_alloc(FUNC(wswan_scanline_interrupt), &m_vdp ); | |
194 | m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); | |
196 | 195 | m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); |
197 | 196 | |
198 | 197 | wswan_setup_bios(machine()); |
199 | 198 | |
200 | 199 | /* Set up RTC timer */ |
201 | 200 | if ( m_rtc.present ) |
202 | machine().scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback)); | |
201 | machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); | |
203 | 202 | |
204 | 203 | machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); |
205 | 204 | } |
r18113 | r18114 | |
209 | 208 | m_ws_bios_bank = NULL; |
210 | 209 | m_system_type = TYPE_WSC; |
211 | 210 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_machine_stop),&machine())); |
212 | m_vdp.timer = machine().scheduler().timer_alloc(FUNC(wswan_scanline_interrupt), &m_vdp ); | |
211 | m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); | |
213 | 212 | m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); |
214 | 213 | |
215 | 214 | wswan_setup_bios(machine()); |
216 | 215 | |
217 | 216 | /* Set up RTC timer */ |
218 | 217 | if ( m_rtc.present ) |
219 | machine().scheduler().timer_pulse(attotime::from_seconds(1), FUNC(wswan_rtc_callback)); | |
218 | machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); | |
220 | 219 | |
221 | 220 | machine().device<nvram_device>("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); |
222 | 221 | } |
r18113 | r18114 | |
1428 | 1427 | return IMAGE_INIT_PASS; |
1429 | 1428 | } |
1430 | 1429 | |
1431 | ||
1430 | TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt) | |
1432 | 1431 | { |
1433 | wswan_state *state = machine.driver_data<wswan_state>(); | |
1434 | if( state->m_vdp.current_line < 144 ) | |
1432 | if( m_vdp.current_line < 144 ) | |
1435 | 1433 | { |
1436 | wswan_refresh_scanline(machine); | |
1434 | wswan_refresh_scanline(machine()); | |
1437 | 1435 | } |
1438 | 1436 | |
1439 | 1437 | /* Decrement 12kHz (HBlank) counter */ |
1440 | if ( | |
1438 | if ( m_vdp.timer_hblank_enable && m_vdp.timer_hblank_reload != 0 ) | |
1441 | 1439 | { |
1442 | state->m_vdp.timer_hblank_count--; | |
1443 | logerror( "timer_hblank_count: %X\n", state->m_vdp.timer_hblank_count ); | |
1444 | if ( state->m_vdp.timer_hblank_count == 0 ) | |
1440 | m_vdp.timer_hblank_count--; | |
1441 | logerror( "timer_hblank_count: %X\n", m_vdp.timer_hblank_count ); | |
1442 | if ( m_vdp.timer_hblank_count == 0 ) | |
1445 | 1443 | { |
1446 | if ( | |
1444 | if ( m_vdp.timer_hblank_mode ) | |
1447 | 1445 | { |
1448 | | |
1446 | m_vdp.timer_hblank_count = m_vdp.timer_hblank_reload; | |
1449 | 1447 | } |
1450 | 1448 | else |
1451 | 1449 | { |
1452 | | |
1450 | m_vdp.timer_hblank_reload = 0; | |
1453 | 1451 | } |
1454 | 1452 | logerror( "trigerring hbltmr interrupt\n" ); |
1455 | wswan_set_irq_line( machine, WSWAN_IFLAG_HBLTMR ); | |
1453 | wswan_set_irq_line( machine(), WSWAN_IFLAG_HBLTMR ); | |
1456 | 1454 | } |
1457 | 1455 | } |
1458 | 1456 | |
1459 | 1457 | /* Handle Sound DMA */ |
1460 | if ( ( | |
1458 | if ( ( m_sound_dma.enable & 0x88 ) == 0x80 ) | |
1461 | 1459 | { |
1462 | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM ); | |
1460 | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM ); | |
1463 | 1461 | /* TODO: Output sound DMA byte */ |
1464 | state->wswan_port_w( space, 0x89, space.read_byte(state->m_sound_dma.source ) ); | |
1465 | state->m_sound_dma.size--; | |
1466 | state->m_sound_dma.source = ( state->m_sound_dma.source + 1 ) & 0x0FFFFF; | |
1467 | if ( state->m_sound_dma.size == 0 ) | |
1462 | wswan_port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); | |
1463 | m_sound_dma.size--; | |
1464 | m_sound_dma.source = ( m_sound_dma.source + 1 ) & 0x0FFFFF; | |
1465 | if ( m_sound_dma.size == 0 ) | |
1468 | 1466 | { |
1469 | | |
1467 | m_sound_dma.enable &= 0x7F; | |
1470 | 1468 | } |
1471 | 1469 | } |
1472 | 1470 | |
1473 | // | |
1471 | // m_vdp.current_line = (m_vdp.current_line + 1) % 159; | |
1474 | 1472 | |
1475 | if( | |
1473 | if( m_vdp.current_line == 144 ) // buffer sprite table | |
1476 | 1474 | { |
1477 | memcpy(state->m_vdp.sprite_table_buffer, &state->m_vdp.vram[state->m_vdp.sprite_table_address], 512); | |
1478 | state->m_vdp.sprite_count = state->m_ws_portram[0x06]; | |
1479 | state->m_vdp.sprite_first = state->m_ws_portram[0x05]; // always zero? | |
1475 | memcpy(m_vdp.sprite_table_buffer, &m_vdp.vram[m_vdp.sprite_table_address], 512); | |
1476 | m_vdp.sprite_count = m_ws_portram[0x06]; | |
1477 | m_vdp.sprite_first = m_ws_portram[0x05]; // always zero? | |
1480 | 1478 | } |
1481 | 1479 | |
1482 | if( | |
1480 | if( m_vdp.current_line == 144 ) | |
1483 | 1481 | { |
1484 | wswan_set_irq_line( machine, WSWAN_IFLAG_VBL ); | |
1482 | wswan_set_irq_line( machine(), WSWAN_IFLAG_VBL ); | |
1485 | 1483 | /* Decrement 75Hz (VBlank) counter */ |
1486 | if ( | |
1484 | if ( m_vdp.timer_vblank_enable && m_vdp.timer_vblank_reload != 0 ) | |
1487 | 1485 | { |
1488 | state->m_vdp.timer_vblank_count--; | |
1489 | logerror( "timer_vblank_count: %X\n", state->m_vdp.timer_vblank_count ); | |
1490 | if ( state->m_vdp.timer_vblank_count == 0 ) | |
1486 | m_vdp.timer_vblank_count--; | |
1487 | logerror( "timer_vblank_count: %X\n", m_vdp.timer_vblank_count ); | |
1488 | if ( m_vdp.timer_vblank_count == 0 ) | |
1491 | 1489 | { |
1492 | if ( | |
1490 | if ( m_vdp.timer_vblank_mode ) | |
1493 | 1491 | { |
1494 | | |
1492 | m_vdp.timer_vblank_count = m_vdp.timer_vblank_reload; | |
1495 | 1493 | } |
1496 | 1494 | else |
1497 | 1495 | { |
1498 | | |
1496 | m_vdp.timer_vblank_reload = 0; | |
1499 | 1497 | } |
1500 | 1498 | logerror( "triggering vbltmr interrupt\n" ); |
1501 | wswan_set_irq_line( machine, WSWAN_IFLAG_VBLTMR ); | |
1499 | wswan_set_irq_line( machine(), WSWAN_IFLAG_VBLTMR ); | |
1502 | 1500 | } |
1503 | 1501 | } |
1504 | 1502 | } |
1505 | 1503 | |
1506 | // | |
1504 | // m_vdp.current_line = (m_vdp.current_line + 1) % 159; | |
1507 | 1505 | |
1508 | if ( | |
1506 | if ( m_vdp.current_line == m_vdp.line_compare ) | |
1509 | 1507 | { |
1510 | wswan_set_irq_line( machine, WSWAN_IFLAG_LCMP ); | |
1508 | wswan_set_irq_line( machine(), WSWAN_IFLAG_LCMP ); | |
1511 | 1509 | } |
1512 | 1510 | |
1513 | | |
1511 | m_vdp.current_line = (m_vdp.current_line + 1) % 159; | |
1514 | 1512 | } |
1515 | 1513 |
r18113 | r18114 | |
---|---|---|
39 | 39 | return machine.device<cassette_image_device>(CASSETTE_TAG); |
40 | 40 | } |
41 | 41 | |
42 | ||
42 | TIMER_CALLBACK_MEMBER(z80ne_state::z80ne_cassette_tc) | |
43 | 43 | { |
44 | z80ne_state *state = machine.driver_data<z80ne_state>(); | |
45 | 44 | UINT8 cass_ws = 0; |
46 | | |
45 | m_cass_data.input.length++; | |
47 | 46 | |
48 | cass_ws = ((cassette_device_image(machine))->input() > +0.02) ? 1 : 0; | |
47 | cass_ws = ((cassette_device_image(machine()))->input() > +0.02) ? 1 : 0; | |
49 | 48 | |
50 | if ((cass_ws ^ | |
49 | if ((cass_ws ^ m_cass_data.input.level) & cass_ws) | |
51 | 50 | { |
52 | state->m_cass_data.input.level = cass_ws; | |
53 | state->m_cass_data.input.bit = ((state->m_cass_data.input.length < state->m_cass_data.wave_filter) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0; | |
54 | state->m_cass_data.input.length = 0; | |
55 | ay31015_set_input_pin( state->m_ay31015, AY31015_SI, state->m_cass_data.input.bit ); | |
51 | m_cass_data.input.level = cass_ws; | |
52 | m_cass_data.input.bit = ((m_cass_data.input.length < m_cass_data.wave_filter) || (m_cass_data.input.length > 0x20)) ? 1 : 0; | |
53 | m_cass_data.input.length = 0; | |
54 | ay31015_set_input_pin( m_ay31015, AY31015_SI, m_cass_data.input.bit ); | |
56 | 55 | } |
57 | | |
56 | m_cass_data.input.level = cass_ws; | |
58 | 57 | |
59 | 58 | /* saving a tape - convert the serial stream from the uart */ |
60 | 59 | |
61 | | |
60 | m_cass_data.output.length--; | |
62 | 61 | |
63 | if (!( | |
62 | if (!(m_cass_data.output.length)) | |
64 | 63 | { |
65 | if (state->m_cass_data.output.level) | |
66 | state->m_cass_data.output.level = 0; | |
64 | if (m_cass_data.output.level) | |
65 | m_cass_data.output.level = 0; | |
67 | 66 | else |
68 | 67 | { |
69 | state->m_cass_data.output.level=1; | |
70 | cass_ws = ay31015_get_output_pin( state->m_ay31015, AY31015_SO ); | |
71 | state->m_cass_data.wave_length = cass_ws ? state->m_cass_data.wave_short : state->m_cass_data.wave_long; | |
68 | m_cass_data.output.level=1; | |
69 | cass_ws = ay31015_get_output_pin( m_ay31015, AY31015_SO ); | |
70 | m_cass_data.wave_length = cass_ws ? m_cass_data.wave_short : m_cass_data.wave_long; | |
72 | 71 | } |
73 | cassette_device_image(machine)->output(state->m_cass_data.output.level ? -1.0 : +1.0); | |
74 | state->m_cass_data.output.length = state->m_cass_data.wave_length; | |
72 | cassette_device_image(machine())->output(m_cass_data.output.level ? -1.0 : +1.0); | |
73 | m_cass_data.output.length = m_cass_data.wave_length; | |
75 | 74 | } |
76 | 75 | } |
77 | 76 | |
r18113 | r18114 | |
114 | 113 | |
115 | 114 | } |
116 | 115 | |
117 | ||
116 | TIMER_CALLBACK_MEMBER(z80ne_state::z80ne_kbd_scan) | |
118 | 117 | { |
119 | z80ne_state *state = machine.driver_data<z80ne_state>(); | |
120 | 118 | /* |
121 | 119 | * NE555 is connected to a 74LS93 binary counter |
122 | 120 | * 74LS93 output: |
r18113 | r18114 | |
141 | 139 | UINT8 i; |
142 | 140 | |
143 | 141 | /* 4-bit counter */ |
144 | --state->m_lx383_scan_counter; | |
145 | state->m_lx383_scan_counter &= 0x0f; | |
142 | --m_lx383_scan_counter; | |
143 | m_lx383_scan_counter &= 0x0f; | |
146 | 144 | |
147 | if ( -- | |
145 | if ( --m_lx383_downsampler == 0 ) | |
148 | 146 | { |
149 | state->m_lx383_downsampler = LX383_DOWNSAMPLING; | |
150 | key_bits = (machine.root_device().ioport("ROW1")->read() << 8) | machine.root_device().ioport("ROW0")->read(); | |
151 | // rst = machine.root_device().ioport("RST")->read(); | |
152 | ctrl = machine.root_device().ioport("CTRL")->read(); | |
147 | m_lx383_downsampler = LX383_DOWNSAMPLING; | |
148 | key_bits = (machine().root_device().ioport("ROW1")->read() << 8) | machine().root_device().ioport("ROW0")->read(); | |
149 | // rst = machine().root_device().ioport("RST")->read(); | |
150 | ctrl = machine().root_device().ioport("CTRL")->read(); | |
153 | 151 | |
154 | 152 | for ( i = 0; i<LX383_KEYS; i++) |
155 | 153 | { |
156 | | |
154 | m_lx383_key[i] = ( i | (key_bits & 0x01 ? 0x80 : 0x00) | ~ctrl); | |
157 | 155 | key_bits >>= 1; |
158 | 156 | } |
159 | 157 | } |
r18113 | r18114 | |
399 | 397 | state_save_register_item( machine(), "z80ne", NULL, 0, m_lx383_downsampler ); |
400 | 398 | state_save_register_item_array( machine(), "z80ne", NULL, 0, m_lx383_key ); |
401 | 399 | state_save_register_item( machine(), "z80ne", NULL, 0, m_nmi_delay_counter ); |
402 | m_cassette_timer = machine().scheduler().timer_alloc(FUNC(z80ne_cassette_tc)); | |
403 | machine().scheduler().timer_pulse( attotime::from_hz(1000), FUNC(z80ne_kbd_scan)); | |
400 | m_cassette_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z80ne_state::z80ne_cassette_tc),this)); | |
401 | machine().scheduler().timer_pulse( attotime::from_hz(1000), timer_expired_delegate(FUNC(z80ne_state::z80ne_kbd_scan),this)); | |
404 | 402 | } |
405 | 403 | |
406 | 404 | MACHINE_START_MEMBER(z80ne_state,z80net) |
r18113 | r18114 | |
---|---|---|
100 | 100 | machine.device<nvram_device>("ram_nvram")->set_base(ram, 0x4800); |
101 | 101 | } |
102 | 102 | |
103 | ||
103 | TIMER_CALLBACK_MEMBER(pc1251_state::pc1251_power_up) | |
104 | 104 | { |
105 | pc1251_state *state = machine.driver_data<pc1251_state>(); | |
106 | state->m_power = 0; | |
105 | m_power = 0; | |
107 | 106 | } |
108 | 107 | |
109 | 108 | DRIVER_INIT_MEMBER(pc1251_state,pc1251) |
r18113 | r18114 | |
113 | 112 | for (i=0; i<128; i++) gfx[i]=i; |
114 | 113 | |
115 | 114 | m_power = 1; |
116 | machine().scheduler().timer_set(attotime::from_seconds(1), FUNC(pc1251_power_up)); | |
115 | machine().scheduler().timer_set(attotime::from_seconds(1), timer_expired_delegate(FUNC(pc1251_state::pc1251_power_up),this)); | |
117 | 116 | } |
118 | 117 |
r18113 | r18114 | |
---|---|---|
90 | 90 | return (device->machine().root_device().ioport("EXTRA")->read() & 0x01); |
91 | 91 | } |
92 | 92 | |
93 | ||
93 | TIMER_CALLBACK_MEMBER(pc1350_state::pc1350_power_up) | |
94 | 94 | { |
95 | pc1350_state *state = machine.driver_data<pc1350_state>(); | |
96 | state->m_power=0; | |
95 | m_power=0; | |
97 | 96 | } |
98 | 97 | |
99 | 98 | MACHINE_START( pc1350 ) |
r18113 | r18114 | |
102 | 101 | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); |
103 | 102 | |
104 | 103 | state->m_power = 1; |
105 | machine.scheduler().timer_set(attotime::from_seconds(1), FUNC(pc1350_power_up)); | |
104 | machine.scheduler().timer_set(attotime::from_seconds(1), timer_expired_delegate(FUNC(pc1350_state::pc1350_power_up),state)); | |
106 | 105 | |
107 | 106 | space.install_readwrite_bank(0x6000, 0x6fff, "bank1"); |
108 | 107 | state->membank("bank1")->set_base(&machine.device<ram_device>(RAM_TAG)->pointer()[0x0000]); |
r18113 | r18114 | |
---|---|---|
254 | 254 | |
255 | 255 | /* not called yet - this will update the via with the state of the tape data. |
256 | 256 | This allows the via to trigger on bit changes and issue interrupts */ |
257 | ||
257 | TIMER_CALLBACK_MEMBER(oric_state::oric_refresh_tape) | |
258 | 258 | { |
259 | 259 | int data; |
260 | 260 | int input_port_9; |
261 | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); | |
261 | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); | |
262 | 262 | |
263 | 263 | data = 0; |
264 | 264 | |
265 | if ((cassette_device_image(machine))->input() > 0.0038) | |
265 | if ((cassette_device_image(machine()))->input() > 0.0038) | |
266 | 266 | data |= 1; |
267 | 267 | |
268 | 268 | /* "A simple cable to catch the vertical retrace signal ! |
r18113 | r18114 | |
270 | 270 | to the via cb1 input. Interrupts can be generated from the vertical |
271 | 271 | sync, and flicker free games can be produced */ |
272 | 272 | |
273 | input_port_9 = machine.root_device().ioport("FLOPPY")->read(); | |
273 | input_port_9 = machine().root_device().ioport("FLOPPY")->read(); | |
274 | 274 | /* cable is enabled? */ |
275 | 275 | if ((input_port_9 & 0x08)!=0) |
276 | 276 | { |
r18113 | r18114 | |
1048 | 1048 | state->m_port_314_r = 0; |
1049 | 1049 | state->m_port_318_r = 0; |
1050 | 1050 | state->m_port_314_w = 0; |
1051 | machine.scheduler().timer_pulse(attotime::from_hz(4800), FUNC(oric_refresh_tape)); | |
1051 | machine.scheduler().timer_pulse(attotime::from_hz(4800), timer_expired_delegate(FUNC(oric_state::oric_refresh_tape),state)); | |
1052 | 1052 | } |
1053 | 1053 | |
1054 | 1054 | void oric_state::machine_start() |
r18113 | r18114 | |
---|---|---|
75 | 75 | { |
76 | 76 | } |
77 | 77 | |
78 | ||
78 | TIMER_CALLBACK_MEMBER(ondra_state::nmi_check_callback) | |
79 | 79 | { |
80 | if ((machine.root_device().ioport("NMI")->read() & 1) == 1) | |
80 | if ((machine().root_device().ioport("NMI")->read() & 1) == 1) | |
81 | 81 | { |
82 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
82 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
83 | 83 | } |
84 | 84 | } |
85 | 85 | |
r18113 | r18114 | |
92 | 92 | |
93 | 93 | void ondra_state::machine_start() |
94 | 94 | { |
95 | machine().scheduler().timer_pulse(attotime::from_hz(10), FUNC(nmi_check_callback)); | |
95 | machine().scheduler().timer_pulse(attotime::from_hz(10), timer_expired_delegate(FUNC(ondra_state::nmi_check_callback),this)); | |
96 | 96 | } |
r18113 | r18114 | |
---|---|---|
968 | 968 | } |
969 | 969 | |
970 | 970 | |
971 | static TIMER_CALLBACK( bebox_get_devices ) { | |
972 | bebox_state *state = machine.driver_data<bebox_state>(); | |
973 | state->m_devices.pic8259_master = machine.device("pic8259_master"); | |
974 | state->m_devices.pic8259_slave = machine.device("pic8259_slave"); | |
975 | state->m_devices.dma8237_1 = machine.device("dma8237_1"); | |
976 | state->m_devices.dma8237_2 = machine.device("dma8237_2"); | |
971 | TIMER_CALLBACK_MEMBER(bebox_state::bebox_get_devices){ | |
972 | m_devices.pic8259_master = machine().device("pic8259_master"); | |
973 | m_devices.pic8259_slave = machine().device("pic8259_slave"); | |
974 | m_devices.dma8237_1 = machine().device("dma8237_1"); | |
975 | m_devices.dma8237_2 = machine().device("dma8237_2"); | |
977 | 976 | } |
978 | 977 | |
979 | 978 | |
r18113 | r18114 | |
990 | 989 | m_devices.dma8237_1 = NULL; |
991 | 990 | m_devices.dma8237_2 = NULL; |
992 | 991 | |
993 | machine().scheduler().timer_set(attotime::zero, FUNC(bebox_get_devices)); | |
992 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(bebox_state::bebox_get_devices),this)); | |
994 | 993 | |
995 | 994 | machine().device("ppc1")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
996 | 995 | machine().device("ppc2")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
r18113 | r18114 | |
---|---|---|
78 | 78 | bit 1 = MDS fast system |
79 | 79 | bit 2 = CA3140 */ |
80 | 80 | |
81 | ||
81 | TIMER_CALLBACK_MEMBER(super80_state::super80_timer) | |
82 | 82 | { |
83 | super80_state *state = machine.driver_data<super80_state>(); | |
84 | 83 | UINT8 cass_ws=0; |
85 | 84 | |
86 | state->m_cass_data[1]++; | |
87 | cass_ws = ((state->m_cass)->input() > +0.03) ? 4 : 0; | |
85 | m_cass_data[1]++; | |
86 | cass_ws = ((m_cass)->input() > +0.03) ? 4 : 0; | |
88 | 87 | |
89 | if (cass_ws != | |
88 | if (cass_ws != m_cass_data[0]) | |
90 | 89 | { |
91 | if (cass_ws) state->m_cass_data[3] ^= 2; // the MDS flipflop | |
92 | state->m_cass_data[0] = cass_ws; | |
93 | state->m_cass_data[2] = ((state->m_cass_data[1] < 0x40) ? 1 : 0) | cass_ws | state->m_cass_data[3]; | |
94 | state->m_cass_data[1] = 0; | |
90 | if (cass_ws) m_cass_data[3] ^= 2; // the MDS flipflop | |
91 | m_cass_data[0] = cass_ws; | |
92 | m_cass_data[2] = ((m_cass_data[1] < 0x40) ? 1 : 0) | cass_ws | m_cass_data[3]; | |
93 | m_cass_data[1] = 0; | |
95 | 94 | } |
96 | 95 | |
97 | | |
96 | m_pio->port_b_write(pio_port_b_r(m_pio,generic_space(),0,0xff)); | |
98 | 97 | } |
99 | 98 | |
100 | 99 | /* after the first 4 bytes have been read from ROM, switch the ram back in */ |
101 | ||
100 | TIMER_CALLBACK_MEMBER(super80_state::super80_reset) | |
102 | 101 | { |
103 | super80_state *state = machine.driver_data<super80_state>(); | |
104 | state->membank("boot")->set_entry(0); | |
102 | membank("boot")->set_entry(0); | |
105 | 103 | } |
106 | 104 | |
107 | ||
105 | TIMER_CALLBACK_MEMBER(super80_state::super80_halfspeed) | |
108 | 106 | { |
109 | 107 | UINT8 go_fast = 0; |
110 | super80_state *state = machine.driver_data<super80_state>(); | |
111 | if ( (!BIT(state->m_shared, 2)) | (!BIT(machine.root_device().ioport("CONFIG")->read(), 1)) ) /* bit 2 of port F0 is low, OR user turned on config switch */ | |
108 | if ( (!BIT(m_shared, 2)) | (!BIT(machine().root_device().ioport("CONFIG")->read(), 1)) ) /* bit 2 of port F0 is low, OR user turned on config switch */ | |
112 | 109 | go_fast++; |
113 | 110 | |
114 | 111 | /* code to slow down computer to 1 MHz by halting cpu on every second frame */ |
115 | 112 | if (!go_fast) |
116 | 113 | { |
117 | if (!state->m_int_sw) | |
118 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it | |
114 | if (!m_int_sw) | |
115 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it | |
119 | 116 | |
120 | state->m_int_sw++; | |
121 | if (state->m_int_sw > 1) | |
117 | m_int_sw++; | |
118 | if (m_int_sw > 1) | |
122 | 119 | { |
123 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it | |
124 | state->m_int_sw = 0; | |
120 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it | |
121 | m_int_sw = 0; | |
125 | 122 | } |
126 | 123 | } |
127 | 124 | else |
128 | 125 | { |
129 | if ( | |
126 | if (m_int_sw < 8) // @2MHz, reset just once | |
130 | 127 | { |
131 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
132 | state->m_int_sw = 8; // ...not every time | |
128 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
129 | m_int_sw = 8; // ...not every time | |
133 | 130 | } |
134 | 131 | } |
135 | 132 | } |
r18113 | r18114 | |
202 | 199 | void super80_state::machine_reset() |
203 | 200 | { |
204 | 201 | m_shared=0xff; |
205 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(super80_reset)); | |
202 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(super80_state::super80_reset),this)); | |
206 | 203 | membank("boot")->set_entry(1); |
207 | 204 | } |
208 | 205 | |
r18113 | r18114 | |
211 | 208 | super80_state *state = machine.driver_data<super80_state>(); |
212 | 209 | UINT8 *RAM = state->memregion("maincpu")->base(); |
213 | 210 | state->membank("boot")->configure_entries(0, 2, &RAM[0x0000], 0xc000); |
214 | machine.scheduler().timer_pulse(attotime::from_hz(200000), FUNC(super80_timer)); /* timer for keyboard and cassette */ | |
211 | machine.scheduler().timer_pulse(attotime::from_hz(200000), timer_expired_delegate(FUNC(super80_state::super80_timer),state)); /* timer for keyboard and cassette */ | |
215 | 212 | } |
216 | 213 | |
217 | 214 | DRIVER_INIT_MEMBER(super80_state,super80) |
218 | 215 | { |
219 | machine().scheduler().timer_pulse(attotime::from_hz(100), FUNC(super80_halfspeed)); /* timer for 1MHz slowdown */ | |
216 | machine().scheduler().timer_pulse(attotime::from_hz(100), timer_expired_delegate(FUNC(super80_state::super80_halfspeed),this)); /* timer for 1MHz slowdown */ | |
220 | 217 | driver_init_common(machine()); |
221 | 218 | } |
222 | 219 |
r18113 | r18114 | |
---|---|---|
18 | 18 | |
19 | 19 | |
20 | 20 | |
21 | ||
21 | TIMER_CALLBACK_MEMBER(irisha_state::irisha_key) | |
22 | 22 | { |
23 | irisha_state *state = machine.driver_data<irisha_state>(); | |
24 | state->m_keypressed = 1; | |
25 | state->m_keyboard_cnt = 0; | |
23 | m_keypressed = 1; | |
24 | m_keyboard_cnt = 0; | |
26 | 25 | } |
27 | 26 | |
28 | 27 | void irisha_state::machine_start() |
29 | 28 | { |
30 | machine().scheduler().timer_pulse(attotime::from_msec(30), FUNC(irisha_key)); | |
29 | machine().scheduler().timer_pulse(attotime::from_msec(30), timer_expired_delegate(FUNC(irisha_state::irisha_key),this)); | |
31 | 30 | } |
32 | 31 | |
33 | 32 | void irisha_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
15 | 15 | #define TI86_SNAPSHOT_SIZE 131284 |
16 | 16 | |
17 | 17 | |
18 | ||
18 | TIMER_CALLBACK_MEMBER(ti85_state::ti85_timer_callback) | |
19 | 19 | { |
20 | ti85_state *state = machine.driver_data<ti85_state>(); | |
21 | if (machine.root_device().ioport("ON")->read() & 0x01) | |
20 | if (machine().root_device().ioport("ON")->read() & 0x01) | |
22 | 21 | { |
23 | if ( | |
22 | if (m_ON_interrupt_mask && !m_ON_pressed) | |
24 | 23 | { |
25 | state->m_maincpu->set_input_line(0, HOLD_LINE); | |
26 | state->m_ON_interrupt_status = 1; | |
27 | if (!state->m_timer_interrupt_mask) state->m_timer_interrupt_mask = 1; | |
24 | m_maincpu->set_input_line(0, HOLD_LINE); | |
25 | m_ON_interrupt_status = 1; | |
26 | if (!m_timer_interrupt_mask) m_timer_interrupt_mask = 1; | |
28 | 27 | } |
29 | | |
28 | m_ON_pressed = 1; | |
30 | 29 | return; |
31 | 30 | } |
32 | 31 | else |
33 | state->m_ON_pressed = 0; | |
34 | if (state->m_timer_interrupt_mask) | |
32 | m_ON_pressed = 0; | |
33 | if (m_timer_interrupt_mask) | |
35 | 34 | { |
36 | state->m_maincpu->set_input_line(0, HOLD_LINE); | |
37 | state->m_timer_interrupt_status = 1; | |
35 | m_maincpu->set_input_line(0, HOLD_LINE); | |
36 | m_timer_interrupt_status = 1; | |
38 | 37 | } |
39 | 38 | } |
40 | 39 | |
r18113 | r18114 | |
131 | 130 | m_port4_bit0 = 0; |
132 | 131 | m_ti81_port_7_data = 0; |
133 | 132 | |
134 | machine().scheduler().timer_pulse(attotime::from_hz(200), FUNC(ti85_timer_callback)); | |
133 | machine().scheduler().timer_pulse(attotime::from_hz(200), timer_expired_delegate(FUNC(ti85_state::ti85_timer_callback),this)); | |
135 | 134 | |
136 | 135 | space.unmap_write(0x0000, 0x3fff); |
137 | 136 | space.unmap_write(0x4000, 0x7fff); |
r18113 | r18114 | |
180 | 179 | membank("bank3")->set_base(m_bios); |
181 | 180 | membank("bank4")->set_base(m_ti8x_ram); |
182 | 181 | |
183 | machine().scheduler().timer_pulse(attotime::from_hz(200), FUNC(ti85_timer_callback)); | |
182 | machine().scheduler().timer_pulse(attotime::from_hz(200), timer_expired_delegate(FUNC(ti85_state::ti85_timer_callback),this)); | |
184 | 183 | |
185 | 184 | } |
186 | 185 | |
r18113 | r18114 | |
216 | 215 | |
217 | 216 | membank("bank4")->set_base(m_ti8x_ram); |
218 | 217 | |
219 | machine().scheduler().timer_pulse(attotime::from_hz(200), FUNC(ti85_timer_callback)); | |
218 | machine().scheduler().timer_pulse(attotime::from_hz(200), timer_expired_delegate(FUNC(ti85_state::ti85_timer_callback),this)); | |
220 | 219 | } |
221 | 220 | |
222 | 221 |
r18113 | r18114 | |
---|---|---|
34 | 34 | state->membank("bank2")->set_entry(dai_rom_bank); |
35 | 35 | } |
36 | 36 | |
37 | ||
37 | TIMER_CALLBACK_MEMBER(dai_state::dai_bootstrap_callback) | |
38 | 38 | { |
39 | machine.device("maincpu")->state().set_pc(0xc000); | |
39 | machine().device("maincpu")->state().set_pc(0xc000); | |
40 | 40 | } |
41 | 41 | |
42 | 42 | |
r18113 | r18114 | |
105 | 105 | } |
106 | 106 | }; |
107 | 107 | |
108 | ||
108 | TIMER_CALLBACK_MEMBER(dai_state::dai_timer) | |
109 | 109 | { |
110 | dai_state *state = machine.driver_data<dai_state>(); | |
111 | state->m_tms5501->set_pio_bit_7((state->ioport("IN8")->read() & 0x04) ? 1:0); | |
110 | m_tms5501->set_pio_bit_7((ioport("IN8")->read() & 0x04) ? 1:0); | |
112 | 111 | } |
113 | 112 | |
114 | 113 | void dai_state::machine_start() |
115 | 114 | { |
116 | 115 | |
117 | 116 | membank("bank2")->configure_entries(0, 4, memregion("maincpu")->base() + 0x010000, 0x1000); |
118 | machine().scheduler().timer_set(attotime::zero, FUNC(dai_bootstrap_callback)); | |
119 | machine().scheduler().timer_pulse(attotime::from_hz(100), FUNC(dai_timer)); /* timer for tms5501 */ | |
117 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(dai_state::dai_bootstrap_callback),this)); | |
118 | machine().scheduler().timer_pulse(attotime::from_hz(100), timer_expired_delegate(FUNC(dai_state::dai_timer),this)); /* timer for tms5501 */ | |
120 | 119 | |
121 | 120 | memset(machine().device<ram_device>(RAM_TAG)->pointer(), 0, machine().device<ram_device>(RAM_TAG)->size()); |
122 | 121 | } |
r18113 | r18114 | |
---|---|---|
12 | 12 | #include "machine/ram.h" |
13 | 13 | #include "includes/pecom.h" |
14 | 14 | |
15 | ||
15 | TIMER_CALLBACK_MEMBER(pecom_state::reset_tick) | |
16 | 16 | { |
17 | pecom_state *state = machine.driver_data<pecom_state>(); | |
18 | 17 | |
19 | | |
18 | m_reset = 1; | |
20 | 19 | } |
21 | 20 | |
22 | 21 | void pecom_state::machine_start() |
23 | 22 | { |
24 | m_reset_timer = machine().scheduler().timer_alloc(FUNC(reset_tick)); | |
23 | m_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pecom_state::reset_tick),this)); | |
25 | 24 | } |
26 | 25 | |
27 | 26 | void pecom_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
12 | 12 | #include "includes/poly88.h" |
13 | 13 | |
14 | 14 | |
15 | ||
15 | TIMER_CALLBACK_MEMBER(poly88_state::poly88_usart_timer_callback) | |
16 | 16 | { |
17 | poly88_state *state = machine.driver_data<poly88_state>(); | |
18 | state->m_int_vector = 0xe7; | |
19 | machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
17 | m_int_vector = 0xe7; | |
18 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
20 | 19 | } |
21 | 20 | |
22 | 21 | WRITE8_MEMBER(poly88_state::poly88_baud_rate_w) |
23 | 22 | { |
24 | 23 | logerror("poly88_baud_rate_w %02x\n",data); |
25 | m_usart_timer = machine().scheduler().timer_alloc(FUNC(poly88_usart_timer_callback)); | |
24 | m_usart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(poly88_state::poly88_usart_timer_callback),this)); | |
26 | 25 | m_usart_timer->adjust(attotime::zero, 0, attotime::from_hz(300)); |
27 | 26 | |
28 | 27 | } |
r18113 | r18114 | |
39 | 38 | return 0; |
40 | 39 | } |
41 | 40 | |
42 | ||
41 | TIMER_CALLBACK_MEMBER(poly88_state::keyboard_callback) | |
43 | 42 | { |
44 | poly88_state *state = machine.driver_data<poly88_state>(); | |
45 | 43 | static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6" }; |
46 | 44 | |
47 | 45 | int i; |
48 | 46 | UINT8 code; |
49 | 47 | UINT8 key_code = 0; |
50 | UINT8 shift = machine.root_device().ioport("LINEC")->read() & 0x02 ? 1 : 0; | |
51 | UINT8 ctrl = machine.root_device().ioport("LINEC")->read() & 0x01 ? 1 : 0; | |
48 | UINT8 shift = machine().root_device().ioport("LINEC")->read() & 0x02 ? 1 : 0; | |
49 | UINT8 ctrl = machine().root_device().ioport("LINEC")->read() & 0x01 ? 1 : 0; | |
52 | 50 | |
53 | 51 | for(i = 0; i < 7; i++) |
54 | 52 | { |
55 | 53 | |
56 | code = machine.root_device().ioport(keynames[i])->read(); | |
54 | code = machine().root_device().ioport(keynames[i])->read(); | |
57 | 55 | if (code != 0) |
58 | 56 | { |
59 | 57 | if (i==0 && shift==0) { |
r18113 | r18114 | |
117 | 115 | } |
118 | 116 | } |
119 | 117 | } |
120 | if (key_code==0 && state->m_last_code !=0){ | |
121 | state->m_int_vector = 0xef; | |
122 | machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
118 | if (key_code==0 && m_last_code !=0){ | |
119 | m_int_vector = 0xef; | |
120 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
123 | 121 | } else { |
124 | | |
122 | m_last_code = key_code; | |
125 | 123 | } |
126 | 124 | } |
127 | 125 | |
r18113 | r18114 | |
131 | 129 | return state->m_int_vector; |
132 | 130 | } |
133 | 131 | |
134 | ||
132 | TIMER_CALLBACK_MEMBER(poly88_state::poly88_cassette_timer_callback) | |
135 | 133 | { |
136 | poly88_state *state = machine.driver_data<poly88_state>(); | |
137 | 134 | int data; |
138 | 135 | int current_level; |
139 | i8251_device *uart = machine.device<i8251_device>("uart"); | |
140 | serial_source_device *ser = machine.device<serial_source_device>("sercas"); | |
136 | i8251_device *uart = machine().device<i8251_device>("uart"); | |
137 | serial_source_device *ser = machine().device<serial_source_device>("sercas"); | |
141 | 138 | |
142 | // if (!(machine.root_device().ioport("DSW0")->read() & 0x02)) /* V.24 / Tape Switch */ | |
139 | // if (!(machine().root_device().ioport("DSW0")->read() & 0x02)) /* V.24 / Tape Switch */ | |
143 | 140 | //{ |
144 | 141 | /* tape reading */ |
145 | if (machine.device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_PLAY) | |
142 | if (machine().device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_PLAY) | |
146 | 143 | { |
147 | if ( | |
144 | if (m_clk_level_tape) | |
148 | 145 | { |
149 | state->m_previous_level = ((machine.device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
150 | state->m_clk_level_tape = 0; | |
146 | m_previous_level = ((machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
147 | m_clk_level_tape = 0; | |
151 | 148 | } |
152 | 149 | else |
153 | 150 | { |
154 | current_level = ((machine.device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
151 | current_level = ((machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
155 | 152 | |
156 | if ( | |
153 | if (m_previous_level!=current_level) | |
157 | 154 | { |
158 | data = (! | |
155 | data = (!m_previous_level && current_level) ? 1 : 0; | |
159 | 156 | //data = current_level; |
160 | 157 | ser->send_bit(data); |
161 | 158 | uart->receive_clock(); |
162 | 159 | |
163 | | |
160 | m_clk_level_tape = 1; | |
164 | 161 | } |
165 | 162 | } |
166 | 163 | } |
167 | 164 | |
168 | 165 | /* tape writing */ |
169 | if (machine.device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_RECORD) | |
166 | if (machine().device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_RECORD) | |
170 | 167 | { |
171 | 168 | data = ser->get_in_data_bit(); |
172 | data ^= state->m_clk_level_tape; | |
173 | machine.device<cassette_image_device>(CASSETTE_TAG)->output(data&0x01 ? 1 : -1); | |
169 | data ^= m_clk_level_tape; | |
170 | machine().device<cassette_image_device>(CASSETTE_TAG)->output(data&0x01 ? 1 : -1); | |
174 | 171 | |
175 | if (! | |
172 | if (!m_clk_level_tape) | |
176 | 173 | uart->transmit_clock(); |
177 | 174 | |
178 | | |
175 | m_clk_level_tape = m_clk_level_tape ? 0 : 1; | |
179 | 176 | |
180 | 177 | return; |
181 | 178 | } |
182 | 179 | |
183 | | |
180 | m_clk_level_tape = 1; | |
184 | 181 | |
185 | if (! | |
182 | if (!m_clk_level) | |
186 | 183 | uart->transmit_clock(); |
187 | | |
184 | m_clk_level = m_clk_level ? 0 : 1; | |
188 | 185 | // } |
189 | 186 | } |
190 | 187 | |
191 | 188 | |
192 | ||
189 | TIMER_CALLBACK_MEMBER(poly88_state::setup_machine_state) | |
193 | 190 | { |
194 | // poly88_state *state = machine.driver_data<poly88_state>(); | |
195 | i8251_device *uart = machine.device<i8251_device>("uart"); | |
196 | serial_source_device *ser = machine.device<serial_source_device>("sercas"); | |
191 | i8251_device *uart = machine().device<i8251_device>("uart"); | |
192 | serial_source_device *ser = machine().device<serial_source_device>("sercas"); | |
197 | 193 | uart->connect(ser); |
198 | 194 | } |
199 | 195 | |
r18113 | r18114 | |
201 | 197 | { |
202 | 198 | m_previous_level = 0; |
203 | 199 | m_clk_level = m_clk_level_tape = 1; |
204 | m_cassette_timer = machine().scheduler().timer_alloc(FUNC(poly88_cassette_timer_callback)); | |
200 | m_cassette_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(poly88_state::poly88_cassette_timer_callback),this)); | |
205 | 201 | m_cassette_timer->adjust(attotime::zero, 0, attotime::from_hz(600)); |
206 | 202 | |
207 | machine().scheduler().timer_pulse(attotime::from_hz(24000), FUNC(keyboard_callback)); | |
203 | machine().scheduler().timer_pulse(attotime::from_hz(24000), timer_expired_delegate(FUNC(poly88_state::keyboard_callback),this)); | |
208 | 204 | } |
209 | 205 | |
210 | 206 | void poly88_state::machine_reset() |
r18113 | r18114 | |
213 | 209 | m_intr = 0; |
214 | 210 | m_last_code = 0; |
215 | 211 | |
216 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_machine_state)); | |
212 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(poly88_state::setup_machine_state),this)); | |
217 | 213 | } |
218 | 214 | |
219 | 215 | INTERRUPT_GEN_MEMBER(poly88_state::poly88_interrupt) |
r18113 | r18114 | |
---|---|---|
136 | 136 | return 0xff; |
137 | 137 | } |
138 | 138 | |
139 | ||
139 | TIMER_CALLBACK_MEMBER(vector06_state::reset_check_callback) | |
140 | 140 | { |
141 | vector06_state *state = machine.driver_data<vector06_state>(); | |
142 | UINT8 val = machine.root_device().ioport("RESET")->read(); | |
141 | UINT8 val = machine().root_device().ioport("RESET")->read(); | |
143 | 142 | |
144 | 143 | if (BIT(val, 0)) |
145 | 144 | { |
146 | state->membank("bank1")->set_base(machine.root_device().memregion("maincpu")->base() + 0x10000); | |
147 | machine.device("maincpu")->reset(); | |
145 | membank("bank1")->set_base(machine().root_device().memregion("maincpu")->base() + 0x10000); | |
146 | machine().device("maincpu")->reset(); | |
148 | 147 | } |
149 | 148 | |
150 | 149 | if (BIT(val, 1)) |
151 | 150 | { |
152 | state->membank("bank1")->set_base(machine.device<ram_device>(RAM_TAG)->pointer() + 0x0000); | |
153 | machine.device("maincpu")->reset(); | |
151 | membank("bank1")->set_base(machine().device<ram_device>(RAM_TAG)->pointer() + 0x0000); | |
152 | machine().device("maincpu")->reset(); | |
154 | 153 | } |
155 | 154 | } |
156 | 155 | |
r18113 | r18114 | |
164 | 163 | |
165 | 164 | void vector06_state::machine_start() |
166 | 165 | { |
167 | machine().scheduler().timer_pulse(attotime::from_hz(50), FUNC(reset_check_callback)); | |
166 | machine().scheduler().timer_pulse(attotime::from_hz(50), timer_expired_delegate(FUNC(vector06_state::reset_check_callback),this)); | |
168 | 167 | } |
169 | 168 | |
170 | 169 | void vector06_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
101 | 101 | DEVCB_DRIVER_MEMBER(special_state, specialist_8255_portc_w) |
102 | 102 | }; |
103 | 103 | |
104 | ||
104 | TIMER_CALLBACK_MEMBER(special_state::special_reset) | |
105 | 105 | { |
106 | special_state *state = machine.driver_data<special_state>(); | |
107 | state->membank("bank1")->set_entry(0); | |
106 | membank("bank1")->set_entry(0); | |
108 | 107 | } |
109 | 108 | |
110 | 109 | |
111 | 110 | MACHINE_RESET_MEMBER(special_state,special) |
112 | 111 | { |
113 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(special_reset)); | |
112 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(special_state::special_reset),this)); | |
114 | 113 | membank("bank1")->set_entry(1); |
115 | 114 | } |
116 | 115 | |
r18113 | r18114 | |
224 | 223 | m_specimx_audio = machine().device("custom"); |
225 | 224 | } |
226 | 225 | |
227 | ||
226 | TIMER_CALLBACK_MEMBER(special_state::setup_pit8253_gates) | |
228 | 227 | { |
229 | device_t *pit8253 = machine.device("pit8253"); | |
228 | device_t *pit8253 = machine().device("pit8253"); | |
230 | 229 | |
231 | 230 | pit8253_gate0_w(pit8253, 0); |
232 | 231 | pit8253_gate1_w(pit8253, 0); |
r18113 | r18114 | |
237 | 236 | { |
238 | 237 | specimx_set_bank(2, 0); // Initiali load ROM disk |
239 | 238 | m_specimx_color = 0x70; |
240 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_pit8253_gates)); | |
239 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(special_state::setup_pit8253_gates),this)); | |
241 | 240 | device_t *fdc = machine().device("wd1793"); |
242 | 241 | wd17xx_set_pause_time(fdc,12); |
243 | 242 | wd17xx_dden_w(fdc, 0); |
r18113 | r18114 | |
---|---|---|
12 | 12 | |
13 | 13 | /* timer for sorcerer serial chip transmit and receive */ |
14 | 14 | |
15 | ||
15 | TIMER_CALLBACK_MEMBER(sorcerer_state::sorcerer_serial_tc) | |
16 | 16 | { |
17 | sorcerer_state *state = machine.driver_data<sorcerer_state>(); | |
18 | 17 | /* if rs232 is enabled, uart is connected to clock defined by bit6 of port fe. |
19 | 18 | Transmit and receive clocks are connected to the same clock */ |
20 | 19 | |
21 | 20 | /* if rs232 is disabled, receive clock is linked to cassette hardware */ |
22 | if ( | |
21 | if (m_fe & 0x80) | |
23 | 22 | { |
24 | 23 | /* connect to rs232 */ |
25 | 24 | } |
r18113 | r18114 | |
41 | 40 | |
42 | 41 | |
43 | 42 | |
44 | ||
43 | TIMER_CALLBACK_MEMBER(sorcerer_state::sorcerer_cassette_tc) | |
45 | 44 | { |
46 | sorcerer_state *state = machine.driver_data<sorcerer_state>(); | |
47 | 45 | UINT8 cass_ws = 0; |
48 | switch ( | |
46 | switch (m_fe & 0xc0) /*/ bit 7 low indicates cassette */ | |
49 | 47 | { |
50 | 48 | case 0x00: /* Cassette 300 baud */ |
51 | 49 | |
52 | 50 | /* loading a tape - this is basically the same as the super80. |
53 | 51 | We convert the 1200/2400 Hz signal to a 0 or 1, and send it to the uart. */ |
54 | 52 | |
55 | | |
53 | m_cass_data.input.length++; | |
56 | 54 | |
57 | cass_ws = ((cassette_device_image(machine))->input() > +0.02) ? 1 : 0; | |
55 | cass_ws = ((cassette_device_image(machine()))->input() > +0.02) ? 1 : 0; | |
58 | 56 | |
59 | if (cass_ws != | |
57 | if (cass_ws != m_cass_data.input.level) | |
60 | 58 | { |
61 | state->m_cass_data.input.level = cass_ws; | |
62 | state->m_cass_data.input.bit = ((state->m_cass_data.input.length < 0x6) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0; | |
63 | state->m_cass_data.input.length = 0; | |
64 | ay31015_set_input_pin( state->m_uart, AY31015_SI, state->m_cass_data.input.bit ); | |
59 | m_cass_data.input.level = cass_ws; | |
60 | m_cass_data.input.bit = ((m_cass_data.input.length < 0x6) || (m_cass_data.input.length > 0x20)) ? 1 : 0; | |
61 | m_cass_data.input.length = 0; | |
62 | ay31015_set_input_pin( m_uart, AY31015_SI, m_cass_data.input.bit ); | |
65 | 63 | } |
66 | 64 | |
67 | 65 | /* saving a tape - convert the serial stream from the uart, into 1200 and 2400 Hz frequencies. |
68 | 66 | Synchronisation of the frequency pulses to the uart is extremely important. */ |
69 | 67 | |
70 | state->m_cass_data.output.length++; | |
71 | if (!(state->m_cass_data.output.length & 0x1f)) | |
68 | m_cass_data.output.length++; | |
69 | if (!(m_cass_data.output.length & 0x1f)) | |
72 | 70 | { |
73 | cass_ws = ay31015_get_output_pin( state->m_uart, AY31015_SO ); | |
74 | if (cass_ws != state->m_cass_data.output.bit) | |
71 | cass_ws = ay31015_get_output_pin( m_uart, AY31015_SO ); | |
72 | if (cass_ws != m_cass_data.output.bit) | |
75 | 73 | { |
76 | state->m_cass_data.output.bit = cass_ws; | |
77 | state->m_cass_data.output.length = 0; | |
74 | m_cass_data.output.bit = cass_ws; | |
75 | m_cass_data.output.length = 0; | |
78 | 76 | } |
79 | 77 | } |
80 | 78 | |
81 | if (!( | |
79 | if (!(m_cass_data.output.length & 3)) | |
82 | 80 | { |
83 | if (!(( | |
81 | if (!((m_cass_data.output.bit == 0) && (m_cass_data.output.length & 4))) | |
84 | 82 | { |
85 | state->m_cass_data.output.level ^= 1; // toggle output state, except on 2nd half of low bit | |
86 | cassette_device_image(machine)->output(state->m_cass_data.output.level ? -1.0 : +1.0); | |
83 | m_cass_data.output.level ^= 1; // toggle output this, except on 2nd half of low bit | |
84 | cassette_device_image(machine())->output(m_cass_data.output.level ? -1.0 : +1.0); | |
87 | 85 | } |
88 | 86 | } |
89 | 87 | return; |
90 | 88 | |
91 | 89 | case 0x40: /* Cassette 1200 baud */ |
92 | 90 | /* loading a tape */ |
93 | | |
91 | m_cass_data.input.length++; | |
94 | 92 | |
95 | cass_ws = ((cassette_device_image(machine))->input() > +0.02) ? 1 : 0; | |
93 | cass_ws = ((cassette_device_image(machine()))->input() > +0.02) ? 1 : 0; | |
96 | 94 | |
97 | if (cass_ws != | |
95 | if (cass_ws != m_cass_data.input.level || m_cass_data.input.length == 10) | |
98 | 96 | { |
99 | state->m_cass_data.input.bit = ((state->m_cass_data.input.length < 10) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0; | |
100 | if ( cass_ws != state->m_cass_data.input.level ) | |
97 | m_cass_data.input.bit = ((m_cass_data.input.length < 10) || (m_cass_data.input.length > 0x20)) ? 1 : 0; | |
98 | if ( cass_ws != m_cass_data.input.level ) | |
101 | 99 | { |
102 | state->m_cass_data.input.length = 0; | |
103 | state->m_cass_data.input.level = cass_ws; | |
100 | m_cass_data.input.length = 0; | |
101 | m_cass_data.input.level = cass_ws; | |
104 | 102 | } |
105 | ay31015_set_input_pin( | |
103 | ay31015_set_input_pin( m_uart, AY31015_SI, m_cass_data.input.bit ); | |
106 | 104 | } |
107 | 105 | |
108 | 106 | /* saving a tape - convert the serial stream from the uart, into 600 and 1200 Hz frequencies. */ |
109 | 107 | |
110 | state->m_cass_data.output.length++; | |
111 | if (!(state->m_cass_data.output.length & 7)) | |
108 | m_cass_data.output.length++; | |
109 | if (!(m_cass_data.output.length & 7)) | |
112 | 110 | { |
113 | cass_ws = ay31015_get_output_pin( state->m_uart, AY31015_SO ); | |
114 | if (cass_ws != state->m_cass_data.output.bit) | |
111 | cass_ws = ay31015_get_output_pin( m_uart, AY31015_SO ); | |
112 | if (cass_ws != m_cass_data.output.bit) | |
115 | 113 | { |
116 | state->m_cass_data.output.bit = cass_ws; | |
117 | state->m_cass_data.output.length = 0; | |
114 | m_cass_data.output.bit = cass_ws; | |
115 | m_cass_data.output.length = 0; | |
118 | 116 | } |
119 | 117 | } |
120 | 118 | |
121 | if (!( | |
119 | if (!(m_cass_data.output.length & 7)) | |
122 | 120 | { |
123 | if (!(( | |
121 | if (!((m_cass_data.output.bit == 0) && (m_cass_data.output.length & 8))) | |
124 | 122 | { |
125 | state->m_cass_data.output.level ^= 1; // toggle output state, except on 2nd half of low bit | |
126 | cassette_device_image(machine)->output(state->m_cass_data.output.level ? -1.0 : +1.0); | |
123 | m_cass_data.output.level ^= 1; // toggle output this, except on 2nd half of low bit | |
124 | cassette_device_image(machine())->output(m_cass_data.output.level ? -1.0 : +1.0); | |
127 | 125 | } |
128 | 126 | } |
129 | 127 | return; |
r18113 | r18114 | |
132 | 130 | |
133 | 131 | |
134 | 132 | /* after the first 4 bytes have been read from ROM, switch the ram back in */ |
135 | ||
133 | TIMER_CALLBACK_MEMBER(sorcerer_state::sorcerer_reset) | |
136 | 134 | { |
137 | sorcerer_state *state = machine.driver_data<sorcerer_state>(); | |
138 | state->membank("boot")->set_entry(0); | |
135 | membank("boot")->set_entry(0); | |
139 | 136 | } |
140 | 137 | |
141 | 138 | WRITE8_MEMBER(sorcerer_state::sorcerer_fc_w) |
r18113 | r18114 | |
353 | 350 | |
354 | 351 | void sorcerer_state::machine_start() |
355 | 352 | { |
356 | m_cassette_timer = machine().scheduler().timer_alloc(FUNC(sorcerer_cassette_tc)); | |
353 | m_cassette_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sorcerer_state::sorcerer_cassette_tc),this)); | |
357 | 354 | #if SORCERER_USING_RS232 |
358 | m_serial_timer = machine().scheduler().timer_alloc(FUNC(sorcerer_serial_tc)); | |
355 | m_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sorcerer_state::sorcerer_serial_tc),this)); | |
359 | 356 | #endif |
360 | 357 | |
361 | 358 | UINT16 endmem = 0xbfff; |
r18113 | r18114 | |
380 | 377 | |
381 | 378 | MACHINE_START_MEMBER(sorcerer_state,sorcererd) |
382 | 379 | { |
383 | m_cassette_timer = machine().scheduler().timer_alloc(FUNC(sorcerer_cassette_tc)); | |
380 | m_cassette_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sorcerer_state::sorcerer_cassette_tc),this)); | |
384 | 381 | #if SORCERER_USING_RS232 |
385 | m_serial_timer = machine().scheduler().timer_alloc(FUNC(sorcerer_serial_tc)); | |
382 | m_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sorcerer_state::sorcerer_serial_tc),this)); | |
386 | 383 | #endif |
387 | 384 | |
388 | 385 | UINT16 endmem = 0xbbff; |
r18113 | r18114 | |
419 | 416 | sorcerer_fe_w(space, 0, 0, 0xff); |
420 | 417 | |
421 | 418 | membank("boot")->set_entry(1); |
422 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(sorcerer_reset)); | |
419 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(sorcerer_state::sorcerer_reset),this)); | |
423 | 420 | } |
r18113 | r18114 | |
---|---|---|
331 | 331 | //}; |
332 | 332 | |
333 | 333 | |
334 | ||
334 | TIMER_CALLBACK_MEMBER(osborne1_state::osborne1_video_callback) | |
335 | 335 | { |
336 | osborne1_state *state = machine.driver_data<osborne1_state>(); | |
337 | int y = machine.primary_screen->vpos(); | |
336 | int y = machine().primary_screen->vpos(); | |
338 | 337 | UINT8 ra=0,chr,gfx,dim; |
339 | 338 | UINT16 x,ma; |
340 | 339 | |
r18113 | r18114 | |
342 | 341 | if ( y == 0 ) |
343 | 342 | { |
344 | 343 | /* Clear CA1 on video PIA */ |
345 | | |
344 | m_pia1->ca1_w(0); | |
346 | 345 | } |
347 | 346 | if ( y == 240 ) |
348 | 347 | { |
349 | 348 | /* Set CA1 on video PIA */ |
350 | | |
349 | m_pia1->ca1_w(1); | |
351 | 350 | } |
352 | 351 | if ( y < 240 ) |
353 | 352 | { |
354 | 353 | ra = y % 10; |
355 | 354 | /* Draw a line of the display */ |
356 | ma = (state->m_new_start_y + (y/10)) * 128 + state->m_new_start_x; | |
357 | UINT16 *p = &state->m_bitmap.pix16(y); | |
355 | ma = (m_new_start_y + (y/10)) * 128 + m_new_start_x; | |
356 | UINT16 *p = &m_bitmap.pix16(y); | |
358 | 357 | |
359 | 358 | for ( x = 0; x < 52; x++ ) |
360 | 359 | { |
361 | chr = machine.device<ram_device>(RAM_TAG)->pointer()[ 0xF000 + ( (ma+x) & 0xFFF ) ]; | |
362 | dim = machine.device<ram_device>(RAM_TAG)->pointer()[ 0x10000 + ( (ma+x) & 0xFFF ) ] & 0x80; | |
360 | chr = machine().device<ram_device>(RAM_TAG)->pointer()[ 0xF000 + ( (ma+x) & 0xFFF ) ]; | |
361 | dim = machine().device<ram_device>(RAM_TAG)->pointer()[ 0x10000 + ( (ma+x) & 0xFFF ) ] & 0x80; | |
363 | 362 | |
364 | 363 | if ( (chr & 0x80) && (ra == 9) ) |
365 | 364 | gfx = 0xFF; |
366 | 365 | else |
367 | gfx = | |
366 | gfx = m_p_chargen[ (ra << 7) | ( chr & 0x7F ) ]; | |
368 | 367 | |
369 | 368 | /* Display a scanline of a character */ |
370 | 369 | *p++ = BIT(gfx, 7) ? ( dim ? 1 : 2 ) : 0; |
r18113 | r18114 | |
380 | 379 | |
381 | 380 | if ( (ra==2) || (ra== 6) ) |
382 | 381 | { |
383 | beep_set_state( | |
382 | beep_set_state( m_beep, m_beep_state ); | |
384 | 383 | } |
385 | 384 | else |
386 | 385 | { |
387 | beep_set_state( | |
386 | beep_set_state( m_beep, 0 ); | |
388 | 387 | } |
389 | 388 | |
390 | | |
389 | m_video_timer->adjust(machine().primary_screen->time_until_pos(y + 1, 0 )); | |
391 | 390 | } |
392 | 391 | |
393 | ||
392 | TIMER_CALLBACK_MEMBER(osborne1_state::setup_osborne1) | |
394 | 393 | { |
395 | osborne1_state *state = machine.driver_data<osborne1_state>(); | |
396 | beep_set_state( state->m_beep, 0 ); | |
397 | beep_set_frequency( state->m_beep, 300 /* 60 * 240 / 2 */ ); | |
398 | state->m_pia1->ca1_w(0); | |
394 | beep_set_state( m_beep, 0 ); | |
395 | beep_set_frequency( m_beep, 300 /* 60 * 240 / 2 */ ); | |
396 | m_pia1->ca1_w(0); | |
399 | 397 | } |
400 | 398 | |
401 | 399 | static void osborne1_load_proc(device_image_interface &image) |
r18113 | r18114 | |
453 | 451 | |
454 | 452 | /* Configure the 6850 ACIA */ |
455 | 453 | // acia6850_config( 0, &osborne1_6850_config ); |
456 | m_video_timer = machine().scheduler().timer_alloc(FUNC(osborne1_video_callback)); | |
454 | m_video_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(osborne1_state::osborne1_video_callback),this)); | |
457 | 455 | m_video_timer->adjust(machine().primary_screen->time_until_pos(1, 0 )); |
458 | 456 | |
459 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_osborne1)); | |
457 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(osborne1_state::setup_osborne1),this)); | |
460 | 458 | } |
461 | 459 | |
462 | 460 |
r18113 | r18114 | |
---|---|---|
340 | 340 | |
341 | 341 | /* handle mouse moves */ |
342 | 342 | /* shamelessly stolen from machine/mac.c :-) */ |
343 | ||
343 | TIMER_CALLBACK_MEMBER(lisa_state::handle_mouse) | |
344 | 344 | { |
345 | lisa_state *state = machine.driver_data<lisa_state>(); | |
346 | 345 | int diff_x = 0, diff_y = 0; |
347 | 346 | int new_mx, new_my; |
348 | 347 | |
349 | 348 | #if 0 |
350 | if ( | |
349 | if (m_COPS_force_unplug) | |
351 | 350 | return; /* ???? */ |
352 | 351 | #endif |
353 | 352 | |
354 | new_mx = machine.root_device().ioport("MOUSE_X")->read(); | |
355 | new_my = machine.root_device().ioport("MOUSE_Y")->read(); | |
353 | new_mx = machine().root_device().ioport("MOUSE_X")->read(); | |
354 | new_my = machine().root_device().ioport("MOUSE_Y")->read(); | |
356 | 355 | |
357 | 356 | /* see if it moved in the x coord */ |
358 | if (new_mx != | |
357 | if (new_mx != m_last_mx) | |
359 | 358 | { |
360 | diff_x = new_mx - | |
359 | diff_x = new_mx - m_last_mx; | |
361 | 360 | |
362 | 361 | /* check for wrap */ |
363 | 362 | if (diff_x > 0x80) |
r18113 | r18114 | |
365 | 364 | if (diff_x < -0x80) |
366 | 365 | diff_x = -0x100-diff_x; |
367 | 366 | |
368 | | |
367 | m_last_mx = new_mx; | |
369 | 368 | } |
370 | 369 | /* see if it moved in the y coord */ |
371 | if (new_my != | |
370 | if (new_my != m_last_my) | |
372 | 371 | { |
373 | diff_y = new_my - | |
372 | diff_y = new_my - m_last_my; | |
374 | 373 | |
375 | 374 | /* check for wrap */ |
376 | 375 | if (diff_y > 0x80) |
r18113 | r18114 | |
378 | 377 | if (diff_y < -0x80) |
379 | 378 | diff_y = -0x100-diff_y; |
380 | 379 | |
381 | | |
380 | m_last_my = new_my; | |
382 | 381 | } |
383 | 382 | |
384 | 383 | /* update any remaining count and then return */ |
385 | 384 | if (diff_x || diff_y) |
386 | 385 | { |
387 | if ( | |
386 | if (m_mouse_data_offset != -1) | |
388 | 387 | { |
389 | state->m_fifo_data[state->m_mouse_data_offset] += diff_x; | |
390 | state->m_fifo_data[(state->m_mouse_data_offset+1) & 0x7] += diff_y; | |
388 | m_fifo_data[m_mouse_data_offset] += diff_x; | |
389 | m_fifo_data[(m_mouse_data_offset+1) & 0x7] += diff_y; | |
391 | 390 | } |
392 | 391 | else |
393 | 392 | { |
394 | 393 | #if 0 |
395 | if ( | |
394 | if (m_fifo_size <= 5) | |
396 | 395 | #else |
397 | 396 | /* trash old data */ |
398 | while ( | |
397 | while (m_fifo_size > 5) | |
399 | 398 | { |
400 | state->m_fifo_head = (state->m_fifo_head+1) & 0x7; | |
401 | state->m_fifo_size--; | |
399 | m_fifo_head = (m_fifo_head+1) & 0x7; | |
400 | m_fifo_size--; | |
402 | 401 | } |
403 | 402 | #endif |
404 | 403 | |
405 | 404 | { |
406 | 405 | /*logerror("Adding 3 bytes of mouse data to FIFO\n");*/ |
407 | 406 | |
408 | state->m_fifo_data[state->m_fifo_tail] = 0; | |
409 | state->m_mouse_data_offset = state->m_fifo_tail = (state->m_fifo_tail+1) & 0x7; | |
410 | state->m_fifo_data[state->m_fifo_tail] = diff_x; | |
411 | state->m_fifo_tail = (state->m_fifo_tail+1) & 0x7; | |
412 | state->m_fifo_data[state->m_fifo_tail] = diff_y; | |
413 | state->m_fifo_tail = (state->m_fifo_tail+1) & 0x7; | |
414 | state->m_fifo_size += 3; | |
407 | m_fifo_data[m_fifo_tail] = 0; | |
408 | m_mouse_data_offset = m_fifo_tail = (m_fifo_tail+1) & 0x7; | |
409 | m_fifo_data[m_fifo_tail] = diff_x; | |
410 | m_fifo_tail = (m_fifo_tail+1) & 0x7; | |
411 | m_fifo_data[m_fifo_tail] = diff_y; | |
412 | m_fifo_tail = (m_fifo_tail+1) & 0x7; | |
413 | m_fifo_size += 3; | |
415 | 414 | |
416 | 415 | /*logerror("handle_mouse : trying to send data to VIA\n");*/ |
417 | COPS_send_data_if_possible(machine); | |
416 | COPS_send_data_if_possible(machine()); | |
418 | 417 | } |
419 | 418 | /* else, mouse data is lost forever (correct ??) */ |
420 | 419 | } |
r18113 | r18114 | |
422 | 421 | } |
423 | 422 | |
424 | 423 | /* read command from the VIA port A */ |
425 | ||
424 | TIMER_CALLBACK_MEMBER(lisa_state::read_COPS_command) | |
426 | 425 | { |
427 | lisa_state *state = machine.driver_data<lisa_state>(); | |
428 | 426 | int command; |
429 | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); | |
430 | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); | |
427 | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); | |
428 | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); | |
431 | 429 | |
432 | | |
430 | m_COPS_Ready = 0; | |
433 | 431 | |
434 | 432 | /*logerror("read_COPS_command : trying to send data to VIA\n");*/ |
435 | COPS_send_data_if_possible(machine); | |
433 | COPS_send_data_if_possible(machine()); | |
436 | 434 | |
437 | 435 | /* some pull-ups allow the COPS to read 1s when the VIA port is not set as output */ |
438 | command = ( | |
436 | command = (m_COPS_command | (~ via_0->read(space, VIA_DDRA))) & 0xff; | |
439 | 437 | |
440 | 438 | // printf("Dropping Ready, command = %02x\n", command); |
441 | 439 | |
r18113 | r18114 | |
449 | 447 | switch ((command & 0xF0) >> 4) |
450 | 448 | { |
451 | 449 | case 0x1: /* write clock data */ |
452 | if ( | |
450 | if (m_clock_regs.clock_write_ptr != -1) | |
453 | 451 | { |
454 | switch ( | |
452 | switch (m_clock_regs.clock_write_ptr) | |
455 | 453 | { |
456 | 454 | case 0: |
457 | 455 | case 1: |
r18113 | r18114 | |
459 | 457 | case 3: |
460 | 458 | case 4: |
461 | 459 | /* alarm */ |
462 | state->m_clock_regs.alarm &= ~ (0xf << (4 * (4 - state->m_clock_regs.clock_write_ptr))); | |
463 | state->m_clock_regs.alarm |= immediate << (4 * (4 - state->m_clock_regs.clock_write_ptr)); | |
460 | m_clock_regs.alarm &= ~ (0xf << (4 * (4 - m_clock_regs.clock_write_ptr))); | |
461 | m_clock_regs.alarm |= immediate << (4 * (4 - m_clock_regs.clock_write_ptr)); | |
464 | 462 | break; |
465 | 463 | case 5: |
466 | 464 | /* year */ |
467 | | |
465 | m_clock_regs.years = immediate; | |
468 | 466 | break; |
469 | 467 | case 6: |
470 | 468 | /* day */ |
471 | | |
469 | m_clock_regs.days1 = immediate; | |
472 | 470 | break; |
473 | 471 | case 7: |
474 | 472 | /* day */ |
475 | | |
473 | m_clock_regs.days2 = immediate; | |
476 | 474 | break; |
477 | 475 | case 8: |
478 | 476 | /* day */ |
479 | | |
477 | m_clock_regs.days3 = immediate; | |
480 | 478 | break; |
481 | 479 | case 9: |
482 | 480 | /* hours */ |
483 | | |
481 | m_clock_regs.hours1 = immediate; | |
484 | 482 | break; |
485 | 483 | case 10: |
486 | 484 | /* hours */ |
487 | | |
485 | m_clock_regs.hours2 = immediate; | |
488 | 486 | break; |
489 | 487 | case 11: |
490 | 488 | /* minutes */ |
491 | | |
489 | m_clock_regs.minutes1 = immediate; | |
492 | 490 | break; |
493 | 491 | case 12: |
494 | 492 | /* minutes */ |
495 | | |
493 | m_clock_regs.minutes1 = immediate; | |
496 | 494 | break; |
497 | 495 | case 13: |
498 | 496 | /* seconds */ |
499 | | |
497 | m_clock_regs.seconds1 = immediate; | |
500 | 498 | break; |
501 | 499 | case 14: |
502 | 500 | /* seconds */ |
503 | | |
501 | m_clock_regs.seconds2 = immediate; | |
504 | 502 | break; |
505 | 503 | case 15: |
506 | 504 | /* tenth */ |
507 | | |
505 | m_clock_regs.tenths = immediate; | |
508 | 506 | break; |
509 | 507 | } |
510 | state->m_clock_regs.clock_write_ptr++; | |
511 | if (state->m_clock_regs.clock_write_ptr == 16) | |
512 | state->m_clock_regs.clock_write_ptr = -1; | |
508 | m_clock_regs.clock_write_ptr++; | |
509 | if (m_clock_regs.clock_write_ptr == 16) | |
510 | m_clock_regs.clock_write_ptr = -1; | |
513 | 511 | } |
514 | 512 | |
515 | 513 | break; |
r18113 | r18114 | |
517 | 515 | case 0x2: /* set clock mode */ |
518 | 516 | if (immediate & 0x8) |
519 | 517 | { /* start setting the clock */ |
520 | | |
518 | m_clock_regs.clock_write_ptr = 0; | |
521 | 519 | } |
522 | 520 | else |
523 | 521 | { /* clock write disabled */ |
524 | | |
522 | m_clock_regs.clock_write_ptr = -1; | |
525 | 523 | } |
526 | 524 | |
527 | 525 | if (! (immediate & 0x4)) |
r18113 | r18114 | |
533 | 531 | /* should never happen */ |
534 | 532 | } |
535 | 533 | |
536 | | |
534 | m_clock_regs.clock_mode = (clock_mode_t)(immediate & 0x3); | |
537 | 535 | break; |
538 | 536 | |
539 | 537 | #if 0 |
r18113 | r18114 | |
548 | 546 | #endif |
549 | 547 | |
550 | 548 | case 0x5: /* set high nibble of NMI character to nnnn */ |
551 | | |
549 | m_NMIcode = (m_NMIcode & 0x0f) | (immediate << 4); | |
552 | 550 | break; |
553 | 551 | |
554 | 552 | case 0x6: /* set low nibble of NMI character to nnnn */ |
555 | | |
553 | m_NMIcode = (m_NMIcode & 0xf0) | immediate; | |
556 | 554 | break; |
557 | 555 | |
558 | 556 | case 0x7: /* send mouse command */ |
559 | 557 | if (immediate & 0x8) |
560 | | |
558 | m_mouse_timer->adjust(attotime::zero, 0, attotime::from_msec((immediate & 0x7)*4)); /* enable mouse */ | |
561 | 559 | else |
562 | | |
560 | m_mouse_timer->reset(); | |
563 | 561 | break; |
564 | 562 | } |
565 | 563 | } |
r18113 | r18114 | |
582 | 580 | UINT8 reply[7]; |
583 | 581 | |
584 | 582 | reply[0] = 0x80; |
585 | reply[1] = 0xE0 | state->m_clock_regs.years; | |
586 | reply[2] = (state->m_clock_regs.days1 << 4) | state->m_clock_regs.days2; | |
587 | reply[3] = (state->m_clock_regs.days3 << 4) | state->m_clock_regs.hours1; | |
588 | reply[4] = (state->m_clock_regs.hours2 << 4) | state->m_clock_regs.minutes1; | |
589 | reply[5] = (state->m_clock_regs.minutes2 << 4) | state->m_clock_regs.seconds1; | |
590 | reply[6] = (state->m_clock_regs.seconds2 << 4) | state->m_clock_regs.tenths; | |
583 | reply[1] = 0xE0 | m_clock_regs.years; | |
584 | reply[2] = (m_clock_regs.days1 << 4) | m_clock_regs.days2; | |
585 | reply[3] = (m_clock_regs.days3 << 4) | m_clock_regs.hours1; | |
586 | reply[4] = (m_clock_regs.hours2 << 4) | m_clock_regs.minutes1; | |
587 | reply[5] = (m_clock_regs.minutes2 << 4) | m_clock_regs.seconds1; | |
588 | reply[6] = (m_clock_regs.seconds2 << 4) | m_clock_regs.tenths; | |
591 | 589 | |
592 | COPS_queue_data(machine, reply, 7); | |
590 | COPS_queue_data(machine(), reply, 7); | |
593 | 591 | } |
594 | 592 | break; |
595 | 593 | } |
r18113 | r18114 | |
597 | 595 | } |
598 | 596 | |
599 | 597 | /* this timer callback raises the COPS Ready line, which tells the COPS is about to read a command */ |
600 | ||
598 | TIMER_CALLBACK_MEMBER(lisa_state::set_COPS_ready) | |
601 | 599 | { |
602 | lisa_state *state = machine.driver_data<lisa_state>(); | |
603 | state->m_COPS_Ready = 1; | |
600 | m_COPS_Ready = 1; | |
604 | 601 | |
605 | 602 | /* impulsion width : +/- 20us */ |
606 | machine.scheduler().timer_set(attotime::from_usec(20), FUNC(read_COPS_command)); | |
603 | machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(lisa_state::read_COPS_command),this)); | |
607 | 604 | } |
608 | 605 | |
609 | 606 | static void reset_COPS(lisa_state *state) |
r18113 | r18114 | |
1031 | 1028 | |
1032 | 1029 | void lisa_state::machine_start() |
1033 | 1030 | { |
1034 | m_mouse_timer = machine().scheduler().timer_alloc(FUNC(handle_mouse)); | |
1031 | m_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(lisa_state::handle_mouse),this)); | |
1035 | 1032 | |
1036 | 1033 | /* read command every ms (don't know the real value) */ |
1037 | machine().scheduler().timer_pulse(attotime::from_msec(1), FUNC(set_COPS_ready)); | |
1034 | machine().scheduler().timer_pulse(attotime::from_msec(1), timer_expired_delegate(FUNC(lisa_state::set_COPS_ready),this)); | |
1038 | 1035 | } |
1039 | 1036 | |
1040 | 1037 | void lisa_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
600 | 600 | } |
601 | 601 | } |
602 | 602 | |
603 | ||
603 | TIMER_CALLBACK_MEMBER(lynx_state::lynx_blitter_timer) | |
604 | 604 | { |
605 | lynx_state *state = machine.driver_data<lynx_state>(); | |
606 | state->m_blitter.busy=0; // blitter finished | |
607 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
605 | m_blitter.busy=0; // blitter finished | |
606 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
608 | 607 | } |
609 | 608 | |
610 | 609 | /* |
r18113 | r18114 | |
805 | 804 | } |
806 | 805 | } |
807 | 806 | |
808 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(state->m_blitter.memory_accesses), FUNC(lynx_blitter_timer)); | |
807 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(state->m_blitter.memory_accesses), timer_expired_delegate(FUNC(lynx_state::lynx_blitter_timer),state)); | |
809 | 808 | } |
810 | 809 | |
811 | 810 | |
r18113 | r18114 | |
1394 | 1393 | #define NR_LYNX_TIMERS 8 |
1395 | 1394 | |
1396 | 1395 | |
1397 | static TIMER_CALLBACK(lynx_timer_shot); | |
1398 | 1396 | |
1397 | ||
1399 | 1398 | static void lynx_timer_init(running_machine &machine, int which) |
1400 | 1399 | { |
1401 | 1400 | lynx_state *state = machine.driver_data<lynx_state>(); |
1402 | 1401 | memset( &state->m_timer[which], 0, sizeof(LYNX_TIMER) ); |
1403 | state->m_timer[which].timer = machine.scheduler().timer_alloc(FUNC(lynx_timer_shot)); | |
1402 | state->m_timer[which].timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(lynx_state::lynx_timer_shot),state)); | |
1404 | 1403 | } |
1405 | 1404 | |
1406 | 1405 | static void lynx_timer_signal_irq(running_machine &machine, int which) |
r18113 | r18114 | |
1506 | 1505 | } |
1507 | 1506 | } |
1508 | 1507 | |
1509 | ||
1508 | TIMER_CALLBACK_MEMBER(lynx_state::lynx_timer_shot) | |
1510 | 1509 | { |
1511 | lynx_state *state = machine.driver_data<lynx_state>(); | |
1512 | lynx_timer_signal_irq( machine, param ); | |
1513 | if ( ! ( state->m_timer[param].cntrl1 & 0x10 ) ) // if reload not enabled | |
1510 | lynx_timer_signal_irq( machine(), param ); | |
1511 | if ( ! ( m_timer[param].cntrl1 & 0x10 ) ) // if reload not enabled | |
1514 | 1512 | { |
1515 | state->m_timer[param].timer_active = 0; | |
1516 | state->m_timer[param].cntrl2 |= 8; // set timer done | |
1513 | m_timer[param].timer_active = 0; | |
1514 | m_timer[param].cntrl2 |= 8; // set timer done | |
1517 | 1515 | } |
1518 | 1516 | else |
1519 | 1517 | { |
1520 | attotime t = (attotime::from_hz(lynx_time_factor(state->m_timer[param].cntrl1 & 0x07)) * (state->m_timer[param].bakup + 1)); | |
1521 | state->m_timer[param].timer->adjust(t, param); | |
1518 | attotime t = (attotime::from_hz(lynx_time_factor(m_timer[param].cntrl1 & 0x07)) * (m_timer[param].bakup + 1)); | |
1519 | m_timer[param].timer->adjust(t, param); | |
1522 | 1520 | } |
1523 | 1521 | } |
1524 | 1522 | |
r18113 | r18114 | |
1616 | 1614 | memset(&state->m_uart, 0, sizeof(state->m_uart)); |
1617 | 1615 | } |
1618 | 1616 | |
1619 | ||
1617 | TIMER_CALLBACK_MEMBER(lynx_state::lynx_uart_loopback_timer) | |
1620 | 1618 | { |
1621 | lynx_state *state = machine.driver_data<lynx_state>(); | |
1622 | state->m_uart.received = FALSE; | |
1619 | m_uart.received = FALSE; | |
1623 | 1620 | } |
1624 | 1621 | |
1625 | ||
1622 | TIMER_CALLBACK_MEMBER(lynx_state::lynx_uart_timer) | |
1626 | 1623 | { |
1627 | lynx_state *state = machine.driver_data<lynx_state>(); | |
1628 | if (state->m_uart.buffer_loaded) | |
1624 | if (m_uart.buffer_loaded) | |
1629 | 1625 | { |
1630 | state->m_uart.data_to_send = state->m_uart.buffer; | |
1631 | state->m_uart.buffer_loaded = FALSE; | |
1632 | machine.scheduler().timer_set(attotime::from_usec(11*16), FUNC(lynx_uart_timer)); | |
1626 | m_uart.data_to_send = m_uart.buffer; | |
1627 | m_uart.buffer_loaded = FALSE; | |
1628 | machine().scheduler().timer_set(attotime::from_usec(11*16), timer_expired_delegate(FUNC(lynx_state::lynx_uart_timer),this)); | |
1633 | 1629 | } |
1634 | 1630 | else |
1635 | 1631 | { |
1636 | state->m_uart.sending = FALSE; | |
1637 | state->m_uart.received = TRUE; | |
1638 | state->m_uart.data_received = state->m_uart.data_to_send; | |
1639 | machine.scheduler().timer_set(attotime::from_usec(11*16), FUNC(lynx_uart_loopback_timer)); | |
1640 | if (state->m_uart.serctl & 0x40) | |
1632 | m_uart.sending = FALSE; | |
1633 | m_uart.received = TRUE; | |
1634 | m_uart.data_received = m_uart.data_to_send; | |
1635 | machine().scheduler().timer_set(attotime::from_usec(11*16), timer_expired_delegate(FUNC(lynx_state::lynx_uart_loopback_timer),this)); | |
1636 | if (m_uart.serctl & 0x40) | |
1641 | 1637 | { |
1642 | state->m_mikey.data[0x81] |= 0x10; | |
1643 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
1644 | machine.device("maincpu")->execute().set_input_line(M65SC02_IRQ_LINE, ASSERT_LINE); | |
1638 | m_mikey.data[0x81] |= 0x10; | |
1639 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
1640 | machine().device("maincpu")->execute().set_input_line(M65SC02_IRQ_LINE, ASSERT_LINE); | |
1645 | 1641 | } |
1646 | 1642 | } |
1647 | 1643 | |
1648 | if ( | |
1644 | if (m_uart.serctl & 0x80) | |
1649 | 1645 | { |
1650 | state->m_mikey.data[0x81] |= 0x10; | |
1651 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
1652 | machine.device("maincpu")->execute().set_input_line(M65SC02_IRQ_LINE, ASSERT_LINE); | |
1646 | m_mikey.data[0x81] |= 0x10; | |
1647 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); | |
1648 | machine().device("maincpu")->execute().set_input_line(M65SC02_IRQ_LINE, ASSERT_LINE); | |
1653 | 1649 | } |
1654 | 1650 | } |
1655 | 1651 | |
r18113 | r18114 | |
1696 | 1692 | m_uart.sending = TRUE; |
1697 | 1693 | m_uart.data_to_send = data; |
1698 | 1694 | // timing not accurate, baude rate should be calculated from timer 4 backup value and clock rate |
1699 | machine().scheduler().timer_set(attotime::from_usec(11*16), FUNC(lynx_uart_timer)); | |
1695 | machine().scheduler().timer_set(attotime::from_usec(11*16), timer_expired_delegate(FUNC(lynx_state::lynx_uart_timer),this)); | |
1700 | 1696 | } |
1701 | 1697 | break; |
1702 | 1698 | } |
r18113 | r18114 | |
---|---|---|
41 | 41 | } |
42 | 42 | } |
43 | 43 | |
44 | ||
44 | TIMER_CALLBACK_MEMBER(lviv_state::lviv_reset) | |
45 | 45 | { |
46 | machine.schedule_soft_reset(); | |
46 | machine().schedule_soft_reset(); | |
47 | 47 | } |
48 | 48 | |
49 | 49 | DIRECT_UPDATE_MEMBER(lviv_state::lviv_directoverride) |
50 | 50 | { |
51 | 51 | if (ioport("RESET")->read() & 0x01) |
52 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(lviv_reset)); | |
52 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(lviv_state::lviv_reset),this)); | |
53 | 53 | return address; |
54 | 54 | } |
55 | 55 |
r18113 | r18114 | |
---|---|---|
300 | 300 | */ |
301 | 301 | |
302 | 302 | |
303 | ||
303 | TIMER_CALLBACK_MEMBER(aim65_state::aim65_printer_timer) | |
304 | 304 | { |
305 | aim65_state *state = machine.driver_data<aim65_state>(); | |
306 | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); | |
305 | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); | |
307 | 306 | |
308 | via_0->write_cb1(state->m_printer_level); | |
309 | via_0->write_cb1(!state->m_printer_level); | |
310 | state->m_printer_level ^= 1; | |
307 | via_0->write_cb1(m_printer_level); | |
308 | via_0->write_cb1(!m_printer_level); | |
309 | m_printer_level ^= 1; | |
311 | 310 | |
312 | if ( | |
311 | if (m_printer_dir) | |
313 | 312 | { |
314 | if (state->m_printer_x > 0) | |
315 | state->m_printer_x--; | |
313 | if (m_printer_x > 0) | |
314 | m_printer_x--; | |
316 | 315 | else |
317 | 316 | { |
318 | state->m_printer_dir = 0; | |
319 | state->m_printer_x++; | |
320 | state->m_printer_y++; | |
317 | m_printer_dir = 0; | |
318 | m_printer_x++; | |
319 | m_printer_y++; | |
321 | 320 | } |
322 | 321 | } |
323 | 322 | else |
324 | 323 | { |
325 | if (state->m_printer_x < 9) | |
326 | state->m_printer_x++; | |
324 | if (m_printer_x < 9) | |
325 | m_printer_x++; | |
327 | 326 | else |
328 | 327 | { |
329 | state->m_printer_dir = 1; | |
330 | state->m_printer_x--; | |
331 | state->m_printer_y++; | |
328 | m_printer_dir = 1; | |
329 | m_printer_x--; | |
330 | m_printer_y++; | |
332 | 331 | } |
333 | 332 | } |
334 | 333 | |
335 | if ( | |
334 | if (m_printer_y > 500) m_printer_y = 0; | |
336 | 335 | |
337 | state->m_flag_a=0; | |
338 | state->m_flag_b=0; | |
336 | m_flag_a=0; | |
337 | m_flag_b=0; | |
339 | 338 | } |
340 | 339 | |
341 | 340 | |
r18113 | r18114 | |
369 | 368 | |
370 | 369 | VIDEO_START_MEMBER(aim65_state,aim65) |
371 | 370 | { |
372 | m_print_timer = machine().scheduler().timer_alloc(FUNC(aim65_printer_timer)); | |
371 | m_print_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aim65_state::aim65_printer_timer),this)); | |
373 | 372 | m_printerRAM = auto_alloc_array(machine(), UINT16, (600 * 10 * 2) / 2); |
374 | 373 | memset(m_printerRAM, 0, videoram_size); |
375 | 374 | VIDEO_START_CALL_MEMBER(generic); |
r18113 | r18114 | |
---|---|---|
291 | 291 | |
292 | 292 | static emu_timer *pc_int_delay_timer; |
293 | 293 | |
294 | ||
294 | TIMER_CALLBACK_MEMBER(pc_state::pcjr_delayed_pic8259_irq) | |
295 | 295 | { |
296 | machine.firstcpu->set_input_line(0, param ? ASSERT_LINE : CLEAR_LINE); | |
296 | machine().firstcpu->set_input_line(0, param ? ASSERT_LINE : CLEAR_LINE); | |
297 | 297 | } |
298 | 298 | |
299 | 299 | static WRITE_LINE_DEVICE_HANDLER( pcjr_pic8259_set_int_line ) |
r18113 | r18114 | |
594 | 594 | } |
595 | 595 | |
596 | 596 | |
597 | ||
597 | TIMER_CALLBACK_MEMBER(pc_state::pcjr_keyb_signal_callback) | |
598 | 598 | { |
599 | 599 | pcjr_keyb.raw_keyb_data = pcjr_keyb.raw_keyb_data >> 1; |
600 | 600 | pcjr_keyb.signal_count--; |
r18113 | r18114 | |
922 | 922 | |
923 | 923 | /* check if any keys are pressed, raise IRQ1 if so */ |
924 | 924 | |
925 | ||
925 | TIMER_CALLBACK_MEMBER(pc_state::mc1502_keyb_signal_callback) | |
926 | 926 | { |
927 | pc_state *st = machine.driver_data<pc_state>(); | |
928 | 927 | UINT8 key = 0; |
929 | 928 | |
930 | key |= machine.root_device().ioport("Y1")->read(); | |
931 | key |= machine.root_device().ioport("Y2")->read(); | |
932 | key |= machine.root_device().ioport("Y3")->read(); | |
933 | key |= machine.root_device().ioport("Y4")->read(); | |
934 | key |= machine.root_device().ioport("Y5")->read(); | |
935 | key |= machine.root_device().ioport("Y6")->read(); | |
936 | key |= machine.root_device().ioport("Y7")->read(); | |
937 | key |= machine.root_device().ioport("Y8")->read(); | |
938 | key |= machine.root_device().ioport("Y9")->read(); | |
939 | key |= machine.root_device().ioport("Y10")->read(); | |
940 | key |= machine.root_device().ioport("Y11")->read(); | |
941 | key |= machine.root_device().ioport("Y12")->read(); | |
942 | DBG_LOG(1,"mc1502_k_s_c",("= %02X (%d) %s\n", key, mc1502_keyb.pulsing, | |
943 | (key || mc1502_keyb.pulsing) ? " will IRQ" : "")); | |
929 | key |= machine().root_device().ioport("Y1")->read(); | |
930 | key |= machine().root_device().ioport("Y2")->read(); | |
931 | key |= machine().root_device().ioport("Y3")->read(); | |
932 | key |= machine().root_device().ioport("Y4")->read(); | |
933 | key |= machine().root_device().ioport("Y5")->read(); | |
934 | key |= machine().root_device().ioport("Y6")->read(); | |
935 | key |= machine().root_device().ioport("Y7")->read(); | |
936 | key |= machine().root_device().ioport("Y8")->read(); | |
937 | key |= machine().root_device().ioport("Y9")->read(); | |
938 | key |= machine().root_device().ioport("Y10")->read(); | |
939 | key |= machine().root_device().ioport("Y11")->read(); | |
940 | key |= machine().root_device().ioport("Y12")->read(); | |
941 | // DBG_LOG(1,"mc1502_k_s_c",("= %02X (%d) %s\n", key, mc1502_keyb.pulsing, | |
942 | // (key || mc1502_keyb.pulsing) ? " will IRQ" : "")); | |
944 | 943 | |
945 | 944 | /* |
946 | 945 | If a key is pressed and we're not pulsing yet, start pulsing the IRQ1; |
r18113 | r18114 | |
954 | 953 | } |
955 | 954 | |
956 | 955 | if (mc1502_keyb.pulsing) { |
957 | pic8259_ir1_w( | |
956 | pic8259_ir1_w(m_pic8259, (mc1502_keyb.pulsing & 1)); | |
958 | 957 | mc1502_keyb.pulsing--; |
959 | 958 | } |
960 | 959 | } |
r18113 | r18114 | |
1486 | 1485 | */ |
1487 | 1486 | pic8259_ir1_w(m_pic8259, 1); |
1488 | 1487 | memset(&mc1502_keyb, 0, sizeof(mc1502_keyb)); |
1489 | mc1502_keyb.keyb_signal_timer = machine().scheduler().timer_alloc(FUNC(mc1502_keyb_signal_callback)); | |
1488 | mc1502_keyb.keyb_signal_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::mc1502_keyb_signal_callback),this)); | |
1490 | 1489 | mc1502_keyb.keyb_signal_timer->adjust( attotime::from_msec(20), 0, attotime::from_msec(20) ); |
1491 | 1490 | } |
1492 | 1491 | |
r18113 | r18114 | |
1494 | 1493 | MACHINE_START_MEMBER(pc_state,pcjr) |
1495 | 1494 | { |
1496 | 1495 | pc_fdc_init( machine(), &pcjr_fdc_interface_nc ); |
1497 | pcjr_keyb.keyb_signal_timer = machine().scheduler().timer_alloc(FUNC(pcjr_keyb_signal_callback)); | |
1498 | pc_int_delay_timer = machine().scheduler().timer_alloc(FUNC(pcjr_delayed_pic8259_irq)); | |
1496 | pcjr_keyb.keyb_signal_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::pcjr_keyb_signal_callback),this)); | |
1497 | pc_int_delay_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::pcjr_delayed_pic8259_irq),this)); | |
1499 | 1498 | m_maincpu = machine().device<cpu_device>("maincpu" ); |
1500 | 1499 | m_maincpu->set_irq_acknowledge_callback(pc_irq_callback); |
1501 | 1500 | |
r18113 | r18114 | |
1679 | 1678 | emu_timer *timer; |
1680 | 1679 | } pc_rtc; |
1681 | 1680 | |
1682 | ||
1681 | TIMER_CALLBACK_MEMBER(pc_state::pc_rtc_timer) | |
1683 | 1682 | { |
1684 | 1683 | int year; |
1685 | 1684 | if (++pc_rtc.data[2]>=60) { |
r18113 | r18114 | |
1704 | 1703 | |
1705 | 1704 | void pc_rtc_init(running_machine &machine) |
1706 | 1705 | { |
1706 | pc_state *state = machine.driver_data<pc_state>(); | |
1707 | 1707 | memset(&pc_rtc,0,sizeof(pc_rtc)); |
1708 | pc_rtc.timer = machine.scheduler().timer_alloc(FUNC(pc_rtc_timer)); | |
1708 | pc_rtc.timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::pc_rtc_timer),state)); | |
1709 | 1709 | pc_rtc.timer->adjust(attotime::zero, 0, attotime(1,0)); |
1710 | 1710 | } |
1711 | 1711 |
r18113 | r18114 | |
---|---|---|
278 | 278 | |
279 | 279 | *************************************************************************************/ |
280 | 280 | |
281 | ||
281 | TIMER_CALLBACK_MEMBER(kaypro_state::kaypro_timer_callback) | |
282 | 282 | { |
283 | if (machine.device("maincpu")->state().state_int(Z80_HALT)) | |
284 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); | |
283 | if (machine().device("maincpu")->state().state_int(Z80_HALT)) | |
284 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); | |
285 | 285 | } |
286 | 286 | |
287 | 287 | WRITE_LINE_MEMBER( kaypro_state::kaypro_fdc_intrq_w ) |
288 | 288 | { |
289 | 289 | if (state) |
290 | machine().scheduler().timer_set(attotime::from_usec(25), FUNC(kaypro_timer_callback)); | |
290 | machine().scheduler().timer_set(attotime::from_usec(25), timer_expired_delegate(FUNC(kaypro_state::kaypro_timer_callback),this)); | |
291 | 291 | else |
292 | 292 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, CLEAR_LINE); |
293 | 293 | } |
r18113 | r18114 | |
295 | 295 | WRITE_LINE_MEMBER( kaypro_state::kaypro_fdc_drq_w ) |
296 | 296 | { |
297 | 297 | if (state) |
298 | machine().scheduler().timer_set(attotime::from_usec(25), FUNC(kaypro_timer_callback)); | |
298 | machine().scheduler().timer_set(attotime::from_usec(25), timer_expired_delegate(FUNC(kaypro_state::kaypro_timer_callback),this)); | |
299 | 299 | else |
300 | 300 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, CLEAR_LINE); |
301 | 301 |
r18113 | r18114 | |
---|---|---|
5 | 5 | |
6 | 6 | static const int gamecom_timer_limit[8] = { 2, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }; |
7 | 7 | |
8 | ||
8 | TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_clock_timer_callback) | |
9 | 9 | { |
10 | UINT8 * RAM = machine.root_device().memregion("maincpu")->base(); | |
10 | UINT8 * RAM = machine().root_device().memregion("maincpu")->base(); | |
11 | 11 | UINT8 val = ( ( RAM[SM8521_CLKT] & 0x3F ) + 1 ) & 0x3F; |
12 | 12 | RAM[SM8521_CLKT] = ( RAM[SM8521_CLKT] & 0xC0 ) | val; |
13 | machine.device("maincpu")->execute().set_input_line(CK_INT, ASSERT_LINE ); | |
13 | machine().device("maincpu")->execute().set_input_line(CK_INT, ASSERT_LINE ); | |
14 | 14 | } |
15 | 15 | |
16 | 16 | void gamecom_state::machine_reset() |
r18113 | r18114 | |
536 | 536 | |
537 | 537 | DRIVER_INIT_MEMBER(gamecom_state,gamecom) |
538 | 538 | { |
539 | m_clock_timer = machine().scheduler().timer_alloc(FUNC(gamecom_clock_timer_callback)); | |
539 | m_clock_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamecom_state::gamecom_clock_timer_callback),this)); | |
540 | 540 | m_p_ram = memregion("maincpu")->base(); // required here because pio_w gets called before machine_reset |
541 | 541 | } |
542 | 542 |
r18113 | r18114 | |
---|---|---|
80 | 80 | Prototypes |
81 | 81 | */ |
82 | 82 | |
83 | ||
83 | ||
84 | 84 | static void gb_machine_stop(running_machine &machine); |
85 | 85 | |
86 | 86 | |
r18113 | r18114 | |
250 | 250 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gb_machine_stop),&machine())); |
251 | 251 | |
252 | 252 | /* Allocate the serial timer, and disable it */ |
253 | m_gb_serial_timer = machine().scheduler().timer_alloc(FUNC(gb_serial_timer_proc)); | |
253 | m_gb_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_serial_timer_proc),this)); | |
254 | 254 | m_gb_serial_timer->enable( 0 ); |
255 | 255 | |
256 | 256 | MACHINE_START_CALL_MEMBER( gb_video ); |
r18113 | r18114 | |
261 | 261 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gb_machine_stop),&machine())); |
262 | 262 | |
263 | 263 | /* Allocate the serial timer, and disable it */ |
264 | m_gb_serial_timer = machine().scheduler().timer_alloc(FUNC(gb_serial_timer_proc)); | |
264 | m_gb_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_serial_timer_proc),this)); | |
265 | 265 | m_gb_serial_timer->enable( 0 ); |
266 | 266 | |
267 | 267 | MACHINE_START_CALL_MEMBER( gbc_video ); |
r18113 | r18114 | |
291 | 291 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gb_machine_stop),&machine())); |
292 | 292 | |
293 | 293 | /* Allocate the serial timer, and disable it */ |
294 | m_gb_serial_timer = machine().scheduler().timer_alloc(FUNC(gb_serial_timer_proc)); | |
294 | m_gb_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_serial_timer_proc),this)); | |
295 | 295 | m_gb_serial_timer->enable( 0 ); |
296 | 296 | |
297 | 297 | MACHINE_START_CALL_MEMBER( gb_video ); |
r18113 | r18114 | |
1896 | 1896 | { |
1897 | 1897 | } |
1898 | 1898 | |
1899 | ||
1899 | TIMER_CALLBACK_MEMBER(gb_state::gb_serial_timer_proc) | |
1900 | 1900 | { |
1901 | gb_state *state = machine.driver_data<gb_state>(); | |
1902 | 1901 | /* Shift in a received bit */ |
1903 | | |
1902 | SIODATA = (SIODATA << 1) | 0x01; | |
1904 | 1903 | /* Decrement number of handled bits */ |
1905 | | |
1904 | m_SIOCount--; | |
1906 | 1905 | /* If all bits done, stop timer and trigger interrupt */ |
1907 | if ( ! | |
1906 | if ( ! m_SIOCount ) | |
1908 | 1907 | { |
1909 | state->SIOCONT &= 0x7F; | |
1910 | state->m_gb_serial_timer->enable( 0 ); | |
1911 | machine.device("maincpu")->execute().set_input_line(SIO_INT, ASSERT_LINE); | |
1908 | SIOCONT &= 0x7F; | |
1909 | m_gb_serial_timer->enable( 0 ); | |
1910 | machine().device("maincpu")->execute().set_input_line(SIO_INT, ASSERT_LINE); | |
1912 | 1911 | } |
1913 | 1912 | } |
1914 | 1913 | |
r18113 | r18114 | |
2017 | 2016 | MACHINE_START_MEMBER(gb_state,megaduck) |
2018 | 2017 | { |
2019 | 2018 | /* Allocate the serial timer, and disable it */ |
2020 | m_gb_serial_timer = machine().scheduler().timer_alloc(FUNC(gb_serial_timer_proc)); | |
2019 | m_gb_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_serial_timer_proc),this)); | |
2021 | 2020 | m_gb_serial_timer->enable( 0 ); |
2022 | 2021 | |
2023 | 2022 | MACHINE_START_CALL_MEMBER( gb_video ); |
r18113 | r18114 | |
---|---|---|
216 | 216 | machine().device("maincpu")->reset(); |
217 | 217 | } |
218 | 218 | |
219 | ||
219 | TIMER_CALLBACK_MEMBER(nes_state::nes_irq_callback) | |
220 | 220 | { |
221 | nes_state *state = machine.driver_data<nes_state>(); | |
222 | state->m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE); | |
223 | state->m_irq_timer->adjust(attotime::never); | |
221 | m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE); | |
222 | m_irq_timer->adjust(attotime::never); | |
224 | 223 | } |
225 | 224 | |
226 | 225 | static void nes_banks_restore(nes_state *state) |
r18113 | r18114 | |
309 | 308 | } |
310 | 309 | } |
311 | 310 | |
312 | m_irq_timer = machine().scheduler().timer_alloc(FUNC(nes_irq_callback)); | |
311 | m_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nes_state::nes_irq_callback),this)); | |
313 | 312 | nes_state_register(machine()); |
314 | 313 | } |
315 | 314 | |
r18113 | r18114 | |
524 | 523 | } |
525 | 524 | |
526 | 525 | |
527 | ||
526 | TIMER_CALLBACK_MEMBER(nes_state::lightgun_tick) | |
528 | 527 | { |
529 | if ((machine.root_device().ioport("CTRLSEL")->read() & 0x000f) == 0x0002) | |
528 | if ((machine().root_device().ioport("CTRLSEL")->read() & 0x000f) == 0x0002) | |
530 | 529 | { |
531 | 530 | /* enable lightpen crosshair */ |
532 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL); | |
531 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); | |
533 | 532 | } |
534 | 533 | else |
535 | 534 | { |
536 | 535 | /* disable lightpen crosshair */ |
537 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE); | |
536 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); | |
538 | 537 | } |
539 | 538 | |
540 | if ((machine.root_device().ioport("CTRLSEL")->read() & 0x00f0) == 0x0030) | |
539 | if ((machine().root_device().ioport("CTRLSEL")->read() & 0x00f0) == 0x0030) | |
541 | 540 | { |
542 | 541 | /* enable lightpen crosshair */ |
543 | crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_ALL); | |
542 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); | |
544 | 543 | } |
545 | 544 | else |
546 | 545 | { |
547 | 546 | /* disable lightpen crosshair */ |
548 | crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_NONE); | |
547 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE); | |
549 | 548 | } |
550 | 549 | } |
551 | 550 | |
r18113 | r18114 | |
554 | 553 | int cfg = ioport("CTRLSEL")->read(); |
555 | 554 | |
556 | 555 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ |
557 | machine().scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); | |
556 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(nes_state::lightgun_tick),this)); | |
558 | 557 | |
559 | 558 | if ((cfg & 0x000f) >= 0x08) // for now we treat the FC keyboard separately from other inputs! |
560 | 559 | { |
r18113 | r18114 | |
---|---|---|
129 | 129 | ************************************************************/ |
130 | 130 | |
131 | 131 | |
132 | ||
132 | TIMER_CALLBACK_MEMBER(mbee_state::mbee256_kbd) | |
133 | 133 | { |
134 | mbee_state *state = machine.driver_data<mbee_state>(); | |
135 | 134 | /* Keyboard scanner is a Mostek M3870 chip. Its speed of operation is determined by a 15k resistor on |
136 | 135 | pin 2 (XTL2) and is therefore unknown. If a key change is detected (up or down), the /strobe |
137 | 136 | line activates, sending a high to bit 1 of port 2 (one of the pio input lines). The next read of |
r18113 | r18114 | |
152 | 151 | for (i = 0; i < 15; i++) |
153 | 152 | { |
154 | 153 | sprintf(kbdrow,"X%d",i); |
155 | pressed[i] = (machine.root_device().ioport(kbdrow)->read()); | |
154 | pressed[i] = (machine().root_device().ioport(kbdrow)->read()); | |
156 | 155 | } |
157 | 156 | |
158 | 157 | /* find what has changed */ |
159 | 158 | for (i = 0; i < 15; i++) |
160 | 159 | { |
161 | if (pressed[i] != | |
160 | if (pressed[i] != m_mbee256_was_pressed[i]) | |
162 | 161 | { |
163 | 162 | /* get scankey value */ |
164 | 163 | for (j = 0; j < 8; j++) |
165 | 164 | { |
166 | if (BIT(pressed[i]^ | |
165 | if (BIT(pressed[i]^m_mbee256_was_pressed[i], j)) | |
167 | 166 | { |
168 | 167 | /* put it in the queue */ |
169 | state->m_mbee256_q[state->m_mbee256_q_pos] = (i << 3) | j | (BIT(pressed[i], j) ? 0x80 : 0); | |
170 | if (state->m_mbee256_q_pos < 19) state->m_mbee256_q_pos++; | |
168 | m_mbee256_q[m_mbee256_q_pos] = (i << 3) | j | (BIT(pressed[i], j) ? 0x80 : 0); | |
169 | if (m_mbee256_q_pos < 19) m_mbee256_q_pos++; | |
171 | 170 | } |
172 | 171 | } |
173 | | |
172 | m_mbee256_was_pressed[i] = pressed[i]; | |
174 | 173 | } |
175 | 174 | } |
176 | 175 | |
177 | 176 | /* if anything queued, cause an interrupt */ |
178 | if (state->m_mbee256_q_pos) | |
179 | state->m_mbee256_key_available = 2; // set irq | |
177 | if (m_mbee256_q_pos) | |
178 | m_mbee256_key_available = 2; // set irq | |
180 | 179 | } |
181 | 180 | |
182 | 181 | READ8_MEMBER( mbee_state::mbee256_18_r ) |
r18113 | r18114 | |
238 | 237 | return machine().device<mc146818_device>("rtc")->read(mem, 1); |
239 | 238 | } |
240 | 239 | |
241 | ||
240 | TIMER_CALLBACK_MEMBER(mbee_state::mbee_rtc_irq) | |
242 | 241 | { |
243 | mbee_state *state = machine.driver_data<mbee_state>(); | |
244 | address_space &mem = machine.device("maincpu")->memory().space(AS_IO); | |
245 | UINT8 data = machine.device<mc146818_device>("rtc")->read(mem, 12); | |
246 | if (data) state->m_clock_pulse = 0x80; | |
242 | address_space &mem = machine().device("maincpu")->memory().space(AS_IO); | |
243 | UINT8 data = machine().device<mc146818_device>("rtc")->read(mem, 12); | |
244 | if (data) m_clock_pulse = 0x80; | |
247 | 245 | } |
248 | 246 | |
249 | 247 | |
r18113 | r18114 | |
495 | 493 | |
496 | 494 | |
497 | 495 | /* after the first 4 bytes have been read from ROM, switch the ram back in */ |
498 | ||
496 | TIMER_CALLBACK_MEMBER(mbee_state::mbee_reset) | |
499 | 497 | { |
500 | mbee_state *state = machine.driver_data<mbee_state>(); | |
501 | state->membank("boot")->set_entry(0); | |
498 | membank("boot")->set_entry(0); | |
502 | 499 | } |
503 | 500 | |
504 | 501 | static void machine_reset_common_disk(running_machine &machine) |
r18113 | r18114 | |
512 | 509 | MACHINE_RESET_MEMBER(mbee_state,mbee) |
513 | 510 | { |
514 | 511 | membank("boot")->set_entry(1); |
515 | machine().scheduler().timer_set(attotime::from_usec(4), FUNC(mbee_reset)); | |
512 | machine().scheduler().timer_set(attotime::from_usec(4), timer_expired_delegate(FUNC(mbee_state::mbee_reset),this)); | |
516 | 513 | } |
517 | 514 | |
518 | 515 | MACHINE_RESET_MEMBER(mbee_state,mbee56) |
519 | 516 | { |
520 | 517 | machine_reset_common_disk(machine()); |
521 | 518 | membank("boot")->set_entry(1); |
522 | machine().scheduler().timer_set(attotime::from_usec(4), FUNC(mbee_reset)); | |
519 | machine().scheduler().timer_set(attotime::from_usec(4), timer_expired_delegate(FUNC(mbee_state::mbee_reset),this)); | |
523 | 520 | } |
524 | 521 | |
525 | 522 | MACHINE_RESET_MEMBER(mbee_state,mbee64) |
r18113 | r18114 | |
547 | 544 | m_mbee256_q_pos = 0; |
548 | 545 | mbee256_50_w(mem,0,0); // set banks to default |
549 | 546 | membank("boot")->set_entry(8); // boot time |
550 | machine().scheduler().timer_set(attotime::from_usec(4), FUNC(mbee_reset)); | |
547 | machine().scheduler().timer_set(attotime::from_usec(4), timer_expired_delegate(FUNC(mbee_state::mbee_reset),this)); | |
551 | 548 | } |
552 | 549 | |
553 | 550 | MACHINE_RESET_MEMBER(mbee_state,mbeett) |
r18113 | r18114 | |
556 | 553 | for (i = 0; i < 15; i++) m_mbee256_was_pressed[i] = 0; |
557 | 554 | m_mbee256_q_pos = 0; |
558 | 555 | membank("boot")->set_entry(1); |
559 | machine().scheduler().timer_set(attotime::from_usec(4), FUNC(mbee_reset)); | |
556 | machine().scheduler().timer_set(attotime::from_usec(4), timer_expired_delegate(FUNC(mbee_state::mbee_reset),this)); | |
560 | 557 | } |
561 | 558 | |
562 | 559 | INTERRUPT_GEN_MEMBER(mbee_state::mbee_interrupt) |
r18113 | r18114 | |
713 | 710 | membank("bank8l")->configure_entry(0, &RAM[0x0000]); // rom |
714 | 711 | membank("bank8h")->configure_entry(0, &RAM[0x0800]); // rom |
715 | 712 | |
716 | machine().scheduler().timer_pulse(attotime::from_hz(1), FUNC(mbee_rtc_irq)); /* timer for rtc */ | |
717 | machine().scheduler().timer_pulse(attotime::from_hz(25), FUNC(mbee256_kbd)); /* timer for kbd */ | |
713 | machine().scheduler().timer_pulse(attotime::from_hz(1), timer_expired_delegate(FUNC(mbee_state::mbee_rtc_irq),this)); /* timer for rtc */ | |
714 | machine().scheduler().timer_pulse(attotime::from_hz(25), timer_expired_delegate(FUNC(mbee_state::mbee256_kbd),this)); /* timer for kbd */ | |
718 | 715 | |
719 | 716 | m_size = 0x8000; |
720 | 717 | } |
r18113 | r18114 | |
733 | 730 | membank("pak")->set_entry(5); |
734 | 731 | membank("telcom")->set_entry(0); |
735 | 732 | |
736 | machine().scheduler().timer_pulse(attotime::from_hz(1), FUNC(mbee_rtc_irq)); /* timer for rtc */ | |
737 | machine().scheduler().timer_pulse(attotime::from_hz(25), FUNC(mbee256_kbd)); /* timer for kbd */ | |
733 | machine().scheduler().timer_pulse(attotime::from_hz(1), timer_expired_delegate(FUNC(mbee_state::mbee_rtc_irq),this)); /* timer for rtc */ | |
734 | machine().scheduler().timer_pulse(attotime::from_hz(25), timer_expired_delegate(FUNC(mbee_state::mbee256_kbd),this)); /* timer for kbd */ | |
738 | 735 | |
739 | 736 | m_size = 0x8000; |
740 | 737 | } |
r18113 | r18114 | |
---|---|---|
177 | 177 | static void hdc_drq(running_machine &machine); |
178 | 178 | |
179 | 179 | static void keyboard_reset(running_machine &machine); |
180 | static TIMER_CALLBACK(keyscan_callback); | |
181 | 180 | |
181 | ||
182 | 182 | static void pc8031_reset(running_machine &machine); |
183 | 183 | static void iou_reset(running_machine &machine); |
184 | 184 | static void rmni_sound_reset(running_machine &machine); |
185 | 185 | |
186 | 186 | static void mouse_js_reset(running_machine &machine); |
187 | static TIMER_CALLBACK(mouse_callback); | |
188 | 187 | |
189 | 188 | |
189 | ||
190 | 190 | /************************************* |
191 | 191 | * |
192 | 192 | * 80186 interrupt controller |
r18113 | r18114 | |
458 | 458 | * |
459 | 459 | *************************************/ |
460 | 460 | |
461 | ||
461 | TIMER_CALLBACK_MEMBER(rmnimbus_state::internal_timer_int) | |
462 | 462 | { |
463 | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); | |
464 | 463 | int which = param; |
465 | struct timer_state *t = & | |
464 | struct timer_state *t = &m_i186.timer[which]; | |
466 | 465 | |
467 | 466 | if (LOG_TIMER) logerror("Hit interrupt callback for timer %d\n", which); |
468 | 467 | |
r18113 | r18114 | |
472 | 471 | /* request an interrupt */ |
473 | 472 | if (t->control & 0x2000) |
474 | 473 | { |
475 | state->m_i186.intr.status |= 0x01 << which; | |
476 | update_interrupt_state(machine); | |
474 | m_i186.intr.status |= 0x01 << which; | |
475 | update_interrupt_state(machine()); | |
477 | 476 | if (LOG_TIMER) logerror(" Generating timer interrupt\n"); |
478 | 477 | } |
479 | 478 | |
r18113 | r18114 | |
654 | 653 | * |
655 | 654 | *************************************/ |
656 | 655 | |
657 | ||
656 | TIMER_CALLBACK_MEMBER(rmnimbus_state::dma_timer_callback) | |
658 | 657 | { |
659 | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); | |
660 | 658 | int which = param; |
661 | struct dma_state *d = & | |
659 | struct dma_state *d = &m_i186.dma[which]; | |
662 | 660 | |
663 | 661 | /* complete the status update */ |
664 | 662 | d->control &= ~0x0002; |
r18113 | r18114 | |
669 | 667 | if (d->control & 0x0100) |
670 | 668 | { |
671 | 669 | if (LOG_DMA>1) logerror("DMA%d timer callback - requesting interrupt: count = %04X, source = %04X\n", which, d->count, d->source); |
672 | state->m_i186.intr.request |= 0x04 << which; | |
673 | update_interrupt_state(machine); | |
670 | m_i186.intr.request |= 0x04 << which; | |
671 | update_interrupt_state(machine()); | |
674 | 672 | } |
675 | 673 | } |
676 | 674 | |
r18113 | r18114 | |
806 | 804 | logerror("Machine reset\n"); |
807 | 805 | |
808 | 806 | /* create timers here so they stick around */ |
809 | state->m_i186.timer[0].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
810 | state->m_i186.timer[1].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
811 | state->m_i186.timer[2].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
807 | state->m_i186.timer[0].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); | |
808 | state->m_i186.timer[1].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); | |
809 | state->m_i186.timer[2].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); | |
812 | 810 | state->m_i186.timer[0].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
813 | 811 | state->m_i186.timer[1].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
814 | 812 | state->m_i186.timer[2].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
815 | state->m_i186.dma[0].finish_timer = machine.scheduler().timer_alloc(FUNC(dma_timer_callback)); | |
816 | state->m_i186.dma[1].finish_timer = machine.scheduler().timer_alloc(FUNC(dma_timer_callback)); | |
813 | state->m_i186.dma[0].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),state)); | |
814 | state->m_i186.dma[1].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),state)); | |
817 | 815 | } |
818 | 816 | |
819 | 817 | static void nimbus_cpu_reset(running_machine &machine) |
r18113 | r18114 | |
1262 | 1260 | /* init cpu */ |
1263 | 1261 | nimbus_cpu_init(machine()); |
1264 | 1262 | |
1265 | m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(FUNC(keyscan_callback)); | |
1266 | m_nimbus_mouse.m_mouse_timer=machine().scheduler().timer_alloc(FUNC(mouse_callback)); | |
1263 | m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::keyscan_callback),this)); | |
1264 | m_nimbus_mouse.m_mouse_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::mouse_callback),this)); | |
1267 | 1265 | |
1268 | 1266 | /* setup debug commands */ |
1269 | 1267 | if (machine().debug_flags & DEBUG_FLAG_ENABLED) |
r18113 | r18114 | |
2171 | 2169 | } |
2172 | 2170 | } |
2173 | 2171 | |
2174 | ||
2172 | TIMER_CALLBACK_MEMBER(rmnimbus_state::keyscan_callback) | |
2175 | 2173 | { |
2176 | scan_keyboard(machine); | |
2174 | scan_keyboard(machine()); | |
2177 | 2175 | } |
2178 | 2176 | |
2179 | 2177 | /* |
r18113 | r18114 | |
2836 | 2834 | state->m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(1000)); |
2837 | 2835 | } |
2838 | 2836 | |
2839 | ||
2837 | TIMER_CALLBACK_MEMBER(rmnimbus_state::mouse_callback) | |
2840 | 2838 | { |
2841 | rmnimbus_state *drvstate = machine.driver_data<rmnimbus_state>(); | |
2842 | 2839 | UINT8 x = 0; |
2843 | 2840 | UINT8 y = 0; |
2844 | // int pc=machine.device(MAINCPU_TAG)->safe_pc(); | |
2841 | // int pc=machine().device(MAINCPU_TAG)->safe_pc(); | |
2845 | 2842 | |
2846 | 2843 | UINT8 intstate_x; |
2847 | 2844 | UINT8 intstate_y; |
2848 | 2845 | int xint; |
2849 | 2846 | int yint; |
2850 | 2847 | |
2851 | mouse_joy_state *state = & | |
2848 | mouse_joy_state *state = &m_nimbus_mouse; | |
2852 | 2849 | |
2853 | 2850 | |
2854 | state->m_reg0a4 = machine.root_device().ioport(MOUSE_BUTTON_TAG)->read() | 0xC0; | |
2855 | x = machine.root_device().ioport(MOUSEX_TAG)->read(); | |
2856 | y = machine.root_device().ioport(MOUSEY_TAG)->read(); | |
2851 | state->m_reg0a4 = machine().root_device().ioport(MOUSE_BUTTON_TAG)->read() | 0xC0; | |
2852 | x = machine().root_device().ioport(MOUSEX_TAG)->read(); | |
2853 | y = machine().root_device().ioport(MOUSEY_TAG)->read(); | |
2857 | 2854 | |
2858 | 2855 | UINT8 mxa; |
2859 | 2856 | UINT8 mxb; |
r18113 | r18114 | |
2923 | 2920 | // mxb,mxa, (mxb ^ mxa) , (state->m_ay8910_a & 0xC0), (mxb ^ mxa) ^ ((state->m_ay8910_a & 0x40) >> 6)); |
2924 | 2921 | } |
2925 | 2922 | |
2926 | intstate_x = (mxb ^ mxa) ^ ((drvstate->m_ay8910_a & 0x40) >> 6); | |
2927 | intstate_y = (myb ^ mya) ^ ((drvstate->m_ay8910_a & 0x80) >> 7); | |
2923 | intstate_x = (mxb ^ mxa) ^ ((m_ay8910_a & 0x40) >> 6); | |
2924 | intstate_y = (myb ^ mya) ^ ((m_ay8910_a & 0x80) >> 7); | |
2928 | 2925 | |
2929 | if (MOUSE_INT_ENABLED( | |
2926 | if (MOUSE_INT_ENABLED(this)) | |
2930 | 2927 | { |
2931 | 2928 | if ((intstate_x==1) && (state->m_intstate_x==0)) |
2932 | 2929 | // if (intstate_x!=state->m_intstate_x) |
r18113 | r18114 | |
2934 | 2931 | |
2935 | 2932 | xint=mxa ? EXTERNAL_INT_MOUSE_XR : EXTERNAL_INT_MOUSE_XL; |
2936 | 2933 | |
2937 | external_int(machine,0,xint); | |
2934 | external_int(machine(),0,xint); | |
2938 | 2935 | |
2939 | 2936 | // logerror("Xint:%02X, mxb=%02X\n",xint,mxb); |
2940 | 2937 | } |
r18113 | r18114 | |
2944 | 2941 | { |
2945 | 2942 | yint=myb ? EXTERNAL_INT_MOUSE_YU : EXTERNAL_INT_MOUSE_YD; |
2946 | 2943 | |
2947 | external_int(machine,0,yint); | |
2944 | external_int(machine(),0,yint); | |
2948 | 2945 | // logerror("Yint:%02X, myb=%02X\n",yint,myb); |
2949 | 2946 | } |
2950 | 2947 | } |
r18113 | r18114 | |
---|---|---|
22 | 22 | #define LOG_ADB 0 |
23 | 23 | #define LOG_VIA 0 |
24 | 24 | |
25 | static TIMER_CALLBACK(mac_6015_tick); | |
26 | 25 | |
26 | ||
27 | 27 | /* VIA1 Handlers */ |
28 | 28 | |
29 | 29 | static DECLARE_READ8_DEVICE_HANDLER(mac_via_in_a); |
r18113 | r18114 | |
144 | 144 | |
145 | 145 | void macpci_state::machine_start() |
146 | 146 | { |
147 | m_6015_timer = machine().scheduler().timer_alloc(FUNC(mac_6015_tick)); | |
147 | m_6015_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(macpci_state::mac_6015_tick),this)); | |
148 | 148 | m_6015_timer->adjust(attotime::never); |
149 | 149 | } |
150 | 150 | |
r18113 | r18114 | |
250 | 250 | { |
251 | 251 | } |
252 | 252 | |
253 | ||
253 | TIMER_CALLBACK_MEMBER(macpci_state::mac_6015_tick) | |
254 | 254 | { |
255 | // macpci_state *mac = machine.driver_data<macpci_state>(); | |
256 | 255 | } |
r18113 | r18114 | |
---|---|---|
13 | 13 | #include "includes/bk.h" |
14 | 14 | |
15 | 15 | |
16 | ||
16 | TIMER_CALLBACK_MEMBER(bk_state::keyboard_callback) | |
17 | 17 | { |
18 | bk_state *state = machine.driver_data<bk_state>(); | |
19 | 18 | UINT8 code, i, j; |
20 | 19 | static const char *const keynames[] = { |
21 | 20 | "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", |
r18113 | r18114 | |
24 | 23 | |
25 | 24 | for(i = 1; i < 12; i++) |
26 | 25 | { |
27 | code = machine.root_device().ioport(keynames[i-1])->read(); | |
26 | code = machine().root_device().ioport(keynames[i-1])->read(); | |
28 | 27 | if (code != 0) |
29 | 28 | { |
30 | 29 | for(j = 0; j < 8; j++) |
31 | 30 | { |
32 | 31 | if (code == (1 << j)) |
33 | 32 | { |
34 | | |
33 | m_key_code = j + i*8; | |
35 | 34 | break; |
36 | 35 | } |
37 | 36 | } |
38 | if ((machine.root_device().ioport("LINE0")->read() & 4) == 4) | |
37 | if ((machine().root_device().ioport("LINE0")->read() & 4) == 4) | |
39 | 38 | { |
40 | 39 | if (i==6 || i==7) |
41 | 40 | { |
42 | | |
41 | m_key_code -= 16; | |
43 | 42 | } |
44 | 43 | |
45 | 44 | } |
46 | if ((machine.root_device().ioport("LINE0")->read() & 4) == 4) | |
45 | if ((machine().root_device().ioport("LINE0")->read() & 4) == 4) | |
47 | 46 | { |
48 | 47 | if (i>=8 && i<=11) |
49 | 48 | { |
50 | | |
49 | m_key_code += 32; | |
51 | 50 | } |
52 | 51 | } |
53 | state->m_key_pressed = 0x40; | |
54 | if ((machine.root_device().ioport("LINE0")->read() & 2) == 0) | |
52 | m_key_pressed = 0x40; | |
53 | if ((machine().root_device().ioport("LINE0")->read() & 2) == 0) | |
55 | 54 | { |
56 | | |
55 | m_key_irq_vector = 0x30; | |
57 | 56 | } |
58 | 57 | else |
59 | 58 | { |
60 | | |
59 | m_key_irq_vector = 0xBC; | |
61 | 60 | } |
62 | machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); | |
61 | machine().device("maincpu")->execute().set_input_line(0, ASSERT_LINE); | |
63 | 62 | break; |
64 | 63 | } |
65 | 64 | } |
r18113 | r18114 | |
68 | 67 | |
69 | 68 | void bk_state::machine_start() |
70 | 69 | { |
71 | machine().scheduler().timer_pulse(attotime::from_hz(2400), FUNC(keyboard_callback)); | |
70 | machine().scheduler().timer_pulse(attotime::from_hz(2400), timer_expired_delegate(FUNC(bk_state::keyboard_callback),this)); | |
72 | 71 | } |
73 | 72 | |
74 | 73 | static IRQ_CALLBACK(bk0010_irq_callback) |
r18113 | r18114 | |
---|---|---|
158 | 158 | // for about 4.5 milliseconds every 20 milliseconds" |
159 | 159 | // |
160 | 160 | |
161 | ||
161 | TIMER_CALLBACK_MEMBER(rm380z_state::static_vblank_timer) | |
162 | 162 | { |
163 | //printf("timer callback called at [%f]\n",machine.time().as_double()); | |
163 | //printf("timer callback called at [%f]\n",machine().time().as_double()); | |
164 | 164 | |
165 | rm380z_state *state = machine.driver_data<rm380z_state>(); | |
166 | 165 | |
167 | state->m_rasterlineCtr++; | |
168 | state->m_rasterlineCtr%=(HORZ_LINES*LINE_SUBDIVISION); | |
166 | m_rasterlineCtr++; | |
167 | m_rasterlineCtr%=(HORZ_LINES*LINE_SUBDIVISION); | |
169 | 168 | |
170 | 169 | // frame blanking |
171 | if ( | |
170 | if (m_rasterlineCtr>=((HORZ_LINES-22)*LINE_SUBDIVISION)) | |
172 | 171 | { |
173 | | |
172 | m_port1|=0x40; | |
174 | 173 | } |
175 | 174 | else |
176 | 175 | { |
177 | | |
176 | m_port1&=~0x40; | |
178 | 177 | } |
179 | 178 | |
180 | 179 | // line blanking |
181 | if (( | |
180 | if ((m_rasterlineCtr%LINE_SUBDIVISION)>80) | |
182 | 181 | { |
183 | | |
182 | m_port1|=0x80; | |
184 | 183 | } |
185 | 184 | else |
186 | 185 | { |
187 | | |
186 | m_port1&=~0x80; | |
188 | 187 | } |
189 | 188 | } |
190 | 189 | |
r18113 | r18114 | |
249 | 248 | |
250 | 249 | void rm380z_state::machine_start() |
251 | 250 | { |
252 | machine().scheduler().timer_pulse(attotime::from_hz(TIMER_SPEED), FUNC(static_vblank_timer)); | |
251 | machine().scheduler().timer_pulse(attotime::from_hz(TIMER_SPEED), timer_expired_delegate(FUNC(rm380z_state::static_vblank_timer),this)); | |
253 | 252 | } |
254 | 253 | |
255 | 254 | void rm380z_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
189 | 189 | } |
190 | 190 | |
191 | 191 | |
192 | ||
192 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_seconds_timer_callback) | |
193 | 193 | { |
194 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
195 | if ( state->m_pm_reg[0x08] & 0x01 ) | |
194 | if ( m_pm_reg[0x08] & 0x01 ) | |
196 | 195 | { |
197 | state->m_pm_reg[0x09] += 1; | |
198 | if ( ! state->m_pm_reg[0x09] ) | |
196 | m_pm_reg[0x09] += 1; | |
197 | if ( ! m_pm_reg[0x09] ) | |
199 | 198 | { |
200 | state->m_pm_reg[0x0A] += 1; | |
201 | if ( ! state->m_pm_reg[0x0A] ) | |
199 | m_pm_reg[0x0A] += 1; | |
200 | if ( ! m_pm_reg[0x0A] ) | |
202 | 201 | { |
203 | | |
202 | m_pm_reg[0x0B] += 1; | |
204 | 203 | } |
205 | 204 | } |
206 | 205 | } |
207 | 206 | } |
208 | 207 | |
209 | 208 | |
210 | ||
209 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_256hz_timer_callback) | |
211 | 210 | { |
212 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
213 | if ( state->m_pm_reg[0x40] & 0x01 ) | |
211 | if ( m_pm_reg[0x40] & 0x01 ) | |
214 | 212 | { |
215 | | |
213 | m_pm_reg[0x41] += 1; | |
216 | 214 | /* Check if the 32Hz IRQ should be triggered */ |
217 | if ( ! ( | |
215 | if ( ! ( m_pm_reg[0x41] & 0x07 ) ) | |
218 | 216 | { |
219 | | |
217 | m_pm_reg[0x28] |= 0x20; | |
220 | 218 | |
221 | 219 | /* Check if the 8Hz IRQ should be triggered */ |
222 | if ( ! ( | |
220 | if ( ! ( m_pm_reg[0x41] & 0x1F ) ) | |
223 | 221 | { |
224 | | |
222 | m_pm_reg[0x28] |= 0x10; | |
225 | 223 | |
226 | 224 | /* Check if the 2Hz IRQ should be triggered */ |
227 | if ( ! ( | |
225 | if ( ! ( m_pm_reg[0x41] & 0x7F ) ) | |
228 | 226 | { |
229 | | |
227 | m_pm_reg[0x28] |= 0x08; | |
230 | 228 | |
231 | 229 | /* Check if the 1Hz IRQ should be triggered */ |
232 | if ( ! | |
230 | if ( ! m_pm_reg[0x41] ) | |
233 | 231 | { |
234 | | |
232 | m_pm_reg[0x28] |= 0x04; | |
235 | 233 | } |
236 | 234 | } |
237 | 235 | } |
238 | 236 | |
239 | pokemini_check_irqs( machine ); | |
237 | pokemini_check_irqs( machine() ); | |
240 | 238 | } |
241 | 239 | } |
242 | 240 | } |
243 | 241 | |
244 | 242 | |
245 | ||
243 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer1_callback) | |
246 | 244 | { |
247 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
248 | state->m_pm_reg[0x36] -= 1; | |
245 | m_pm_reg[0x36] -= 1; | |
249 | 246 | /* Check for underflow of timer */ |
250 | if ( | |
247 | if ( m_pm_reg[0x36] == 0xFF ) | |
251 | 248 | { |
252 | 249 | /* Check if timer1 is running in 16bit mode */ |
253 | if ( | |
250 | if ( m_pm_reg[0x30] & 0x80 ) | |
254 | 251 | { |
255 | state->m_pm_reg[0x37] -= 1; | |
256 | if ( state->m_pm_reg[0x37] == 0xFF ) | |
252 | m_pm_reg[0x37] -= 1; | |
253 | if ( m_pm_reg[0x37] == 0xFF ) | |
257 | 254 | { |
258 | state->m_pm_reg[0x27] |= 0x08; | |
259 | pokemini_check_irqs( machine ); | |
260 | state->m_pm_reg[0x36] = state->m_pm_reg[0x32]; | |
261 | state->m_pm_reg[0x37] = state->m_pm_reg[0x33]; | |
255 | m_pm_reg[0x27] |= 0x08; | |
256 | pokemini_check_irqs( machine() ); | |
257 | m_pm_reg[0x36] = m_pm_reg[0x32]; | |
258 | m_pm_reg[0x37] = m_pm_reg[0x33]; | |
262 | 259 | } |
263 | 260 | } |
264 | 261 | else |
265 | 262 | { |
266 | state->m_pm_reg[0x27] |= 0x04; | |
267 | pokemini_check_irqs( machine ); | |
268 | state->m_pm_reg[0x36] = state->m_pm_reg[0x32]; | |
263 | m_pm_reg[0x27] |= 0x04; | |
264 | pokemini_check_irqs( machine() ); | |
265 | m_pm_reg[0x36] = m_pm_reg[0x32]; | |
269 | 266 | } |
270 | 267 | } |
271 | 268 | } |
272 | 269 | |
273 | 270 | |
274 | ||
271 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer1_hi_callback) | |
275 | 272 | { |
276 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
277 | state->m_pm_reg[0x37] -= 1; | |
273 | m_pm_reg[0x37] -= 1; | |
278 | 274 | /* Check for underflow of timer */ |
279 | if ( | |
275 | if ( m_pm_reg[0x37] == 0xFF ) | |
280 | 276 | { |
281 | state->m_pm_reg[0x27] |= 0x08; | |
282 | pokemini_check_irqs( machine ); | |
283 | state->m_pm_reg[0x37] = state->m_pm_reg[0x33]; | |
277 | m_pm_reg[0x27] |= 0x08; | |
278 | pokemini_check_irqs( machine() ); | |
279 | m_pm_reg[0x37] = m_pm_reg[0x33]; | |
284 | 280 | } |
285 | 281 | } |
286 | 282 | |
287 | 283 | |
288 | ||
284 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer2_callback) | |
289 | 285 | { |
290 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
291 | state->m_pm_reg[0x3E] -= 1; | |
286 | m_pm_reg[0x3E] -= 1; | |
292 | 287 | /* Check for underflow of timer */ |
293 | if ( | |
288 | if ( m_pm_reg[0x3E] == 0xFF ) | |
294 | 289 | { |
295 | 290 | /* Check if timer2 is running in 16bit mode */ |
296 | if ( | |
291 | if ( m_pm_reg[0x38] & 0x80 ) | |
297 | 292 | { |
298 | state->m_pm_reg[0x3F] -= 1; | |
299 | if ( state->m_pm_reg[0x3F] == 0xFF ) | |
293 | m_pm_reg[0x3F] -= 1; | |
294 | if ( m_pm_reg[0x3F] == 0xFF ) | |
300 | 295 | { |
301 | state->m_pm_reg[0x27] |= 0x20; | |
302 | pokemini_check_irqs( machine ); | |
303 | state->m_pm_reg[0x3E] = state->m_pm_reg[0x3A]; | |
304 | state->m_pm_reg[0x3F] = state->m_pm_reg[0x3B]; | |
296 | m_pm_reg[0x27] |= 0x20; | |
297 | pokemini_check_irqs( machine() ); | |
298 | m_pm_reg[0x3E] = m_pm_reg[0x3A]; | |
299 | m_pm_reg[0x3F] = m_pm_reg[0x3B]; | |
305 | 300 | } |
306 | 301 | } |
307 | 302 | else |
308 | 303 | { |
309 | state->m_pm_reg[0x27] |= 0x10; | |
310 | pokemini_check_irqs( machine ); | |
311 | state->m_pm_reg[0x3E] = state->m_pm_reg[0x3A]; | |
304 | m_pm_reg[0x27] |= 0x10; | |
305 | pokemini_check_irqs( machine() ); | |
306 | m_pm_reg[0x3E] = m_pm_reg[0x3A]; | |
312 | 307 | } |
313 | 308 | } |
314 | 309 | } |
315 | 310 | |
316 | 311 | |
317 | ||
312 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer2_hi_callback) | |
318 | 313 | { |
319 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
320 | state->m_pm_reg[0x3F] -= 1; | |
314 | m_pm_reg[0x3F] -= 1; | |
321 | 315 | /* Check for underfow of timer */ |
322 | if ( | |
316 | if ( m_pm_reg[0x3F] == 0xFF ) | |
323 | 317 | { |
324 | state->m_pm_reg[0x27] |= 0x20; | |
325 | pokemini_check_irqs( machine ); | |
326 | state->m_pm_reg[0x3F] = state->m_pm_reg[0x3B]; | |
318 | m_pm_reg[0x27] |= 0x20; | |
319 | pokemini_check_irqs( machine() ); | |
320 | m_pm_reg[0x3F] = m_pm_reg[0x3B]; | |
327 | 321 | } |
328 | 322 | } |
329 | 323 | |
330 | 324 | |
331 | ||
325 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer3_callback) | |
332 | 326 | { |
333 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
334 | state->m_pm_reg[0x4E] -= 1; | |
327 | m_pm_reg[0x4E] -= 1; | |
335 | 328 | /* Check for underflow of timer */ |
336 | if ( | |
329 | if ( m_pm_reg[0x4E] == 0xFF ) | |
337 | 330 | { |
338 | 331 | /* Check if timer3 is running in 16bit mode */ |
339 | if ( | |
332 | if ( m_pm_reg[0x48] & 0x80 ) | |
340 | 333 | { |
341 | state->m_pm_reg[0x4F] -= 1; | |
342 | if ( state->m_pm_reg[0x4F] == 0xFF ) | |
334 | m_pm_reg[0x4F] -= 1; | |
335 | if ( m_pm_reg[0x4F] == 0xFF ) | |
343 | 336 | { |
344 | state->m_pm_reg[0x27] |= 0x02; | |
345 | pokemini_check_irqs( machine ); | |
346 | state->m_pm_reg[0x4E] = state->m_pm_reg[0x4A]; | |
347 | state->m_pm_reg[0x4F] = state->m_pm_reg[0x4B]; | |
337 | m_pm_reg[0x27] |= 0x02; | |
338 | pokemini_check_irqs( machine() ); | |
339 | m_pm_reg[0x4E] = m_pm_reg[0x4A]; | |
340 | m_pm_reg[0x4F] = m_pm_reg[0x4B]; | |
348 | 341 | } |
349 | 342 | } |
350 | 343 | else |
351 | 344 | { |
352 | | |
345 | m_pm_reg[0x4E] = m_pm_reg[0x4A]; | |
353 | 346 | } |
354 | 347 | } |
355 | 348 | |
356 | if ( | |
349 | if ( m_pm_reg[0x48] & 0x80 ) | |
357 | 350 | { |
358 | if ( ( | |
351 | if ( ( m_pm_reg[0x4E] == m_pm_reg[0x4C] ) && ( m_pm_reg[0x4F] == m_pm_reg[0x4D] ) ) | |
359 | 352 | { |
360 | state->m_pm_reg[0x27] |= 0x01; | |
361 | pokemini_check_irqs( machine ); | |
353 | m_pm_reg[0x27] |= 0x01; | |
354 | pokemini_check_irqs( machine() ); | |
362 | 355 | } |
363 | pokemini_update_sound( machine ); | |
356 | pokemini_update_sound( machine() ); | |
364 | 357 | } |
365 | 358 | } |
366 | 359 | |
367 | 360 | |
368 | ||
361 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_timer3_hi_callback) | |
369 | 362 | { |
370 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
371 | state->m_pm_reg[0x4F] -= 1; | |
363 | m_pm_reg[0x4F] -= 1; | |
372 | 364 | /* Check for underflow of timer */ |
373 | if ( | |
365 | if ( m_pm_reg[0x4F] == 0xFF ) | |
374 | 366 | { |
375 | state->m_pm_reg[0x27] |= 0x02; | |
376 | pokemini_check_irqs( machine ); | |
377 | state->m_pm_reg[0x4F] = state->m_pm_reg[0x4B]; | |
367 | m_pm_reg[0x27] |= 0x02; | |
368 | pokemini_check_irqs( machine() ); | |
369 | m_pm_reg[0x4F] = m_pm_reg[0x4B]; | |
378 | 370 | } |
379 | 371 | |
380 | if ( ! ( | |
372 | if ( ! ( m_pm_reg[0x48] & 0x80 ) ) | |
381 | 373 | { |
382 | if( | |
374 | if( m_pm_reg[0x4F] == m_pm_reg[0x4D] ) | |
383 | 375 | { |
384 | state->m_pm_reg[0x27] |= 0x01; | |
385 | pokemini_check_irqs( machine ); | |
376 | m_pm_reg[0x27] |= 0x01; | |
377 | pokemini_check_irqs( machine() ); | |
386 | 378 | } |
387 | pokemini_update_sound( machine ); | |
379 | pokemini_update_sound( machine() ); | |
388 | 380 | } |
389 | 381 | } |
390 | 382 | |
r18113 | r18114 | |
1413 | 1405 | } |
1414 | 1406 | |
1415 | 1407 | |
1416 | ||
1408 | TIMER_CALLBACK_MEMBER(pokemini_state::pokemini_prc_counter_callback) | |
1417 | 1409 | { |
1418 | pokemini_state *state = machine.driver_data<pokemini_state>(); | |
1419 | address_space &space = machine.device( "maincpu")->memory().space( AS_PROGRAM ); | |
1420 | state->m_prc.count++; | |
1410 | address_space &space = machine().device( "maincpu")->memory().space( AS_PROGRAM ); | |
1411 | m_prc.count++; | |
1421 | 1412 | |
1422 | 1413 | /* Check for overflow */ |
1423 | if ( | |
1414 | if ( m_prc.count >= 0x42 ) | |
1424 | 1415 | { |
1425 | state->m_prc.count = 0; | |
1426 | state->m_prc.frame_count++; | |
1416 | m_prc.count = 0; | |
1417 | m_prc.frame_count++; | |
1427 | 1418 | } |
1428 | 1419 | else |
1429 | 1420 | { |
1430 | if ( | |
1421 | if ( m_prc.count == 0x18 && m_prc.frame_count >= m_prc.max_frame_count ) | |
1431 | 1422 | { |
1432 | | |
1423 | m_prc.frame_count = 0; | |
1433 | 1424 | |
1434 | 1425 | /* Check if the background should be drawn */ |
1435 | if ( | |
1426 | if ( m_prc.background_enabled ) | |
1436 | 1427 | { |
1437 | 1428 | int x, y; |
1438 | 1429 | for ( y = 0; y < 8; y++ ) { |
1439 | 1430 | for ( x = 0; x < 12; x++ ) { |
1440 | UINT8 tile = | |
1431 | UINT8 tile = m_p_ram[ 0x360 + ( y * m_prc.map_size_x ) + x ]; | |
1441 | 1432 | int i; |
1442 | 1433 | for( i = 0; i < 8; i++ ) { |
1443 | | |
1434 | m_p_ram[ ( y * 96 ) + ( x * 8 ) + i ] = space.read_byte( m_prc.bg_tiles + ( tile * 8 ) + i ); | |
1444 | 1435 | } |
1445 | 1436 | } |
1446 | 1437 | } |
1447 | 1438 | } |
1448 | 1439 | |
1449 | 1440 | /* Check if the sprites should be drawn */ |
1450 | if ( | |
1441 | if ( m_prc.sprites_enabled ) | |
1451 | 1442 | { |
1452 | 1443 | UINT16 spr; |
1453 | 1444 | |
1454 | 1445 | for ( spr = 0x35C; spr >= 0x300; spr -= 4 ) |
1455 | 1446 | { |
1456 | int spr_x = ( state->m_p_ram[ spr + 0 ] & 0x7F ) - 16; | |
1457 | int spr_y = ( state->m_p_ram[ spr + 1 ] & 0x7F ) - 16; | |
1458 | UINT8 spr_tile = state->m_p_ram[ spr + 2 ]; | |
1459 | UINT8 spr_flag = state->m_p_ram[ spr + 3 ]; | |
1447 | int spr_x = ( m_p_ram[ spr + 0 ] & 0x7F ) - 16; | |
1448 | int spr_y = ( m_p_ram[ spr + 1 ] & 0x7F ) - 16; | |
1449 | UINT8 spr_tile = m_p_ram[ spr + 2 ]; | |
1450 | UINT8 spr_flag = m_p_ram[ spr + 3 ]; | |
1460 | 1451 | |
1461 | 1452 | if ( spr_flag & 0x08 ) |
1462 | 1453 | { |
1463 | 1454 | UINT16 gfx, mask; |
1464 | UINT32 spr_base = | |
1455 | UINT32 spr_base = m_prc.spr_tiles + spr_tile * 64; | |
1465 | 1456 | int i, j; |
1466 | 1457 | |
1467 | 1458 | for ( i = 0; i < 16; i++ ) |
r18113 | r18114 | |
1490 | 1481 | { |
1491 | 1482 | if ( mask & 0x8000 ) |
1492 | 1483 | { |
1493 | | |
1484 | m_p_ram[ ram_addr ] &= ~ ( 1 << ( ( spr_y + j ) & 0x07 ) ); | |
1494 | 1485 | if ( gfx & 0x8000 ) |
1495 | 1486 | { |
1496 | | |
1487 | m_p_ram[ ram_addr ] |= ( 1 << ( ( spr_y + j ) & 0x07 ) ); | |
1497 | 1488 | } |
1498 | 1489 | } |
1499 | 1490 | mask <<= 1; |
r18113 | r18114 | |
1503 | 1494 | { |
1504 | 1495 | if ( mask & 0x0001 ) |
1505 | 1496 | { |
1506 | | |
1497 | m_p_ram[ ram_addr ] &= ~ ( 1 << ( ( spr_y + j ) & 0x07 ) ); | |
1507 | 1498 | if ( gfx & 0x0001 ) |
1508 | 1499 | { |
1509 | | |
1500 | m_p_ram[ ram_addr ] |= ( 1 << ( ( spr_y + j ) & 0x07 ) ); | |
1510 | 1501 | } |
1511 | 1502 | } |
1512 | 1503 | mask >>= 1; |
r18113 | r18114 | |
1521 | 1512 | } |
1522 | 1513 | |
1523 | 1514 | /* Set PRC Render interrupt */ |
1524 | state->m_pm_reg[0x27] |= 0x40; | |
1525 | pokemini_check_irqs( machine ); | |
1515 | m_pm_reg[0x27] |= 0x40; | |
1516 | pokemini_check_irqs( machine() ); | |
1526 | 1517 | |
1527 | 1518 | /* Check if the rendered data should be copied to the LCD */ |
1528 | if ( | |
1519 | if ( m_prc.copy_enabled ) | |
1529 | 1520 | { |
1530 | 1521 | int x, y; |
1531 | 1522 | |
1532 | 1523 | for( y = 0; y < 64; y += 8 ) { |
1533 | 1524 | for( x = 0; x < 96; x++ ) { |
1534 | UINT8 data = | |
1525 | UINT8 data = m_p_ram[ ( y * 12 ) + x ]; | |
1535 | 1526 | |
1536 | state->m_bitmap.pix16(y + 0, x) = ( data & 0x01 ) ? 3 : 0; | |
1537 | state->m_bitmap.pix16(y + 1, x) = ( data & 0x02 ) ? 3 : 0; | |
1538 | state->m_bitmap.pix16(y + 2, x) = ( data & 0x04 ) ? 3 : 0; | |
1539 | state->m_bitmap.pix16(y + 3, x) = ( data & 0x08 ) ? 3 : 0; | |
1540 | state->m_bitmap.pix16(y + 4, x) = ( data & 0x10 ) ? 3 : 0; | |
1541 | state->m_bitmap.pix16(y + 5, x) = ( data & 0x20 ) ? 3 : 0; | |
1542 | state->m_bitmap.pix16(y + 6, x) = ( data & 0x40 ) ? 3 : 0; | |
1543 | state->m_bitmap.pix16(y + 7, x) = ( data & 0x80 ) ? 3 : 0; | |
1527 | m_bitmap.pix16(y + 0, x) = ( data & 0x01 ) ? 3 : 0; | |
1528 | m_bitmap.pix16(y + 1, x) = ( data & 0x02 ) ? 3 : 0; | |
1529 | m_bitmap.pix16(y + 2, x) = ( data & 0x04 ) ? 3 : 0; | |
1530 | m_bitmap.pix16(y + 3, x) = ( data & 0x08 ) ? 3 : 0; | |
1531 | m_bitmap.pix16(y + 4, x) = ( data & 0x10 ) ? 3 : 0; | |
1532 | m_bitmap.pix16(y + 5, x) = ( data & 0x20 ) ? 3 : 0; | |
1533 | m_bitmap.pix16(y + 6, x) = ( data & 0x40 ) ? 3 : 0; | |
1534 | m_bitmap.pix16(y + 7, x) = ( data & 0x80 ) ? 3 : 0; | |
1544 | 1535 | } |
1545 | 1536 | } |
1546 | 1537 | |
1547 | 1538 | /* Set PRC Copy interrupt */ |
1548 | state->m_pm_reg[0x27] |= 0x80; | |
1549 | pokemini_check_irqs( machine ); | |
1539 | m_pm_reg[0x27] |= 0x80; | |
1540 | pokemini_check_irqs( machine() ); | |
1550 | 1541 | } |
1551 | 1542 | } |
1552 | 1543 | |
1553 | 1544 | /* Set possible input irqs */ |
1554 | | |
1545 | m_pm_reg[0x29] |= ~ machine().root_device().ioport( "INPUTS" )->read(); | |
1555 | 1546 | } |
1556 | 1547 | } |
1557 | 1548 | |
r18113 | r18114 | |
1564 | 1555 | memset( m_pm_reg, 0, sizeof(m_pm_reg) ); |
1565 | 1556 | |
1566 | 1557 | /* Set up timers */ |
1567 | m_timers.seconds_timer = machine().scheduler().timer_alloc(FUNC(pokemini_seconds_timer_callback)); | |
1558 | m_timers.seconds_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_seconds_timer_callback),this)); | |
1568 | 1559 | m_timers.seconds_timer->adjust( attotime::zero, 0, attotime::from_seconds( 1 ) ); |
1569 | 1560 | |
1570 | m_timers.hz256_timer = machine().scheduler().timer_alloc(FUNC(pokemini_256hz_timer_callback)); | |
1561 | m_timers.hz256_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_256hz_timer_callback),this)); | |
1571 | 1562 | m_timers.hz256_timer->adjust( attotime::zero, 0, attotime::from_hz( 256 ) ); |
1572 | 1563 | |
1573 | m_timers.timer1 = machine().scheduler().timer_alloc(FUNC(pokemini_timer1_callback)); | |
1574 | m_timers.timer1_hi = machine().scheduler().timer_alloc(FUNC(pokemini_timer1_hi_callback)); | |
1575 | m_timers.timer2 = machine().scheduler().timer_alloc(FUNC(pokemini_timer2_callback)); | |
1576 | m_timers.timer2_hi = machine().scheduler().timer_alloc(FUNC(pokemini_timer2_hi_callback)); | |
1577 | m_timers.timer3 = machine().scheduler().timer_alloc(FUNC(pokemini_timer3_callback)); | |
1578 | m_timers.timer3_hi = machine().scheduler().timer_alloc(FUNC(pokemini_timer3_hi_callback)); | |
1564 | m_timers.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer1_callback),this)); | |
1565 | m_timers.timer1_hi = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer1_hi_callback),this)); | |
1566 | m_timers.timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer2_callback),this)); | |
1567 | m_timers.timer2_hi = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer2_hi_callback),this)); | |
1568 | m_timers.timer3 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer3_callback),this)); | |
1569 | m_timers.timer3_hi = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_timer3_hi_callback),this)); | |
1579 | 1570 | |
1580 | 1571 | /* Set up the PRC */ |
1581 | 1572 | m_prc.max_frame_count = 2; |
1582 | m_prc.count_timer = machine().scheduler().timer_alloc(FUNC(pokemini_prc_counter_callback)); | |
1573 | m_prc.count_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pokemini_state::pokemini_prc_counter_callback),this)); | |
1583 | 1574 | m_prc.count_timer->adjust( attotime::zero, 0, m_maincpu->cycles_to_attotime(55640 / 65) ); |
1584 | 1575 | } |
1585 | 1576 |
r18113 | r18114 | |
---|---|---|
90 | 90 | m_tape_bit = 0x80; |
91 | 91 | } |
92 | 92 | |
93 | ||
93 | TIMER_CALLBACK_MEMBER(zx_state::zx_tape_pulse) | |
94 | 94 | { |
95 | zx_state *state = machine.driver_data<zx_state>(); | |
96 | state->m_tape_bit = 0x80; | |
95 | m_tape_bit = 0x80; | |
97 | 96 | } |
98 | 97 | |
99 | 98 | READ8_MEMBER( zx_state::zx80_io_r ) |
r18113 | r18114 | |
138 | 137 | if (((machine().device<cassette_image_device>(CASSETTE_TAG))->input() < -0.75) && m_tape_bit) |
139 | 138 | { |
140 | 139 | m_tape_bit = 0x00; |
141 | machine().scheduler().timer_set(attotime::from_usec(362), FUNC(zx_tape_pulse)); | |
140 | machine().scheduler().timer_set(attotime::from_usec(362), timer_expired_delegate(FUNC(zx_state::zx_tape_pulse),this)); | |
142 | 141 | } |
143 | 142 | |
144 | 143 | data &= ~m_tape_bit; |
r18113 | r18114 | |
195 | 194 | if (((machine().device<cassette_image_device>(CASSETTE_TAG))->input() < -0.75) && m_tape_bit) |
196 | 195 | { |
197 | 196 | m_tape_bit = 0x00; |
198 | machine().scheduler().timer_set(attotime::from_usec(362), FUNC(zx_tape_pulse)); | |
197 | machine().scheduler().timer_set(attotime::from_usec(362), timer_expired_delegate(FUNC(zx_state::zx_tape_pulse),this)); | |
199 | 198 | } |
200 | 199 | |
201 | 200 | data &= ~m_tape_bit; |
r18113 | r18114 | |
259 | 258 | if (((machine().device<cassette_image_device>(CASSETTE_TAG))->input() < -0.75) && m_tape_bit) |
260 | 259 | { |
261 | 260 | m_tape_bit = 0x00; |
262 | machine().scheduler().timer_set(attotime::from_usec(362), FUNC(zx_tape_pulse)); | |
261 | machine().scheduler().timer_set(attotime::from_usec(362), timer_expired_delegate(FUNC(zx_state::zx_tape_pulse),this)); | |
263 | 262 | } |
264 | 263 | |
265 | 264 | data &= ~m_tape_bit; |
r18113 | r18114 | |
328 | 327 | if (((machine().device<cassette_image_device>(CASSETTE_TAG))->input() < -0.75) && m_tape_bit) |
329 | 328 | { |
330 | 329 | m_tape_bit = 0x00; |
331 | machine().scheduler().timer_set(attotime::from_usec(362), FUNC(zx_tape_pulse)); | |
330 | machine().scheduler().timer_set(attotime::from_usec(362), timer_expired_delegate(FUNC(zx_state::zx_tape_pulse),this)); | |
332 | 331 | } |
333 | 332 | |
334 | 333 | data &= ~m_tape_bit; |
r18113 | r18114 | |
---|---|---|
103 | 103 | /* prototypes */ |
104 | 104 | static void pce_cd_init( running_machine &machine ); |
105 | 105 | static void pce_cd_set_irq_line( running_machine &machine, int num, int state ); |
106 | static TIMER_CALLBACK( pce_cd_adpcm_dma_timer_callback ); | |
107 | static TIMER_CALLBACK( pce_cd_cdda_fadeout_callback ); | |
108 | static TIMER_CALLBACK( pce_cd_cdda_fadein_callback ); | |
109 | static TIMER_CALLBACK( pce_cd_adpcm_fadeout_callback ); | |
110 | static TIMER_CALLBACK( pce_cd_adpcm_fadein_callback ); | |
111 | 106 | |
107 | ||
108 | ||
109 | ||
110 | ||
111 | ||
112 | 112 | WRITE8_MEMBER(pce_state::pce_sf2_banking_w) |
113 | 113 | { |
114 | 114 | membank( "bank2" )->set_base( memregion("user1")->base() + offset * 0x080000 + 0x080000 ); |
r18113 | r18114 | |
1118 | 1118 | } |
1119 | 1119 | } |
1120 | 1120 | |
1121 | ||
1121 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_data_timer_callback) | |
1122 | 1122 | { |
1123 | pce_state *state = machine.driver_data<pce_state>(); | |
1124 | pce_cd_t &pce_cd = state->m_cd; | |
1123 | pce_cd_t &pce_cd = m_cd; | |
1125 | 1124 | if ( pce_cd.data_buffer_index == pce_cd.data_buffer_size ) |
1126 | 1125 | { |
1127 | 1126 | /* Read next data sector */ |
r18113 | r18114 | |
1208 | 1207 | } |
1209 | 1208 | } |
1210 | 1209 | |
1211 | pce_cd.data_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_data_timer_callback)); | |
1210 | pce_cd.data_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_data_timer_callback),state)); | |
1212 | 1211 | pce_cd.data_timer->adjust(attotime::never); |
1213 | pce_cd.adpcm_dma_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_adpcm_dma_timer_callback)); | |
1212 | pce_cd.adpcm_dma_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_adpcm_dma_timer_callback),state)); | |
1214 | 1213 | pce_cd.adpcm_dma_timer->adjust(attotime::never); |
1215 | 1214 | |
1216 | pce_cd.cdda_fadeout_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_cdda_fadeout_callback)); | |
1215 | pce_cd.cdda_fadeout_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_cdda_fadeout_callback),state)); | |
1217 | 1216 | pce_cd.cdda_fadeout_timer->adjust(attotime::never); |
1218 | pce_cd.cdda_fadein_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_cdda_fadein_callback)); | |
1217 | pce_cd.cdda_fadein_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_cdda_fadein_callback),state)); | |
1219 | 1218 | pce_cd.cdda_fadein_timer->adjust(attotime::never); |
1220 | 1219 | |
1221 | pce_cd.adpcm_fadeout_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_adpcm_fadeout_callback)); | |
1220 | pce_cd.adpcm_fadeout_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_adpcm_fadeout_callback),state)); | |
1222 | 1221 | pce_cd.adpcm_fadeout_timer->adjust(attotime::never); |
1223 | pce_cd.adpcm_fadein_timer = machine.scheduler().timer_alloc(FUNC(pce_cd_adpcm_fadein_callback)); | |
1222 | pce_cd.adpcm_fadein_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pce_state::pce_cd_adpcm_fadein_callback),state)); | |
1224 | 1223 | pce_cd.adpcm_fadein_timer->adjust(attotime::never); |
1225 | 1224 | } |
1226 | 1225 | |
r18113 | r18114 | |
1249 | 1248 | } |
1250 | 1249 | } |
1251 | 1250 | |
1252 | ||
1251 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_cdda_fadeout_callback) | |
1253 | 1252 | { |
1254 | pce_state *state = machine.driver_data<pce_state>(); | |
1255 | pce_cd_t &pce_cd = state->m_cd; | |
1253 | pce_cd_t &pce_cd = m_cd; | |
1256 | 1254 | pce_cd.cdda_volume-= 0.1; |
1257 | 1255 | |
1258 | 1256 | if(pce_cd.cdda_volume <= 0) |
1259 | 1257 | { |
1260 | 1258 | pce_cd.cdda_volume = 0.0; |
1261 | cdda_set_volume(machine.device("cdda"), 0.0); | |
1259 | cdda_set_volume(machine().device("cdda"), 0.0); | |
1262 | 1260 | pce_cd.cdda_fadeout_timer->adjust(attotime::never); |
1263 | 1261 | } |
1264 | 1262 | else |
1265 | 1263 | { |
1266 | cdda_set_volume(machine.device("cdda"), pce_cd.cdda_volume); | |
1264 | cdda_set_volume(machine().device("cdda"), pce_cd.cdda_volume); | |
1267 | 1265 | pce_cd.cdda_fadeout_timer->adjust(attotime::from_usec(param), param); |
1268 | 1266 | } |
1269 | 1267 | } |
1270 | 1268 | |
1271 | ||
1269 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_cdda_fadein_callback) | |
1272 | 1270 | { |
1273 | pce_state *state = machine.driver_data<pce_state>(); | |
1274 | pce_cd_t &pce_cd = state->m_cd; | |
1271 | pce_cd_t &pce_cd = m_cd; | |
1275 | 1272 | pce_cd.cdda_volume+= 0.1; |
1276 | 1273 | |
1277 | 1274 | if(pce_cd.cdda_volume >= 100.0) |
1278 | 1275 | { |
1279 | 1276 | pce_cd.cdda_volume = 100.0; |
1280 | cdda_set_volume(machine.device("cdda"), 100.0); | |
1277 | cdda_set_volume(machine().device("cdda"), 100.0); | |
1281 | 1278 | pce_cd.cdda_fadein_timer->adjust(attotime::never); |
1282 | 1279 | } |
1283 | 1280 | else |
1284 | 1281 | { |
1285 | cdda_set_volume(machine.device("cdda"), pce_cd.cdda_volume); | |
1282 | cdda_set_volume(machine().device("cdda"), pce_cd.cdda_volume); | |
1286 | 1283 | pce_cd.cdda_fadein_timer->adjust(attotime::from_usec(param), param); |
1287 | 1284 | } |
1288 | 1285 | } |
1289 | 1286 | |
1290 | ||
1287 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_adpcm_fadeout_callback) | |
1291 | 1288 | { |
1292 | pce_state *state = machine.driver_data<pce_state>(); | |
1293 | pce_cd_t &pce_cd = state->m_cd; | |
1289 | pce_cd_t &pce_cd = m_cd; | |
1294 | 1290 | pce_cd.adpcm_volume-= 0.1; |
1295 | 1291 | |
1296 | 1292 | if(pce_cd.adpcm_volume <= 0) |
1297 | 1293 | { |
1298 | 1294 | pce_cd.adpcm_volume = 0.0; |
1299 | msm5205_set_volume(machine.device("msm5205"), 0.0); | |
1295 | msm5205_set_volume(machine().device("msm5205"), 0.0); | |
1300 | 1296 | pce_cd.adpcm_fadeout_timer->adjust(attotime::never); |
1301 | 1297 | } |
1302 | 1298 | else |
1303 | 1299 | { |
1304 | msm5205_set_volume(machine.device("msm5205"), pce_cd.adpcm_volume); | |
1300 | msm5205_set_volume(machine().device("msm5205"), pce_cd.adpcm_volume); | |
1305 | 1301 | pce_cd.adpcm_fadeout_timer->adjust(attotime::from_usec(param), param); |
1306 | 1302 | } |
1307 | 1303 | } |
1308 | 1304 | |
1309 | ||
1305 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_adpcm_fadein_callback) | |
1310 | 1306 | { |
1311 | pce_state *state = machine.driver_data<pce_state>(); | |
1312 | pce_cd_t &pce_cd = state->m_cd; | |
1307 | pce_cd_t &pce_cd = m_cd; | |
1313 | 1308 | pce_cd.adpcm_volume+= 0.1; |
1314 | 1309 | |
1315 | 1310 | if(pce_cd.adpcm_volume >= 100.0) |
1316 | 1311 | { |
1317 | 1312 | pce_cd.adpcm_volume = 100.0; |
1318 | msm5205_set_volume(machine.device("msm5205"), 100.0); | |
1313 | msm5205_set_volume(machine().device("msm5205"), 100.0); | |
1319 | 1314 | pce_cd.adpcm_fadein_timer->adjust(attotime::never); |
1320 | 1315 | } |
1321 | 1316 | else |
1322 | 1317 | { |
1323 | msm5205_set_volume(machine.device("msm5205"), pce_cd.adpcm_volume); | |
1318 | msm5205_set_volume(machine().device("msm5205"), pce_cd.adpcm_volume); | |
1324 | 1319 | pce_cd.adpcm_fadein_timer->adjust(attotime::from_usec(param), param); |
1325 | 1320 | } |
1326 | 1321 | } |
r18113 | r18114 | |
1515 | 1510 | pce_cd_update(machine()); |
1516 | 1511 | } |
1517 | 1512 | |
1518 | ||
1513 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_clear_ack) | |
1519 | 1514 | { |
1520 | pce_state *state = machine.driver_data<pce_state>(); | |
1521 | pce_cd_t &pce_cd = state->m_cd; | |
1522 | pce_cd_update(machine); | |
1515 | pce_cd_t &pce_cd = m_cd; | |
1516 | pce_cd_update(machine()); | |
1523 | 1517 | pce_cd.scsi_ACK = 0; |
1524 | pce_cd_update(machine); | |
1518 | pce_cd_update(machine()); | |
1525 | 1519 | if ( pce_cd.scsi_CD ) |
1526 | 1520 | { |
1527 | 1521 | pce_cd.regs[0x0B] &= 0xFE; |
r18113 | r18114 | |
1538 | 1532 | if ( pce_cd.scsi_IO ) |
1539 | 1533 | { |
1540 | 1534 | pce_cd.scsi_ACK = 1; |
1541 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(15), FUNC(pce_cd_clear_ack)); | |
1535 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(15), timer_expired_delegate(FUNC(pce_state::pce_cd_clear_ack),state)); | |
1542 | 1536 | } |
1543 | 1537 | } |
1544 | 1538 | return data; |
1545 | 1539 | } |
1546 | 1540 | |
1547 | 1541 | |
1548 | ||
1542 | TIMER_CALLBACK_MEMBER(pce_state::pce_cd_adpcm_dma_timer_callback) | |
1549 | 1543 | { |
1550 | pce_state *state = machine.driver_data<pce_state>(); | |
1551 | pce_cd_t &pce_cd = state->m_cd; | |
1544 | pce_cd_t &pce_cd = m_cd; | |
1552 | 1545 | if ( pce_cd.scsi_REQ && ! pce_cd.scsi_ACK && ! pce_cd.scsi_CD && pce_cd.scsi_IO ) |
1553 | 1546 | { |
1554 | pce_cd.adpcm_ram[pce_cd.adpcm_write_ptr] = pce_cd_get_cd_data_byte(machine); | |
1547 | pce_cd.adpcm_ram[pce_cd.adpcm_write_ptr] = pce_cd_get_cd_data_byte(machine()); | |
1555 | 1548 | pce_cd.adpcm_write_ptr = ( pce_cd.adpcm_write_ptr + 1 ) & 0xFFFF; |
1556 | 1549 | |
1557 | 1550 | pce_cd.regs[0x0c] &= ~4; |
r18113 | r18114 | |
---|---|---|
1314 | 1314 | state->m_mc6850_clock = new_clock; |
1315 | 1315 | } |
1316 | 1316 | |
1317 | ||
1317 | TIMER_CALLBACK_MEMBER(bbc_state::bbc_tape_timer_cb) | |
1318 | 1318 | { |
1319 | bbc_state *state = machine.driver_data<bbc_state>(); | |
1320 | 1319 | |
1321 | 1320 | double dev_val; |
1322 | dev_val=machine.device<cassette_image_device>(CASSETTE_TAG)->input(); | |
1321 | dev_val=machine().device<cassette_image_device>(CASSETTE_TAG)->input(); | |
1323 | 1322 | |
1324 | 1323 | // look for rising edges on the cassette wave |
1325 | if (((dev_val>=0.0) && ( | |
1324 | if (((dev_val>=0.0) && (m_last_dev_val<0.0)) || ((dev_val<0.0) && (m_last_dev_val>=0.0))) | |
1326 | 1325 | { |
1327 | if ( | |
1326 | if (m_wav_len>(9*3)) | |
1328 | 1327 | { |
1329 | 1328 | //this is to long to recive anything so reset the serial IC. This is a hack, this should be done as a timer in the MC6850 code. |
1330 | logerror ("Cassette length %d\n",state->m_wav_len); | |
1331 | state->m_len0=0; | |
1332 | state->m_len1=0; | |
1333 | state->m_len2=0; | |
1334 | state->m_len3=0; | |
1335 | state->m_wav_len=0; | |
1329 | logerror ("Cassette length %d\n",m_wav_len); | |
1330 | m_len0=0; | |
1331 | m_len1=0; | |
1332 | m_len2=0; | |
1333 | m_len3=0; | |
1334 | m_wav_len=0; | |
1336 | 1335 | |
1337 | 1336 | } |
1338 | 1337 | |
1339 | state->m_len3=state->m_len2; | |
1340 | state->m_len2=state->m_len1; | |
1341 | state->m_len1=state->m_len0; | |
1342 | state->m_len0=state->m_wav_len; | |
1338 | m_len3=m_len2; | |
1339 | m_len2=m_len1; | |
1340 | m_len1=m_len0; | |
1341 | m_len0=m_wav_len; | |
1343 | 1342 | |
1344 | state->m_wav_len=0; | |
1345 | logerror ("cassette %d %d %d %d\n",state->m_len3,state->m_len2,state->m_len1,state->m_len0); | |
1343 | m_wav_len=0; | |
1344 | logerror ("cassette %d %d %d %d\n",m_len3,m_len2,m_len1,m_len0); | |
1346 | 1345 | |
1347 | if (( | |
1346 | if ((m_len0+m_len1)>=(18+18-5)) | |
1348 | 1347 | { |
1349 | 1348 | /* Clock a 0 onto the serial line */ |
1350 | 1349 | logerror("Serial value 0\n"); |
1351 | MC6850_Receive_Clock(machine, 0); | |
1352 | state->m_len0=0; | |
1353 | state->m_len1=0; | |
1354 | state->m_len2=0; | |
1355 | state->m_len3=0; | |
1350 | MC6850_Receive_Clock(machine(), 0); | |
1351 | m_len0=0; | |
1352 | m_len1=0; | |
1353 | m_len2=0; | |
1354 | m_len3=0; | |
1356 | 1355 | } |
1357 | 1356 | |
1358 | if ((( | |
1357 | if (((m_len0+m_len1+m_len2+m_len3)<=41) && (m_len3!=0)) | |
1359 | 1358 | { |
1360 | 1359 | /* Clock a 1 onto the serial line */ |
1361 | 1360 | logerror("Serial value 1\n"); |
1362 | MC6850_Receive_Clock(machine, 1); | |
1363 | state->m_len0=0; | |
1364 | state->m_len1=0; | |
1365 | state->m_len2=0; | |
1366 | state->m_len3=0; | |
1361 | MC6850_Receive_Clock(machine(), 1); | |
1362 | m_len0=0; | |
1363 | m_len1=0; | |
1364 | m_len2=0; | |
1365 | m_len3=0; | |
1367 | 1366 | } |
1368 | 1367 | |
1369 | 1368 | |
1370 | 1369 | } |
1371 | 1370 | |
1372 | state->m_wav_len++; | |
1373 | state->m_last_dev_val=dev_val; | |
1371 | m_wav_len++; | |
1372 | m_last_dev_val=dev_val; | |
1374 | 1373 | |
1375 | 1374 | } |
1376 | 1375 | |
r18113 | r18114 | |
1987 | 1986 | DRIVER_INIT_MEMBER(bbc_state,bbc) |
1988 | 1987 | { |
1989 | 1988 | m_Master=0; |
1990 | m_tape_timer = machine().scheduler().timer_alloc(FUNC(bbc_tape_timer_cb)); | |
1989 | m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_state::bbc_tape_timer_cb),this)); | |
1991 | 1990 | } |
1992 | 1991 | DRIVER_INIT_MEMBER(bbc_state,bbcm) |
1993 | 1992 | { |
1994 | 1993 | m_Master=1; |
1995 | m_tape_timer = machine().scheduler().timer_alloc(FUNC(bbc_tape_timer_cb)); | |
1994 | m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_state::bbc_tape_timer_cb),this)); | |
1996 | 1995 | } |
1997 | 1996 | |
1998 | 1997 | MACHINE_START_MEMBER(bbc_state,bbca) |
r18113 | r18114 | |
---|---|---|
100 | 100 | } |
101 | 101 | |
102 | 102 | /* Cassette timer*/ |
103 | ||
103 | TIMER_CALLBACK_MEMBER(hec2hrp_state::Callback_CK) | |
104 | 104 | { |
105 | hec2hrp_state *state = machine.driver_data<hec2hrp_state>(); | |
106 | 105 | /* To generate the CK signal (K7)*/ |
107 | | |
106 | m_CK_signal++; | |
108 | 107 | } |
109 | 108 | |
110 | 109 | void hector_minidisc_init(running_machine &machine) |
r18113 | r18114 | |
891 | 890 | state->m_pot0 = state->m_pot1 = 0x40; |
892 | 891 | |
893 | 892 | /* For Cassette synchro*/ |
894 | state->m_Cassette_timer = machine.scheduler().timer_alloc(FUNC(Callback_CK)); | |
893 | state->m_Cassette_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(hec2hrp_state::Callback_CK),state)); | |
895 | 894 | state->m_Cassette_timer->adjust(attotime::from_msec(100), 0, attotime::from_usec(64));/* => real synchro scan speed for 15,624Khz*/ |
896 | 895 | |
897 | 896 | /* Sound sn76477*/ |
r18113 | r18114 | |
---|---|---|
41 | 41 | #define TAPE_LOW 0x00; |
42 | 42 | #define TAPE_HIGH 0xFF; |
43 | 43 | |
44 | ||
44 | TIMER_CALLBACK_MEMBER(electron_state::electron_tape_timer_handler) | |
45 | 45 | { |
46 | electron_state *state = machine.driver_data<electron_state>(); | |
47 | if ( state->m_ula.cassette_motor_mode ) | |
46 | if ( m_ula.cassette_motor_mode ) | |
48 | 47 | { |
49 | 48 | double tap_val; |
50 | tap_val = cassette_device_image(machine)->input(); | |
49 | tap_val = cassette_device_image(machine())->input(); | |
51 | 50 | if ( tap_val < -0.5 ) |
52 | 51 | { |
53 | state->m_ula.tape_value = ( state->m_ula.tape_value << 8 ) | TAPE_LOW; | |
54 | state->m_ula.tape_steps++; | |
52 | m_ula.tape_value = ( m_ula.tape_value << 8 ) | TAPE_LOW; | |
53 | m_ula.tape_steps++; | |
55 | 54 | } |
56 | 55 | else if ( tap_val > 0.5 ) |
57 | 56 | { |
58 | state->m_ula.tape_value = ( state->m_ula.tape_value << 8 ) | TAPE_HIGH; | |
59 | state->m_ula.tape_steps++; | |
57 | m_ula.tape_value = ( m_ula.tape_value << 8 ) | TAPE_HIGH; | |
58 | m_ula.tape_steps++; | |
60 | 59 | } |
61 | 60 | else |
62 | 61 | { |
63 | state->m_ula.tape_steps = 0; | |
64 | state->m_ula.bit_count = 0; | |
65 | state->m_ula.high_tone_set = 0; | |
66 | state->m_ula.tape_value = 0x80808080; | |
62 | m_ula.tape_steps = 0; | |
63 | m_ula.bit_count = 0; | |
64 | m_ula.high_tone_set = 0; | |
65 | m_ula.tape_value = 0x80808080; | |
67 | 66 | } |
68 | if ( | |
67 | if ( m_ula.tape_steps > 2 && ( m_ula.tape_value == 0x0000FFFF || m_ula.tape_value == 0x00FF00FF ) ) | |
69 | 68 | { |
70 | state->m_ula.tape_steps = 0; | |
71 | switch( state->m_ula.bit_count ) | |
69 | m_ula.tape_steps = 0; | |
70 | switch( m_ula.bit_count ) | |
72 | 71 | { |
73 | 72 | case 0: /* start bit */ |
74 | state->m_ula.start_bit = ( ( state->m_ula.tape_value == 0x0000FFFF ) ? 0 : 1 ); | |
75 | //logerror( "++ Read start bit: %d\n", state->m_ula.start_bit ); | |
76 | if ( state->m_ula.start_bit ) | |
73 | m_ula.start_bit = ( ( m_ula.tape_value == 0x0000FFFF ) ? 0 : 1 ); | |
74 | //logerror( "++ Read start bit: %d\n", m_ula.start_bit ); | |
75 | if ( m_ula.start_bit ) | |
77 | 76 | { |
78 | if ( | |
77 | if ( m_ula.high_tone_set ) | |
79 | 78 | { |
80 | | |
79 | m_ula.bit_count--; | |
81 | 80 | } |
82 | 81 | } |
83 | 82 | else |
84 | 83 | { |
85 | | |
84 | m_ula.high_tone_set = 0; | |
86 | 85 | } |
87 | 86 | break; |
88 | 87 | case 1: case 2: case 3: case 4: |
89 | 88 | case 5: case 6: case 7: case 8: |
90 | //logerror( "++ Read regular bit: %d\n", state->m_ula.tape_value == 0x0000FFFF ? 0 : 1 ); | |
91 | state->m_ula.tape_byte = ( state->m_ula.tape_byte >> 1 ) | ( state->m_ula.tape_value == 0x0000FFFF ? 0 : 0x80 ); | |
89 | //logerror( "++ Read regular bit: %d\n", m_ula.tape_value == 0x0000FFFF ? 0 : 1 ); | |
90 | m_ula.tape_byte = ( m_ula.tape_byte >> 1 ) | ( m_ula.tape_value == 0x0000FFFF ? 0 : 0x80 ); | |
92 | 91 | break; |
93 | 92 | case 9: /* stop bit */ |
94 | state->m_ula.stop_bit = ( ( state->m_ula.tape_value == 0x0000FFFF ) ? 0 : 1 ); | |
95 | //logerror( "++ Read stop bit: %d\n", state->m_ula.stop_bit ); | |
96 | if ( state->m_ula.start_bit && state->m_ula.stop_bit && state->m_ula.tape_byte == 0xFF && ! state->m_ula.high_tone_set ) | |
93 | m_ula.stop_bit = ( ( m_ula.tape_value == 0x0000FFFF ) ? 0 : 1 ); | |
94 | //logerror( "++ Read stop bit: %d\n", m_ula.stop_bit ); | |
95 | if ( m_ula.start_bit && m_ula.stop_bit && m_ula.tape_byte == 0xFF && ! m_ula.high_tone_set ) | |
97 | 96 | { |
98 | electron_interrupt_handler( machine, INT_SET, INT_HIGH_TONE ); | |
99 | state->m_ula.high_tone_set = 1; | |
97 | electron_interrupt_handler( machine(), INT_SET, INT_HIGH_TONE ); | |
98 | m_ula.high_tone_set = 1; | |
100 | 99 | } |
101 | else if ( ! | |
100 | else if ( ! m_ula.start_bit && m_ula.stop_bit ) | |
102 | 101 | { |
103 | //logerror( "-- Byte read from tape: %02x\n", state->m_ula.tape_byte ); | |
104 | electron_interrupt_handler( machine, INT_SET, INT_RECEIVE_FULL ); | |
102 | //logerror( "-- Byte read from tape: %02x\n", m_ula.tape_byte ); | |
103 | electron_interrupt_handler( machine(), INT_SET, INT_RECEIVE_FULL ); | |
105 | 104 | } |
106 | 105 | else |
107 | 106 | { |
108 | logerror( "Invalid start/stop bit combination detected: %d,%d\n", | |
107 | logerror( "Invalid start/stop bit combination detected: %d,%d\n", m_ula.start_bit, m_ula.stop_bit ); | |
109 | 108 | } |
110 | 109 | break; |
111 | 110 | } |
112 | | |
111 | m_ula.bit_count = ( m_ula.bit_count + 1 ) % 10; | |
113 | 112 | } |
114 | 113 | } |
115 | 114 | } |
r18113 | r18114 | |
315 | 314 | Machine Initialisation functions |
316 | 315 | ***************************************/ |
317 | 316 | |
318 | ||
317 | TIMER_CALLBACK_MEMBER(electron_state::setup_beep) | |
319 | 318 | { |
320 | device_t *speaker = machine.device(BEEPER_TAG); | |
319 | device_t *speaker = machine().device(BEEPER_TAG); | |
321 | 320 | beep_set_state( speaker, 0 ); |
322 | 321 | beep_set_frequency( speaker, 300 ); |
323 | 322 | } |
r18113 | r18114 | |
346 | 345 | |
347 | 346 | m_ula.interrupt_status = 0x82; |
348 | 347 | m_ula.interrupt_control = 0x00; |
349 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep)); | |
350 | m_tape_timer = machine().scheduler().timer_alloc(FUNC(electron_tape_timer_handler)); | |
348 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(electron_state::setup_beep),this)); | |
349 | m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(electron_state::electron_tape_timer_handler),this)); | |
351 | 350 | machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(electron_reset),&machine())); |
352 | 351 | } |
353 | 352 |
r18113 | r18114 | |
---|---|---|
69 | 69 | }; |
70 | 70 | |
71 | 71 | |
72 | ||
72 | TIMER_CALLBACK_MEMBER(mikro80_state::mikro80_reset) | |
73 | 73 | { |
74 | mikro80_state *state = machine.driver_data<mikro80_state>(); | |
75 | state->membank("bank1")->set_entry(0); | |
74 | membank("bank1")->set_entry(0); | |
76 | 75 | } |
77 | 76 | |
78 | 77 | void mikro80_state::machine_reset() |
79 | 78 | { |
80 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(mikro80_reset)); | |
79 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(mikro80_state::mikro80_reset),this)); | |
81 | 80 | membank("bank1")->set_entry(1); |
82 | 81 | m_keyboard_mask = 0; |
83 | 82 | } |
r18113 | r18114 | |
---|---|---|
333 | 333 | DEVCB_LINE(via_1_irq) |
334 | 334 | }; |
335 | 335 | |
336 | ||
336 | TIMER_CALLBACK_MEMBER(microtan_state::microtan_read_cassette) | |
337 | 337 | { |
338 | double level = (cassette_device_image(machine))->input(); | |
339 | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); | |
338 | double level = (cassette_device_image(machine()))->input(); | |
339 | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); | |
340 | 340 | |
341 | 341 | LOG(("microtan_read_cassette: %g\n", level)); |
342 | 342 | if (level < -0.07) |
r18113 | r18114 | |
382 | 382 | |
383 | 383 | |
384 | 384 | /* This callback is called one clock cycle after BFF2 is written (delayed nmi) */ |
385 | ||
385 | TIMER_CALLBACK_MEMBER(microtan_state::microtan_pulse_nmi) | |
386 | 386 | { |
387 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
387 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
388 | 388 | } |
389 | 389 | |
390 | 390 | WRITE8_MEMBER(microtan_state::microtan_bffx_w) |
r18113 | r18114 | |
400 | 400 | break; |
401 | 401 | case 1: /* BFF1: write delayed NMI */ |
402 | 402 | LOG(("microtan_bff1_w: %d <- %02x (delayed NMI)\n", offset, data)); |
403 | machine().scheduler().timer_set(machine().device<cpu_device>("maincpu")->cycles_to_attotime(8), FUNC(microtan_pulse_nmi)); | |
403 | machine().scheduler().timer_set(machine().device<cpu_device>("maincpu")->cycles_to_attotime(8), timer_expired_delegate(FUNC(microtan_state::microtan_pulse_nmi),this)); | |
404 | 404 | break; |
405 | 405 | case 2: /* BFF2: write keypad column write (what is this meant for?) */ |
406 | 406 | LOG(("microtan_bff2_w: %d <- %02x (keypad column)\n", offset, data)); |
r18113 | r18114 | |
566 | 566 | break; |
567 | 567 | } |
568 | 568 | |
569 | m_timer = machine().scheduler().timer_alloc(FUNC(microtan_read_cassette)); | |
569 | m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(microtan_state::microtan_read_cassette),this)); | |
570 | 570 | } |
571 | 571 | |
572 | 572 | void microtan_state::machine_reset() |
r18113 | r18114 | |
---|---|---|
596 | 596 | * |
597 | 597 | *************************************/ |
598 | 598 | |
599 | ||
599 | TIMER_CALLBACK_MEMBER(compis_state::internal_timer_int) | |
600 | 600 | { |
601 | compis_state *state = machine.driver_data<compis_state>(); | |
602 | 601 | int which = param; |
603 | struct timer_state *t = & | |
602 | struct timer_state *t = &m_i186.timer[which]; | |
604 | 603 | |
605 | 604 | if (LOG_TIMER) logerror("Hit interrupt callback for timer %d\n", which); |
606 | 605 | |
r18113 | r18114 | |
610 | 609 | /* request an interrupt */ |
611 | 610 | if (t->control & 0x2000) |
612 | 611 | { |
613 | state->m_i186.intr.status |= 0x01 << which; | |
614 | update_interrupt_state(machine); | |
612 | m_i186.intr.status |= 0x01 << which; | |
613 | update_interrupt_state(machine()); | |
615 | 614 | if (LOG_TIMER) logerror(" Generating timer interrupt\n"); |
616 | 615 | } |
617 | 616 | |
r18113 | r18114 | |
781 | 780 | * |
782 | 781 | *************************************/ |
783 | 782 | |
784 | ||
783 | TIMER_CALLBACK_MEMBER(compis_state::dma_timer_callback) | |
785 | 784 | { |
786 | compis_state *state = machine.driver_data<compis_state>(); | |
787 | 785 | int which = param; |
788 | struct dma_state *d = & | |
786 | struct dma_state *d = &m_i186.dma[which]; | |
789 | 787 | |
790 | 788 | /* force an update and see if we're really done */ |
791 | 789 | //stream_update(dma_stream, 0); |
r18113 | r18114 | |
799 | 797 | if (d->control & 0x0100) |
800 | 798 | { |
801 | 799 | if (LOG_DMA) logerror("DMA%d timer callback - requesting interrupt: count = %04X, source = %04X\n", which, d->count, d->source); |
802 | state->m_i186.intr.request |= 0x04 << which; | |
803 | update_interrupt_state(machine); | |
800 | m_i186.intr.request |= 0x04 << which; | |
801 | update_interrupt_state(machine()); | |
804 | 802 | } |
805 | 803 | } |
806 | 804 | |
r18113 | r18114 | |
1301 | 1299 | { |
1302 | 1300 | compis_state *state = machine.driver_data<compis_state>(); |
1303 | 1301 | /* create timers here so they stick around */ |
1304 | state->m_i186.timer[0].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
1305 | state->m_i186.timer[1].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
1306 | state->m_i186.timer[2].int_timer = machine.scheduler().timer_alloc(FUNC(internal_timer_int)); | |
1307 | state->m_i186.timer[0].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); | |
1308 | state->m_i186.timer[1].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); | |
1309 | state->m_i186.timer[2].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); | |
1310 | state->m_i186.dma[0].finish_timer = machine.scheduler().timer_alloc(FUNC(dma_timer_callback)); | |
1311 | state->m_i186.dma[1].finish_timer = machine.scheduler().timer_alloc(FUNC(dma_timer_callback)); | |
1302 | state->m_i186.timer[0].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(compis_state::internal_timer_int),state)); | |
1303 | state->m_i186.timer[1].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(compis_state::internal_timer_int),state)); | |
1304 | state->m_i186.timer[2].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(compis_state::internal_timer_int),state)); | |
1305 | state->m_i186.timer[0].time_timer = machine.scheduler().timer_alloc(timer_expired_delegate()); | |
1306 | state->m_i186.timer[1].time_timer = machine.scheduler().timer_alloc(timer_expired_delegate()); | |
1307 | state->m_i186.timer[2].time_timer = machine.scheduler().timer_alloc(timer_expired_delegate()); | |
1308 | state->m_i186.dma[0].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(compis_state::dma_timer_callback),state)); | |
1309 | state->m_i186.dma[1].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(compis_state::dma_timer_callback),state)); | |
1312 | 1310 | } |
1313 | 1311 | |
1314 | 1312 | /*-------------------------------------------------------------------------*/ |
r18113 | r18114 | |
---|---|---|
124 | 124 | machine.device<nvram_device>("ram_nvram")->set_base(ram, 0x2800); |
125 | 125 | } |
126 | 126 | |
127 | ||
127 | TIMER_CALLBACK_MEMBER(pc1401_state::pc1401_power_up) | |
128 | 128 | { |
129 | pc1401_state *state = machine.driver_data<pc1401_state>(); | |
130 | state->m_power = 0; | |
129 | m_power = 0; | |
131 | 130 | } |
132 | 131 | |
133 | 132 | DRIVER_INIT_MEMBER(pc1401_state,pc1401) |
r18113 | r18114 | |
234 | 233 | gfx[i]=i; |
235 | 234 | |
236 | 235 | m_power = 1; |
237 | machine().scheduler().timer_set(attotime::from_seconds(1), FUNC(pc1401_power_up)); | |
236 | machine().scheduler().timer_set(attotime::from_seconds(1), timer_expired_delegate(FUNC(pc1401_state::pc1401_power_up),this)); | |
238 | 237 | } |
r18113 | r18114 | |
---|---|---|
178 | 178 | MOUSE |
179 | 179 | ***************************************************************************/ |
180 | 180 | |
181 | ||
181 | TIMER_CALLBACK_MEMBER(samcoupe_state::samcoupe_mouse_reset) | |
182 | 182 | { |
183 | samcoupe_state *state = machine.driver_data<samcoupe_state>(); | |
184 | state->m_mouse_index = 0; | |
183 | m_mouse_index = 0; | |
185 | 184 | } |
186 | 185 | |
187 | 186 | UINT8 samcoupe_mouse_r(running_machine &machine) |
r18113 | r18114 | |
231 | 230 | |
232 | 231 | void samcoupe_state::machine_start() |
233 | 232 | { |
234 | m_mouse_reset = machine().scheduler().timer_alloc(FUNC(samcoupe_mouse_reset)); | |
233 | m_mouse_reset = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(samcoupe_state::samcoupe_mouse_reset),this)); | |
235 | 234 | |
236 | 235 | /* schedule our video updates */ |
237 | m_video_update_timer = machine().scheduler().timer_alloc(FUNC(sam_video_update_callback)); | |
236 | m_video_update_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(samcoupe_state::sam_video_update_callback),this)); | |
238 | 237 | m_video_update_timer->adjust(machine().primary_screen->time_until_pos(0, 0)); |
239 | 238 | } |
240 | 239 |
r18113 | r18114 | |
---|---|---|
618 | 618 | } |
619 | 619 | } |
620 | 620 | |
621 | ||
621 | TIMER_CALLBACK_MEMBER(pet_state::pet_interrupt) | |
622 | 622 | { |
623 | pet_state *state = machine.driver_data<pet_state>(); | |
624 | pia6821_device *pia_0 = machine.device<pia6821_device>("pia_0"); | |
623 | pia6821_device *pia_0 = machine().device<pia6821_device>("pia_0"); | |
625 | 624 | |
626 | pia_0->cb1_w(state->m_pia_level); | |
627 | state->m_pia_level = !state->m_pia_level; | |
625 | pia_0->cb1_w(m_pia_level); | |
626 | m_pia_level = !m_pia_level; | |
628 | 627 | } |
629 | 628 | |
630 | 629 | |
631 | ||
630 | TIMER_CALLBACK_MEMBER(pet_state::pet_tape1_timer) | |
632 | 631 | { |
633 | pia6821_device *pia_0 = machine.device<pia6821_device>("pia_0"); | |
632 | pia6821_device *pia_0 = machine().device<pia6821_device>("pia_0"); | |
634 | 633 | // cassette 1 |
635 | UINT8 data = (machine.device<cassette_image_device>(CASSETTE_TAG)->input() > +0.0) ? 1 : 0; | |
634 | UINT8 data = (machine().device<cassette_image_device>(CASSETTE_TAG)->input() > +0.0) ? 1 : 0; | |
636 | 635 | pia_0->ca1_w(data); |
637 | 636 | } |
638 | 637 | |
639 | ||
638 | TIMER_CALLBACK_MEMBER(pet_state::pet_tape2_timer) | |
640 | 639 | { |
641 | via6522_device *via_0 = machine.device<via6522_device>("via6522_0"); | |
640 | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); | |
642 | 641 | // cassette 2 |
643 | UINT8 data = (machine.device<cassette_image_device>(CASSETTE2_TAG)->input() > +0.0) ? 1 : 0; | |
642 | UINT8 data = (machine().device<cassette_image_device>(CASSETTE2_TAG)->input() > +0.0) ? 1 : 0; | |
644 | 643 | via_0->write_cb1(data); |
645 | 644 | } |
646 | 645 | |
r18113 | r18114 | |
671 | 670 | } |
672 | 671 | |
673 | 672 | /* pet clock */ |
674 | machine.scheduler().timer_pulse(attotime::from_msec(10), FUNC(pet_interrupt)); | |
673 | machine.scheduler().timer_pulse(attotime::from_msec(10), timer_expired_delegate(FUNC(pet_state::pet_interrupt),state)); | |
675 | 674 | |
676 | 675 | /* datasette */ |
677 | state->m_datasette1_timer = machine.scheduler().timer_alloc(FUNC(pet_tape1_timer)); | |
678 | state->m_datasette2_timer = machine.scheduler().timer_alloc(FUNC(pet_tape2_timer)); | |
676 | state->m_datasette1_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pet_state::pet_tape1_timer),state)); | |
677 | state->m_datasette2_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pet_state::pet_tape2_timer),state)); | |
679 | 678 | } |
680 | 679 | |
681 | 680 |
r18113 | r18114 | |
---|---|---|
73 | 73 | } |
74 | 74 | |
75 | 75 | |
76 | ||
76 | TIMER_CALLBACK_MEMBER(sym1_state::led_refresh) | |
77 | 77 | { |
78 | sym1_state *state = machine.driver_data<sym1_state>(); | |
79 | output_set_digit_value(param, state->m_riot_port_a); | |
78 | output_set_digit_value(param, m_riot_port_a); | |
80 | 79 | } |
81 | 80 | |
82 | 81 | |
r18113 | r18114 | |
294 | 293 | } |
295 | 294 | |
296 | 295 | /* allocate a timer to refresh the led display */ |
297 | m_led_update = machine().scheduler().timer_alloc(FUNC(led_refresh)); | |
296 | m_led_update = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sym1_state::led_refresh),this)); | |
298 | 297 | } |
299 | 298 | |
300 | 299 |
r18113 | r18114 | |
---|---|---|
787 | 787 | }; |
788 | 788 | |
789 | 789 | |
790 | ||
790 | TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback) | |
791 | 791 | { |
792 | pmd85_state *state = machine.driver_data<pmd85_state>(); | |
793 | i8251_device *uart = machine.device<i8251_device>("uart"); | |
794 | serial_source_device *ser = machine.device<serial_source_device>("sercas"); | |
792 | i8251_device *uart = machine().device<i8251_device>("uart"); | |
793 | serial_source_device *ser = machine().device<serial_source_device>("sercas"); | |
795 | 794 | int data; |
796 | 795 | int current_level; |
797 | 796 | |
798 | if (!(machine.root_device().ioport("DSW0")->read() & 0x02)) /* V.24 / Tape Switch */ | |
797 | if (!(machine().root_device().ioport("DSW0")->read() & 0x02)) /* V.24 / Tape Switch */ | |
799 | 798 | { |
800 | 799 | /* tape reading */ |
801 | if (machine.device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_PLAY) | |
800 | if (machine().device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_PLAY) | |
802 | 801 | { |
803 | switch ( | |
802 | switch (m_model) | |
804 | 803 | { |
805 | 804 | case PMD85_1: |
806 | if ( | |
805 | if (m_clk_level_tape) | |
807 | 806 | { |
808 | state->m_previous_level = ((machine.device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
809 | state->m_clk_level_tape = 0; | |
807 | m_previous_level = ((machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
808 | m_clk_level_tape = 0; | |
810 | 809 | } |
811 | 810 | else |
812 | 811 | { |
813 | current_level = ((machine.device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
812 | current_level = ((machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.038) ? 1 : 0; | |
814 | 813 | |
815 | if ( | |
814 | if (m_previous_level!=current_level) | |
816 | 815 | { |
817 | data = (! | |
816 | data = (!m_previous_level && current_level) ? 1 : 0; | |
818 | 817 | |
819 | 818 | ser->send_bit(data); |
820 | 819 | uart->receive_clock(); |
821 | 820 | |
822 | | |
821 | m_clk_level_tape = 1; | |
823 | 822 | } |
824 | 823 | } |
825 | 824 | return; |
r18113 | r18114 | |
834 | 833 | } |
835 | 834 | |
836 | 835 | /* tape writing */ |
837 | if (machine.device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_RECORD) | |
836 | if (machine().device<cassette_image_device>(CASSETTE_TAG)->get_state()&CASSETTE_RECORD) | |
838 | 837 | { |
839 | 838 | data = ser->get_in_data_bit(); |
840 | data ^= state->m_clk_level_tape; | |
841 | machine.device<cassette_image_device>(CASSETTE_TAG)->output(data&0x01 ? 1 : -1); | |
839 | data ^= m_clk_level_tape; | |
840 | machine().device<cassette_image_device>(CASSETTE_TAG)->output(data&0x01 ? 1 : -1); | |
842 | 841 | |
843 | if (! | |
842 | if (!m_clk_level_tape) | |
844 | 843 | uart->transmit_clock(); |
845 | 844 | |
846 | | |
845 | m_clk_level_tape = m_clk_level_tape ? 0 : 1; | |
847 | 846 | |
848 | 847 | return; |
849 | 848 | } |
850 | 849 | |
851 | | |
850 | m_clk_level_tape = 1; | |
852 | 851 | |
853 | if (! | |
852 | if (!m_clk_level) | |
854 | 853 | uart->transmit_clock(); |
855 | | |
854 | m_clk_level = m_clk_level ? 0 : 1; | |
856 | 855 | } |
857 | 856 | } |
858 | 857 | |
859 | ||
858 | TIMER_CALLBACK_MEMBER(pmd85_state::pmd_reset) | |
860 | 859 | { |
861 | machine.schedule_soft_reset(); | |
860 | machine().schedule_soft_reset(); | |
862 | 861 | } |
863 | 862 | |
864 | 863 | DIRECT_UPDATE_MEMBER(pmd85_state::pmd85_opbaseoverride) |
865 | 864 | { |
866 | 865 | if (ioport("RESET")->read() & 0x01) |
867 | machine().scheduler().timer_set(attotime::from_usec(10), FUNC(pmd_reset)); | |
866 | machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(pmd85_state::pmd_reset),this)); | |
868 | 867 | return address; |
869 | 868 | } |
870 | 869 | |
r18113 | r18114 | |
873 | 872 | pmd85_state *state = machine.driver_data<pmd85_state>(); |
874 | 873 | state->m_previous_level = 0; |
875 | 874 | state->m_clk_level = state->m_clk_level_tape = 1; |
876 | state->m_cassette_timer = machine.scheduler().timer_alloc(FUNC(pmd85_cassette_timer_callback)); | |
875 | state->m_cassette_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pmd85_state::pmd85_cassette_timer_callback),state)); | |
877 | 876 | state->m_cassette_timer->adjust(attotime::zero, 0, attotime::from_hz(2400)); |
878 | 877 | } |
879 | 878 | |
r18113 | r18114 | |
918 | 917 | pmd85_common_driver_init(machine()); |
919 | 918 | } |
920 | 919 | |
921 | ||
920 | TIMER_CALLBACK_MEMBER(pmd85_state::setup_machine_state) | |
922 | 921 | { |
923 | pmd85_state *state = machine.driver_data<pmd85_state>(); | |
924 | if (state->m_model != MATO) | |
922 | if (m_model != MATO) | |
925 | 923 | { |
926 | i8251_device *uart = machine.device<i8251_device>("uart"); | |
927 | serial_source_device *ser = machine.device<serial_source_device>("sercas"); | |
924 | i8251_device *uart = machine().device<i8251_device>("uart"); | |
925 | serial_source_device *ser = machine().device<serial_source_device>("sercas"); | |
928 | 926 | uart->connect(ser); |
929 | 927 | } |
930 | 928 | } |
r18113 | r18114 | |
958 | 956 | m_startup_mem_map = 1; |
959 | 957 | update_memory(machine()); |
960 | 958 | |
961 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_machine_state)); | |
959 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(pmd85_state::setup_machine_state),this)); | |
962 | 960 | |
963 | 961 | machine().device("maincpu")->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(pmd85_state::pmd85_opbaseoverride), this)); |
964 | 962 | } |
r18113 | r18114 | |
---|---|---|
294 | 294 | |
295 | 295 | |
296 | 296 | /* Clock interrupt */ |
297 | ||
297 | TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_clock_tick) | |
298 | 298 | { |
299 | apple2gs_state *state = machine.driver_data<apple2gs_state>(); | |
300 | if ((state->m_vgcint & 0x04) && !(state->m_vgcint & 0x40)) | |
299 | if ((m_vgcint & 0x04) && !(m_vgcint & 0x40)) | |
301 | 300 | { |
302 | state->m_vgcint |= 0xc0; | |
303 | apple2gs_add_irq(machine, IRQ_VGC_SECOND); | |
301 | m_vgcint |= 0xc0; | |
302 | apple2gs_add_irq(machine(), IRQ_VGC_SECOND); | |
304 | 303 | } |
305 | 304 | } |
306 | 305 | |
307 | 306 | |
308 | 307 | /* Quarter-second interrupt */ |
309 | ||
308 | TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_qsecond_tick) | |
310 | 309 | { |
311 | apple2gs_state *state = machine.driver_data<apple2gs_state>(); | |
312 | if ((state->m_inten & 0x10) && !(state->m_intflag & 0x10)) | |
310 | if ((m_inten & 0x10) && !(m_intflag & 0x10)) | |
313 | 311 | { |
314 | state->m_intflag |= 0x10; | |
315 | apple2gs_add_irq(machine, IRQ_INTEN_QSECOND); | |
312 | m_intflag |= 0x10; | |
313 | apple2gs_add_irq(machine(), IRQ_INTEN_QSECOND); | |
316 | 314 | } |
317 | 315 | } |
318 | 316 | |
r18113 | r18114 | |
736 | 734 | } |
737 | 735 | |
738 | 736 | |
739 | ||
737 | TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_scanline_tick) | |
740 | 738 | { |
741 | apple2gs_state *state = machine.driver_data<apple2gs_state>(); | |
742 | 739 | int scanline; |
743 | 740 | |
744 | scanline = machine.primary_screen->vpos(); | |
745 | machine.primary_screen->update_partial(scanline); | |
741 | scanline = machine().primary_screen->vpos(); | |
742 | machine().primary_screen->update_partial(scanline); | |
746 | 743 | |
747 | 744 | /* check scanline interrupt bits if we're in super hi-res and the current scanline is within the active display area */ |
748 | if (( | |
745 | if ((m_newvideo & 0x80) && (scanline >= (BORDER_TOP-1)) && (scanline < (200+BORDER_TOP-1))) | |
749 | 746 | { |
750 | 747 | UINT8 scb; |
751 | 748 | |
752 | scb = | |
749 | scb = m_slowmem[0x19D00 + scanline - BORDER_TOP + 1]; | |
753 | 750 | |
754 | 751 | if (scb & 0x40) |
755 | 752 | { |
756 | 753 | // scanline int flag is set even when the actual interrupt is disabled |
757 | | |
754 | m_vgcint |= 0x20; | |
758 | 755 | |
759 | 756 | // see if the interrupt is also enabled and trigger it if so |
760 | if ( | |
757 | if (m_vgcint & 0x02) | |
761 | 758 | { |
762 | state->m_vgcint |= 0x80; | |
763 | apple2gs_add_irq(machine, IRQ_VGC_SCANLINE); | |
759 | m_vgcint |= 0x80; | |
760 | apple2gs_add_irq(machine(), IRQ_VGC_SCANLINE); | |
764 | 761 | } |
765 | 762 | } |
766 | 763 | } |
r18113 | r18114 | |
768 | 765 | if (scanline == (192+BORDER_TOP)) |
769 | 766 | { |
770 | 767 | /* VBL interrupt */ |
771 | if (( | |
768 | if ((m_inten & 0x08) && !(m_intflag & 0x08)) | |
772 | 769 | { |
773 | state->m_intflag |= 0x08; | |
774 | apple2gs_add_irq(machine, IRQ_INTEN_VBL); | |
770 | m_intflag |= 0x08; | |
771 | apple2gs_add_irq(machine(), IRQ_INTEN_VBL); | |
775 | 772 | } |
776 | 773 | } |
777 | 774 | |
778 | 775 | /* check the mouse status */ |
779 | 776 | if ((scanline % 8) == 0) |
780 | 777 | { |
781 | adb_check_mouse(machine); | |
778 | adb_check_mouse(machine()); | |
782 | 779 | |
783 | 780 | /* call Apple II interrupt handler */ |
784 | if ((machine.primary_screen->vpos() % 8) == 7) | |
781 | if ((machine().primary_screen->vpos() % 8) == 7) | |
785 | 782 | { |
786 | //apple2_interrupt(machine.device("maincpu")); | |
783 | //apple2_interrupt(machine().device("maincpu")); | |
787 | 784 | /* TODO: check me! */ |
788 | machine.primary_screen->update_partial(machine.primary_screen->vpos()); | |
785 | machine().primary_screen->update_partial(machine().primary_screen->vpos()); | |
789 | 786 | } |
790 | 787 | } |
791 | 788 | |
792 | | |
789 | m_scanline_timer->adjust(machine().primary_screen->time_until_pos((scanline+1)%262, 0)); | |
793 | 790 | } |
794 | 791 | |
795 | 792 | |
r18113 | r18114 | |
1993 | 1990 | |
1994 | 1991 | state_save_register_item(machine(), "ECHOBANK", NULL,0, m_echo_bank); |
1995 | 1992 | |
1996 | m_clock_timer = machine().scheduler().timer_alloc(FUNC(apple2gs_clock_tick)); | |
1993 | m_clock_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_clock_tick),this)); | |
1997 | 1994 | m_clock_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1)); |
1998 | 1995 | |
1999 | m_qsecond_timer = machine().scheduler().timer_alloc(FUNC(apple2gs_qsecond_tick)); | |
1996 | m_qsecond_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_qsecond_tick),this)); | |
2000 | 1997 | m_qsecond_timer->adjust(attotime::from_usec(266700), 0, attotime::from_usec(266700)); |
2001 | 1998 | |
2002 | m_scanline_timer = machine().scheduler().timer_alloc(FUNC(apple2gs_scanline_tick)); | |
1999 | m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_scanline_tick),this)); | |
2003 | 2000 | m_scanline_timer->adjust(attotime::never); |
2004 | 2001 | |
2005 | 2002 | // fire on scanline zero |
r18113 | r18114 | |
---|---|---|
78 | 78 | DECLARE_WRITE8_MEMBER(hp48_io_w); |
79 | 79 | DECLARE_READ8_MEMBER(hp48_io_r); |
80 | 80 | DECLARE_READ8_MEMBER(hp48_bank_r); |
81 | TIMER_CALLBACK_MEMBER(hp48_rs232_byte_recv_cb); | |
82 | TIMER_CALLBACK_MEMBER(hp48_rs232_byte_sent_cb); | |
83 | TIMER_CALLBACK_MEMBER(hp48_chardev_byte_recv_cb); | |
84 | TIMER_CALLBACK_MEMBER(hp48_kbd_cb); | |
85 | TIMER_CALLBACK_MEMBER(hp48_timer1_cb); | |
86 | TIMER_CALLBACK_MEMBER(hp48_timer2_cb); | |
81 | 87 | }; |
82 | 88 | |
83 | 89 |
r18113 | r18114 | |
---|---|---|
86 | 86 | virtual void machine_start(); |
87 | 87 | virtual void machine_reset(); |
88 | 88 | DECLARE_MACHINE_START(sorcererd); |
89 | TIMER_CALLBACK_MEMBER(sorcerer_serial_tc); | |
90 | TIMER_CALLBACK_MEMBER(sorcerer_cassette_tc); | |
91 | TIMER_CALLBACK_MEMBER(sorcerer_reset); | |
89 | 92 | }; |
90 | 93 | |
91 | 94 |
r18113 | r18114 | |
---|---|---|
57 | 57 | DECLARE_VIDEO_START(pet_crtc); |
58 | 58 | UINT32 screen_update_pet(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
59 | 59 | INTERRUPT_GEN_MEMBER(pet_frame_interrupt); |
60 | TIMER_CALLBACK_MEMBER(pet_interrupt); | |
61 | TIMER_CALLBACK_MEMBER(pet_tape1_timer); | |
62 | TIMER_CALLBACK_MEMBER(pet_tape2_timer); | |
60 | 63 | }; |
61 | 64 | |
62 | 65 | /*----------- defined in video/pet.c -----------*/ |
r18113 | r18114 | |
---|---|---|
101 | 101 | virtual void palette_init(); |
102 | 102 | UINT32 screen_update_pcw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
103 | 103 | UINT32 screen_update_pcw_printer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
104 | TIMER_CALLBACK_MEMBER(pcw_timer_pulse); | |
105 | TIMER_CALLBACK_MEMBER(pcw_stepper_callback); | |
106 | TIMER_CALLBACK_MEMBER(pcw_pins_callback); | |
107 | TIMER_CALLBACK_MEMBER(setup_beep); | |
104 | 108 | }; |
105 | 109 | |
106 | 110 | #endif /* PCW_H_ */ |
r18113 | r18114 | |
---|---|---|
73 | 73 | UINT32 screen_update_cgenie(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
74 | 74 | INTERRUPT_GEN_MEMBER(cgenie_timer_interrupt); |
75 | 75 | INTERRUPT_GEN_MEMBER(cgenie_frame_interrupt); |
76 | TIMER_CALLBACK_MEMBER(handle_cassette_input); | |
76 | 77 | }; |
77 | 78 | |
78 | 79 |
r18113 | r18114 | |
---|---|---|
64 | 64 | |
65 | 65 | /* floppy state */ |
66 | 66 | int m_fdc_index; |
67 | TIMER_CALLBACK_MEMBER(setup_beep); | |
67 | 68 | }; |
68 | 69 | |
69 | 70 | class c1p_state : public sb2m600_state |
r18113 | r18114 | |
---|---|---|
86 | 86 | DECLARE_MACHINE_START(pcjr); |
87 | 87 | DECLARE_MACHINE_RESET(pcjr); |
88 | 88 | DECLARE_MACHINE_START(mc1502); |
89 | TIMER_CALLBACK_MEMBER(pcjr_delayed_pic8259_irq); | |
90 | TIMER_CALLBACK_MEMBER(pcjr_keyb_signal_callback); | |
91 | TIMER_CALLBACK_MEMBER(mc1502_keyb_signal_callback); | |
92 | TIMER_CALLBACK_MEMBER(pc_rtc_timer); | |
89 | 93 | }; |
90 | 94 | |
91 | 95 | /*----------- defined in machine/pc.c -----------*/ |
r18113 | r18114 | |
---|---|---|
79 | 79 | UINT32 screen_update_kaypro2x(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
80 | 80 | UINT32 screen_update_omni2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
81 | 81 | INTERRUPT_GEN_MEMBER(kay_kbd_interrupt); |
82 | TIMER_CALLBACK_MEMBER(kaypro_timer_callback); | |
82 | 83 | }; |
83 | 84 | |
84 | 85 |
r18113 | r18114 | |
---|---|---|
142 | 142 | DECLARE_MACHINE_RESET(mbeett); |
143 | 143 | UINT32 screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
144 | 144 | INTERRUPT_GEN_MEMBER(mbee_interrupt); |
145 | TIMER_CALLBACK_MEMBER(mbee256_kbd); | |
146 | TIMER_CALLBACK_MEMBER(mbee_rtc_irq); | |
147 | TIMER_CALLBACK_MEMBER(mbee_reset); | |
145 | 148 | }; |
146 | 149 | |
147 | 150 |
r18113 | r18114 | |
---|---|---|
72 | 72 | |
73 | 73 | /* TV Draw state */ |
74 | 74 | UINT8 m_tvdraw_data; |
75 | TIMER_CALLBACK_MEMBER(lightgun_tick); | |
75 | 76 | }; |
76 | 77 | |
77 | 78 | class sc3000_state : public sg1000_state |
r18113 | r18114 | |
---|---|---|
53 | 53 | virtual void video_start(); |
54 | 54 | UINT32 screen_update_microtan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
55 | 55 | INTERRUPT_GEN_MEMBER(microtan_interrupt); |
56 | TIMER_CALLBACK_MEMBER(microtan_read_cassette); | |
57 | TIMER_CALLBACK_MEMBER(microtan_pulse_nmi); | |
56 | 58 | }; |
57 | 59 | |
58 | 60 |
r18113 | r18114 | |
---|---|---|
124 | 124 | UINT32 screen_update_meritum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
125 | 125 | INTERRUPT_GEN_MEMBER(trs80_rtc_interrupt); |
126 | 126 | INTERRUPT_GEN_MEMBER(trs80_fdc_interrupt); |
127 | TIMER_CALLBACK_MEMBER(cassette_data_callback); | |
127 | 128 | }; |
128 | 129 | |
129 | 130 |
r18113 | r18114 | |
---|---|---|
82 | 82 | DECLARE_DRIVER_INIT(osborne1); |
83 | 83 | virtual void machine_reset(); |
84 | 84 | virtual void palette_init(); |
85 | TIMER_CALLBACK_MEMBER(osborne1_video_callback); | |
86 | TIMER_CALLBACK_MEMBER(setup_osborne1); | |
85 | 87 | }; |
86 | 88 | |
87 | 89 |
r18113 | r18114 | |
---|---|---|
228 | 228 | virtual void palette_init(); |
229 | 229 | UINT32 screen_update_nimbus(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
230 | 230 | void screen_eof_nimbus(screen_device &screen, bool state); |
231 | TIMER_CALLBACK_MEMBER(internal_timer_int); | |
232 | TIMER_CALLBACK_MEMBER(dma_timer_callback); | |
233 | TIMER_CALLBACK_MEMBER(keyscan_callback); | |
234 | TIMER_CALLBACK_MEMBER(mouse_callback); | |
231 | 235 | }; |
232 | 236 | |
233 | 237 |
r18113 | r18114 | |
---|---|---|
146 | 146 | |
147 | 147 | kcexp_slot_device * m_expansions[3]; |
148 | 148 | DECLARE_PALETTE_INIT(kc85); |
149 | TIMER_CALLBACK_MEMBER(kc_cassette_oneshot_timer); | |
150 | TIMER_CALLBACK_MEMBER(kc_cassette_timer_callback); | |
149 | 151 | }; |
150 | 152 | |
151 | 153 |
r18113 | r18114 | |
---|---|---|
58 | 58 | DECLARE_MACHINE_RESET(pc8300); |
59 | 59 | DECLARE_MACHINE_RESET(pow3000); |
60 | 60 | void screen_eof_zx(screen_device &screen, bool state); |
61 | TIMER_CALLBACK_MEMBER(zx_tape_pulse); | |
62 | TIMER_CALLBACK_MEMBER(zx_ula_nmi); | |
63 | TIMER_CALLBACK_MEMBER(zx_ula_irq); | |
61 | 64 | }; |
62 | 65 | /*----------- defined in video/zx.c -----------*/ |
63 | 66 |
r18113 | r18114 | |
---|---|---|
40 | 40 | virtual void machine_reset(); |
41 | 41 | DECLARE_VIDEO_START(pecom); |
42 | 42 | DECLARE_INPUT_CHANGED_MEMBER(ef_w); |
43 | TIMER_CALLBACK_MEMBER(reset_tick); | |
43 | 44 | }; |
44 | 45 | |
45 | 46 | /*----------- defined in machine/pecom.c -----------*/ |
r18113 | r18114 | |
---|---|---|
157 | 157 | virtual void video_reset(); |
158 | 158 | virtual void palette_init(); |
159 | 159 | void screen_eof_mbc55x(screen_device &screen, bool state); |
160 | TIMER_CALLBACK_MEMBER(keyscan_callback); | |
160 | 161 | }; |
161 | 162 | |
162 | 163 | /* IO chips */ |
r18113 | r18114 | |
---|---|---|
43 | 43 | int m_joy_d7_state[2]; |
44 | 44 | UINT8 m_joy_analog_state[2]; |
45 | 45 | UINT8 m_joy_analog_reload[2]; |
46 | TIMER_CALLBACK_MEMBER(paddle_d7reset_callback); | |
47 | TIMER_CALLBACK_MEMBER(paddle_irqreset_callback); | |
48 | TIMER_CALLBACK_MEMBER(paddle_pulse_callback); | |
46 | 49 | }; |
47 | 50 | |
48 | 51 | #endif |
r18113 | r18114 | |
---|---|---|
30 | 30 | |
31 | 31 | DECLARE_DRIVER_INIT(pc1403); |
32 | 32 | UINT32 screen_update_pc1403(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
33 | TIMER_CALLBACK_MEMBER(pc1403_power_up); | |
33 | 34 | }; |
34 | 35 | |
35 | 36 |
r18113 | r18114 | |
---|---|---|
83 | 83 | virtual void machine_reset(); |
84 | 84 | virtual void palette_init(); |
85 | 85 | INTERRUPT_GEN_MEMBER(samcoupe_frame_interrupt); |
86 | TIMER_CALLBACK_MEMBER(irq_off); | |
87 | TIMER_CALLBACK_MEMBER(samcoupe_mouse_reset); | |
88 | TIMER_CALLBACK_MEMBER(sam_video_update_callback); | |
86 | 89 | }; |
87 | 90 | |
88 | 91 |
r18113 | r18114 | |
---|---|---|
47 | 47 | virtual void machine_reset(); |
48 | 48 | virtual void video_start(); |
49 | 49 | UINT32 screen_update_irisha(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
50 | TIMER_CALLBACK_MEMBER(irisha_key); | |
50 | 51 | }; |
51 | 52 | |
52 | 53 |
r18113 | r18114 | |
---|---|---|
115 | 115 | virtual void video_start(); |
116 | 116 | virtual void palette_init(); |
117 | 117 | UINT32 screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
118 | TIMER_CALLBACK_MEMBER(i824x_scanline_callback); | |
119 | TIMER_CALLBACK_MEMBER(i824x_hblank_callback); | |
118 | 120 | }; |
119 | 121 | |
120 | 122 |
r18113 | r18114 | |
---|---|---|
48 | 48 | virtual void machine_reset(); |
49 | 49 | virtual void video_start(); |
50 | 50 | UINT32 screen_update_apple1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
51 | TIMER_CALLBACK_MEMBER(apple1_kbd_poll); | |
52 | TIMER_CALLBACK_MEMBER(apple1_kbd_strobe_end); | |
53 | TIMER_CALLBACK_MEMBER(apple1_dsp_ready_start); | |
54 | TIMER_CALLBACK_MEMBER(apple1_dsp_ready_end); | |
51 | 55 | }; |
52 | 56 | |
53 | 57 |
r18113 | r18114 | |
---|---|---|
165 | 165 | virtual void video_start(); |
166 | 166 | UINT32 screen_update_lisa(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
167 | 167 | INTERRUPT_GEN_MEMBER(lisa_interrupt); |
168 | TIMER_CALLBACK_MEMBER(handle_mouse); | |
169 | TIMER_CALLBACK_MEMBER(read_COPS_command); | |
170 | TIMER_CALLBACK_MEMBER(set_COPS_ready); | |
168 | 171 | }; |
169 | 172 | |
170 | 173 |
r18113 | r18114 | |
---|---|---|
41 | 41 | emu_timer *m_led_update; |
42 | 42 | DECLARE_DRIVER_INIT(sym1); |
43 | 43 | virtual void machine_reset(); |
44 | TIMER_CALLBACK_MEMBER(led_refresh); | |
44 | 45 | }; |
45 | 46 | |
46 | 47 | /*----------- defined in machine/sym1.c -----------*/ |
r18113 | r18114 | |
---|---|---|
140 | 140 | virtual void machine_start(); |
141 | 141 | virtual void machine_reset(); |
142 | 142 | virtual void palette_init(); |
143 | TIMER_CALLBACK_MEMBER(lynx_blitter_timer); | |
144 | TIMER_CALLBACK_MEMBER(lynx_timer_shot); | |
145 | TIMER_CALLBACK_MEMBER(lynx_uart_loopback_timer); | |
146 | TIMER_CALLBACK_MEMBER(lynx_uart_timer); | |
143 | 147 | }; |
144 | 148 | |
145 | 149 |
r18113 | r18114 | |
---|---|---|
157 | 157 | virtual void palette_init(); |
158 | 158 | DECLARE_MACHINE_START(wscolor); |
159 | 159 | DECLARE_PALETTE_INIT(wscolor); |
160 | TIMER_CALLBACK_MEMBER(wswan_rtc_callback); | |
161 | TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt); | |
160 | 162 | }; |
161 | 163 | |
162 | 164 |
r18113 | r18114 | |
---|---|---|
82 | 82 | int m_fdc_drq; /* data request */ |
83 | 83 | int m_8n5; /* 5.25" / 8" drive select */ |
84 | 84 | int m_dsdd; /* double sided disk detect */ |
85 | TIMER_CALLBACK_MEMBER(bigboard_beepoff); | |
85 | 86 | }; |
86 | 87 | |
87 | 88 | class xerox820ii_state : public xerox820_state |
r18113 | r18114 | |
---|---|---|
268 | 268 | DECLARE_PALETTE_INIT(x68000); |
269 | 269 | UINT32 screen_update_x68000(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
270 | 270 | INTERRUPT_GEN_MEMBER(x68k_vsync_irq); |
271 | TIMER_CALLBACK_MEMBER(mfp_update_irq); | |
272 | TIMER_CALLBACK_MEMBER(mfp_timer_a_callback); | |
273 | TIMER_CALLBACK_MEMBER(mfp_timer_b_callback); | |
274 | TIMER_CALLBACK_MEMBER(mfp_timer_c_callback); | |
275 | TIMER_CALLBACK_MEMBER(mfp_timer_d_callback); | |
276 | TIMER_CALLBACK_MEMBER(x68k_led_callback); | |
277 | TIMER_CALLBACK_MEMBER(x68k_keyboard_poll); | |
278 | TIMER_CALLBACK_MEMBER(x68k_scc_ack); | |
279 | TIMER_CALLBACK_MEMBER(md_6button_port1_timeout); | |
280 | TIMER_CALLBACK_MEMBER(md_6button_port2_timeout); | |
281 | TIMER_CALLBACK_MEMBER(x68k_bus_error); | |
282 | TIMER_CALLBACK_MEMBER(x68k_net_irq); | |
283 | TIMER_CALLBACK_MEMBER(x68k_crtc_operation_end); | |
284 | TIMER_CALLBACK_MEMBER(x68k_hsync); | |
285 | TIMER_CALLBACK_MEMBER(x68k_crtc_raster_end); | |
286 | TIMER_CALLBACK_MEMBER(x68k_crtc_raster_irq); | |
287 | TIMER_CALLBACK_MEMBER(x68k_crtc_vblank_irq); | |
271 | 288 | }; |
272 | 289 | |
273 | 290 |
r18113 | r18114 | |
---|---|---|
80 | 80 | DECLARE_MACHINE_START(nc200); |
81 | 81 | DECLARE_MACHINE_RESET(nc200); |
82 | 82 | UINT32 screen_update_nc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
83 | TIMER_CALLBACK_MEMBER(nc_keyboard_timer_callback); | |
84 | TIMER_CALLBACK_MEMBER(nc_serial_timer_callback); | |
83 | 85 | }; |
84 | 86 | |
85 | 87 |
r18113 | r18114 | |
---|---|---|
186 | 186 | UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
187 | 187 | DECLARE_INPUT_CHANGED_MEMBER(lgun1_changed); |
188 | 188 | DECLARE_INPUT_CHANGED_MEMBER(lgun2_changed); |
189 | TIMER_CALLBACK_MEMBER(rapid_fire_callback); | |
190 | TIMER_CALLBACK_MEMBER(lightgun_tick); | |
191 | TIMER_CALLBACK_MEMBER(lphaser_1_callback); | |
192 | TIMER_CALLBACK_MEMBER(lphaser_2_callback); | |
189 | 193 | }; |
190 | 194 | |
191 | 195 |
r18113 | r18114 | |
---|---|---|
55 | 55 | |
56 | 56 | emu_timer *m_led_refresh_timer; |
57 | 57 | DECLARE_DRIVER_INIT(mpf1); |
58 | TIMER_CALLBACK_MEMBER(led_refresh); | |
58 | 59 | }; |
59 | 60 | |
60 | 61 | #endif |
r18113 | r18114 | |
---|---|---|
106 | 106 | DECLARE_MACHINE_RESET(z80ne_base); |
107 | 107 | DECLARE_INPUT_CHANGED_MEMBER(z80ne_reset); |
108 | 108 | DECLARE_INPUT_CHANGED_MEMBER(z80ne_nmi); |
109 | TIMER_CALLBACK_MEMBER(z80ne_cassette_tc); | |
110 | TIMER_CALLBACK_MEMBER(z80ne_kbd_scan); | |
109 | 111 | }; |
110 | 112 | |
111 | 113 |
r18113 | r18114 | |
---|---|---|
244 | 244 | virtual void video_start(); |
245 | 245 | virtual void palette_init(); |
246 | 246 | INTERRUPT_GEN_MEMBER(gamecom_interrupt); |
247 | TIMER_CALLBACK_MEMBER(gamecom_clock_timer_callback); | |
248 | TIMER_CALLBACK_MEMBER(gamecom_scanline); | |
247 | 249 | }; |
248 | 250 | |
249 | 251 |
r18113 | r18114 | |
---|---|---|
49 | 49 | UINT8 m_segment; |
50 | 50 | |
51 | 51 | emu_timer *m_led_refresh_timer; |
52 | TIMER_CALLBACK_MEMBER(led_refresh); | |
52 | 53 | }; |
53 | 54 | |
54 | 55 | #endif |
r18113 | r18114 | |
---|---|---|
39 | 39 | DECLARE_MACHINE_RESET(radio86); |
40 | 40 | DECLARE_PALETTE_INIT(radio86); |
41 | 41 | UINT32 screen_update_radio86(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
42 | TIMER_CALLBACK_MEMBER(radio86_reset); | |
42 | 43 | }; |
43 | 44 | |
44 | 45 |
r18113 | r18114 | |
---|---|---|
152 | 152 | virtual void machine_reset(); |
153 | 153 | virtual void video_start(); |
154 | 154 | UINT32 screen_update_cxhumax(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
155 | TIMER_CALLBACK_MEMBER(timer_tick); | |
155 | 156 | }; |
156 | 157 | |
157 | 158 | #define INTDEST 0 // Interrupt destination (1=IRQ, 0=FIQ) |
r18113 | r18114 | |
---|---|---|
27 | 27 | virtual void video_start(); |
28 | 28 | virtual void palette_init(); |
29 | 29 | UINT32 screen_update_lviv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
30 | TIMER_CALLBACK_MEMBER(lviv_reset); | |
30 | 31 | }; |
31 | 32 | |
32 | 33 |
r18113 | r18114 | |
---|---|---|
246 | 246 | DECLARE_MACHINE_START(gb_video); |
247 | 247 | DECLARE_MACHINE_START(gbc_video); |
248 | 248 | INTERRUPT_GEN_MEMBER(gb_scanline_interrupt); |
249 | TIMER_CALLBACK_MEMBER(gb_serial_timer_proc); | |
250 | TIMER_CALLBACK_MEMBER(gb_video_init_vbl); | |
251 | TIMER_CALLBACK_MEMBER(gb_lcd_timer_proc); | |
252 | TIMER_CALLBACK_MEMBER(gbc_lcd_timer_proc); | |
249 | 253 | }; |
250 | 254 | |
251 | 255 |
r18113 | r18114 | |
---|---|---|
202 | 202 | UINT32 screen_update_x1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
203 | 203 | DECLARE_INPUT_CHANGED_MEMBER(ipl_reset); |
204 | 204 | DECLARE_INPUT_CHANGED_MEMBER(nmi_reset); |
205 | TIMER_CALLBACK_MEMBER(x1_rtc_increment); | |
205 | 206 | }; |
206 | 207 | |
207 | 208 |
r18113 | r18114 | |
---|---|---|
108 | 108 | virtual void palette_init(); |
109 | 109 | DECLARE_MACHINE_START(telestrat); |
110 | 110 | UINT32 screen_update_oric(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
111 | TIMER_CALLBACK_MEMBER(oric_refresh_tape); | |
112 | TIMER_CALLBACK_MEMBER(oric_vh_timer_callback); | |
111 | 113 | }; |
112 | 114 | |
113 | 115 | /*----------- defined in machine/oric.c -----------*/ |
r18113 | r18114 | |
---|---|---|
35 | 35 | virtual void video_start(); |
36 | 36 | UINT32 screen_update_poly88(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
37 | 37 | INTERRUPT_GEN_MEMBER(poly88_interrupt); |
38 | TIMER_CALLBACK_MEMBER(poly88_usart_timer_callback); | |
39 | TIMER_CALLBACK_MEMBER(keyboard_callback); | |
40 | TIMER_CALLBACK_MEMBER(poly88_cassette_timer_callback); | |
41 | TIMER_CALLBACK_MEMBER(setup_machine_state); | |
38 | 42 | }; |
39 | 43 | |
40 | 44 |
r18113 | r18114 | |
---|---|---|
86 | 86 | UINT32 screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
87 | 87 | UINT32 screen_update_super80m(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
88 | 88 | void screen_eof_super80m(screen_device &screen, bool state); |
89 | TIMER_CALLBACK_MEMBER(super80_timer); | |
90 | TIMER_CALLBACK_MEMBER(super80_reset); | |
91 | TIMER_CALLBACK_MEMBER(super80_halfspeed); | |
89 | 92 | }; |
90 | 93 | |
91 | 94 |
r18113 | r18114 | |
---|---|---|
274 | 274 | floppy_image_device *floppy_devices[2]; |
275 | 275 | |
276 | 276 | static const floppy_format_type floppy_formats[]; |
277 | TIMER_CALLBACK_MEMBER(st_mouse_tick); | |
278 | TIMER_CALLBACK_MEMBER(atarist_shifter_tick); | |
279 | TIMER_CALLBACK_MEMBER(atarist_glue_tick); | |
280 | TIMER_CALLBACK_MEMBER(atarist_blitter_tick); | |
277 | 281 | }; |
278 | 282 | |
279 | 283 | class megast_state : public st_state |
r18113 | r18114 | |
327 | 331 | |
328 | 332 | DECLARE_READ8_MEMBER( mfp_gpio_r ); |
329 | 333 | |
334 | TIMER_CALLBACK_MEMBER(atariste_dmasound_tick); | |
335 | TIMER_CALLBACK_MEMBER(atariste_microwire_tick); | |
336 | ||
330 | 337 | void dmasound_set_state(int level); |
331 | 338 | void dmasound_tick(); |
332 | 339 | void microwire_shift(); |
r18113 | r18114 | |
---|---|---|
142 | 142 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
143 | 143 | DECLARE_MACHINE_START(pce); |
144 | 144 | DECLARE_MACHINE_RESET(mess_pce); |
145 | TIMER_CALLBACK_MEMBER(pce_cd_data_timer_callback); | |
146 | TIMER_CALLBACK_MEMBER(pce_cd_cdda_fadeout_callback); | |
147 | TIMER_CALLBACK_MEMBER(pce_cd_cdda_fadein_callback); | |
148 | TIMER_CALLBACK_MEMBER(pce_cd_adpcm_fadeout_callback); | |
149 | TIMER_CALLBACK_MEMBER(pce_cd_adpcm_fadein_callback); | |
150 | TIMER_CALLBACK_MEMBER(pce_cd_clear_ack); | |
151 | TIMER_CALLBACK_MEMBER(pce_cd_adpcm_dma_timer_callback); | |
145 | 152 | }; |
146 | 153 | |
147 | 154 |
r18113 | r18114 | |
---|---|---|
164 | 164 | virtual void machine_start(); |
165 | 165 | virtual void machine_reset(); |
166 | 166 | UINT32 screen_update_gp32(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
167 | TIMER_CALLBACK_MEMBER(s3c240x_lcd_timer_exp); | |
168 | TIMER_CALLBACK_MEMBER(s3c240x_pwm_timer_exp); | |
169 | TIMER_CALLBACK_MEMBER(s3c240x_dma_timer_exp); | |
170 | TIMER_CALLBACK_MEMBER(s3c240x_iic_timer_exp); | |
171 | TIMER_CALLBACK_MEMBER(s3c240x_iis_timer_exp); | |
167 | 172 | }; |
168 | 173 | |
169 | 174 |
r18113 | r18114 | |
---|---|---|
142 | 142 | DECLARE_MACHINE_START(apple2gsr1); |
143 | 143 | DECLARE_MACHINE_START(apple2gscommon); |
144 | 144 | UINT32 screen_update_apple2gs(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
145 | TIMER_CALLBACK_MEMBER(apple2gs_clock_tick); | |
146 | TIMER_CALLBACK_MEMBER(apple2gs_qsecond_tick); | |
147 | TIMER_CALLBACK_MEMBER(apple2gs_scanline_tick); | |
145 | 148 | }; |
146 | 149 | |
147 | 150 |
r18113 | r18114 | |
---|---|---|
260 | 260 | UINT8 m_prn_buffer[0x100]; |
261 | 261 | UINT8 m_prn_size; |
262 | 262 | virtual void palette_init(); |
263 | TIMER_CALLBACK_MEMBER(cassette_tick); | |
264 | TIMER_CALLBACK_MEMBER(cassette_poll); | |
265 | TIMER_CALLBACK_MEMBER(rsta_clear); | |
266 | TIMER_CALLBACK_MEMBER(rstb_clear); | |
267 | TIMER_CALLBACK_MEMBER(beep_stop); | |
263 | 268 | }; |
r18113 | r18114 | |
---|---|---|
285 | 285 | INTERRUPT_GEN_MEMBER(bbcb_vsync); |
286 | 286 | INTERRUPT_GEN_MEMBER(bbcb_keyscan); |
287 | 287 | INTERRUPT_GEN_MEMBER(bbcm_keyscan); |
288 | TIMER_CALLBACK_MEMBER(bbc_tape_timer_cb); | |
288 | 289 | }; |
289 | 290 | |
290 | 291 |
r18113 | r18114 | |
---|---|---|
49 | 49 | /* keyboard state */ |
50 | 50 | UINT8 m_keylatch; |
51 | 51 | DECLARE_DRIVER_INIT(studio2); |
52 | TIMER_CALLBACK_MEMBER(setup_beep); | |
52 | 53 | }; |
53 | 54 | |
54 | 55 | class visicom_state : public studio2_state |
r18113 | r18114 | |
---|---|---|
240 | 240 | virtual void machine_start(); |
241 | 241 | virtual void machine_reset(); |
242 | 242 | virtual void palette_init(); |
243 | TIMER_CALLBACK_MEMBER(dma_complete); | |
244 | TIMER_CALLBACK_MEMBER(timer_expire); | |
245 | TIMER_CALLBACK_MEMBER(handle_irq); | |
246 | TIMER_CALLBACK_MEMBER(perform_hbl); | |
247 | TIMER_CALLBACK_MEMBER(perform_scan); | |
243 | 248 | }; |
244 | 249 | |
245 | 250 | /*----------- defined in video/gba.c -----------*/ |
r18113 | r18114 | |
---|---|---|
239 | 239 | DECLARE_MACHINE_START(fm11); |
240 | 240 | DECLARE_MACHINE_START(fm16); |
241 | 241 | UINT32 screen_update_fm7(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
242 | TIMER_CALLBACK_MEMBER(fm7_beeper_off); | |
243 | TIMER_CALLBACK_MEMBER(fm77av_encoder_ack); | |
244 | TIMER_CALLBACK_MEMBER(fm7_timer_irq); | |
245 | TIMER_CALLBACK_MEMBER(fm7_subtimer_irq); | |
246 | TIMER_CALLBACK_MEMBER(fm7_keyboard_poll); | |
247 | TIMER_CALLBACK_MEMBER(fm77av_alu_task_end); | |
248 | TIMER_CALLBACK_MEMBER(fm77av_vsync); | |
242 | 249 | }; |
243 | 250 | |
244 | 251 | /*----------- defined in video/fm7.c -----------*/ |
r18113 | r18114 | |
---|---|---|
27 | 27 | |
28 | 28 | DECLARE_DRIVER_INIT(pc1251); |
29 | 29 | UINT32 screen_update_pc1251(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
30 | TIMER_CALLBACK_MEMBER(pc1251_power_up); | |
30 | 31 | }; |
31 | 32 | |
32 | 33 |
r18113 | r18114 | |
---|---|---|
64 | 64 | |
65 | 65 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
66 | 66 | virtual void palette_init(); |
67 | TIMER_CALLBACK_MEMBER(pokemini_seconds_timer_callback); | |
68 | TIMER_CALLBACK_MEMBER(pokemini_256hz_timer_callback); | |
69 | TIMER_CALLBACK_MEMBER(pokemini_timer1_callback); | |
70 | TIMER_CALLBACK_MEMBER(pokemini_timer1_hi_callback); | |
71 | TIMER_CALLBACK_MEMBER(pokemini_timer2_callback); | |
72 | TIMER_CALLBACK_MEMBER(pokemini_timer2_hi_callback); | |
73 | TIMER_CALLBACK_MEMBER(pokemini_timer3_callback); | |
74 | TIMER_CALLBACK_MEMBER(pokemini_timer3_hi_callback); | |
75 | TIMER_CALLBACK_MEMBER(pokemini_prc_counter_callback); | |
67 | 76 | }; |
68 | 77 | |
69 | 78 |
r18113 | r18114 | |
---|---|---|
134 | 134 | UINT32 screen_update_intvkbd(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
135 | 135 | INTERRUPT_GEN_MEMBER(intv_interrupt2); |
136 | 136 | INTERRUPT_GEN_MEMBER(intv_interrupt); |
137 | TIMER_CALLBACK_MEMBER(intv_interrupt2_complete); | |
138 | TIMER_CALLBACK_MEMBER(intv_interrupt_complete); | |
139 | TIMER_CALLBACK_MEMBER(intv_btb_fill); | |
137 | 140 | }; |
138 | 141 | |
139 | 142 | /*----------- defined in video/intv.c -----------*/ |
r18113 | r18114 | |
---|---|---|
57 | 57 | required_device<cassette_image_device> m_cass1; |
58 | 58 | required_device<cassette_image_device> m_cass2; |
59 | 59 | virtual void machine_start(); |
60 | TIMER_CALLBACK_MEMBER(aim65_printer_timer); | |
60 | 61 | }; |
61 | 62 | |
62 | 63 |
r18113 | r18114 | |
---|---|---|
33 | 33 | DECLARE_MACHINE_RESET(galaxyp); |
34 | 34 | UINT32 screen_update_galaxy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
35 | 35 | INTERRUPT_GEN_MEMBER(galaxy_interrupt); |
36 | TIMER_CALLBACK_MEMBER(gal_video); | |
36 | 37 | }; |
37 | 38 | |
38 | 39 |
r18113 | r18114 | |
---|---|---|
188 | 188 | virtual void palette_init(); |
189 | 189 | UINT32 screen_update_compis2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
190 | 190 | INTERRUPT_GEN_MEMBER(compis_vblank_int); |
191 | TIMER_CALLBACK_MEMBER(internal_timer_int); | |
192 | TIMER_CALLBACK_MEMBER(dma_timer_callback); | |
191 | 193 | }; |
192 | 194 | |
193 | 195 |
r18113 | r18114 | |
---|---|---|
137 | 137 | DECLARE_MACHINE_START(hec2mdhrx); |
138 | 138 | DECLARE_MACHINE_RESET(hec2mdhrx); |
139 | 139 | UINT32 screen_update_hec2hrp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
140 | TIMER_CALLBACK_MEMBER(Callback_CK); | |
140 | 141 | }; |
141 | 142 | |
142 | 143 | /*----------- defined in machine/hec2hrp.c -----------*/ |
r18113 | r18114 | |
---|---|---|
49 | 49 | /* keyboard state */ |
50 | 50 | int m_keylatch; /* key latch */ |
51 | 51 | DECLARE_DRIVER_INIT(tmc1800); |
52 | TIMER_CALLBACK_MEMBER(setup_beep); | |
52 | 53 | }; |
53 | 54 | |
54 | 55 | class osc1000b_state : public driver_device |
r18113 | r18114 | |
---|---|---|
276 | 276 | void wait_end(); |
277 | 277 | public: |
278 | 278 | INTERRUPT_GEN_MEMBER(towns_vsync_irq); |
279 | TIMER_CALLBACK_MEMBER(towns_cd_status_ready); | |
280 | TIMER_CALLBACK_MEMBER(towns_cdrom_read_byte); | |
281 | TIMER_CALLBACK_MEMBER(towns_delay_cdda); | |
282 | TIMER_CALLBACK_MEMBER(towns_sprite_done); | |
283 | TIMER_CALLBACK_MEMBER(towns_vblank_end); | |
279 | 284 | }; |
280 | 285 | |
281 | 286 | class marty_state : public towns_state |
r18113 | r18114 | |
---|---|---|
81 | 81 | virtual void video_start(); |
82 | 82 | virtual void palette_init(); |
83 | 83 | UINT32 screen_update_dai(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
84 | TIMER_CALLBACK_MEMBER(dai_bootstrap_callback); | |
85 | TIMER_CALLBACK_MEMBER(dai_timer); | |
84 | 86 | }; |
85 | 87 | |
86 | 88 |
r18113 | r18114 | |
---|---|---|
40 | 40 | virtual void video_start(); |
41 | 41 | virtual void palette_init(); |
42 | 42 | UINT32 screen_update_pmd85(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
43 | TIMER_CALLBACK_MEMBER(pmd85_cassette_timer_callback); | |
44 | TIMER_CALLBACK_MEMBER(pmd_reset); | |
45 | TIMER_CALLBACK_MEMBER(setup_machine_state); | |
43 | 46 | }; |
44 | 47 | |
45 | 48 |
r18113 | r18114 | |
---|---|---|
523 | 523 | UINT32 screen_update_macrbvvram(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
524 | 524 | UINT32 screen_update_macpbwd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
525 | 525 | INTERRUPT_GEN_MEMBER(mac_rbv_vbl); |
526 | TIMER_CALLBACK_MEMBER(kbd_clock); | |
527 | TIMER_CALLBACK_MEMBER(inquiry_timeout_func); | |
528 | TIMER_CALLBACK_MEMBER(mac_6015_tick); | |
529 | TIMER_CALLBACK_MEMBER(mac_scanline_tick); | |
530 | TIMER_CALLBACK_MEMBER(dafb_vbl_tick); | |
531 | TIMER_CALLBACK_MEMBER(dafb_cursor_tick); | |
526 | 532 | }; |
527 | 533 | |
528 | 534 | #endif /* MAC_H_ */ |
r18113 | r18114 | |
---|---|---|
25 | 25 | virtual void video_start(); |
26 | 26 | UINT32 screen_update_ondra(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
27 | 27 | INTERRUPT_GEN_MEMBER(ondra_interrupt); |
28 | TIMER_CALLBACK_MEMBER(nmi_check_callback); | |
28 | 29 | }; |
29 | 30 | |
30 | 31 | #endif |
r18113 | r18114 | |
---|---|---|
27 | 27 | UINT8 m_reg[0x100]; |
28 | 28 | DECLARE_DRIVER_INIT(pc1401); |
29 | 29 | UINT32 screen_update_pc1401(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
30 | TIMER_CALLBACK_MEMBER(pc1401_power_up); | |
30 | 31 | }; |
31 | 32 | |
32 | 33 |
r18113 | r18114 | |
---|---|---|
48 | 48 | DECLARE_MACHINE_START(ut88mini); |
49 | 49 | DECLARE_MACHINE_RESET(ut88mini); |
50 | 50 | UINT32 screen_update_ut88(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
51 | TIMER_CALLBACK_MEMBER(ut88_reset); | |
52 | TIMER_CALLBACK_MEMBER(update_display); | |
51 | 53 | }; |
52 | 54 | |
53 | 55 |
r18113 | r18114 | |
---|---|---|
94 | 94 | UINT32 screen_update_erik(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
95 | 95 | UINT32 screen_update_specialp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
96 | 96 | UINT32 screen_update_specimx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
97 | TIMER_CALLBACK_MEMBER(special_reset); | |
98 | TIMER_CALLBACK_MEMBER(setup_pit8253_gates); | |
97 | 99 | }; |
98 | 100 | |
99 | 101 |
r18113 | r18114 | |
---|---|---|
124 | 124 | virtual void video_start(); |
125 | 125 | virtual void palette_init(); |
126 | 126 | UINT32 screen_update_nes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
127 | TIMER_CALLBACK_MEMBER(nes_irq_callback); | |
128 | TIMER_CALLBACK_MEMBER(lightgun_tick); | |
127 | 129 | }; |
128 | 130 | |
129 | 131 | /*----------- defined in machine/nes.c -----------*/ |
r18113 | r18114 | |
---|---|---|
102 | 102 | DECLARE_MACHINE_START(ti86); |
103 | 103 | DECLARE_MACHINE_START(ti83p); |
104 | 104 | UINT32 screen_update_ti85(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
105 | TIMER_CALLBACK_MEMBER(ti85_timer_callback); | |
105 | 106 | }; |
106 | 107 | |
107 | 108 |
r18113 | r18114 | |
---|---|---|
34 | 34 | virtual void machine_reset(); |
35 | 35 | virtual void video_start(); |
36 | 36 | UINT32 screen_update_mikro80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
37 | TIMER_CALLBACK_MEMBER(mikro80_reset); | |
37 | 38 | }; |
38 | 39 | |
39 | 40 |
r18113 | r18114 | |
---|---|---|
170 | 170 | UINT32 screen_update_amstrad(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
171 | 171 | void screen_eof_amstrad(screen_device &screen, bool state); |
172 | 172 | DECLARE_INPUT_CHANGED_MEMBER(cpc_monitor_changed); |
173 | TIMER_CALLBACK_MEMBER(amstrad_pc2_low); | |
174 | TIMER_CALLBACK_MEMBER(amstrad_video_update_timer); | |
175 | TIMER_CALLBACK_MEMBER(cb_set_resolution); | |
173 | 176 | }; |
174 | 177 | |
175 | 178 |
r18113 | r18114 | |
---|---|---|
158 | 158 | public: |
159 | 159 | emu_timer *m_scanline_timer; |
160 | 160 | UINT32 screen_update_pippin(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
161 | TIMER_CALLBACK_MEMBER(mac_6015_tick); | |
161 | 162 | }; |
162 | 163 | |
163 | 164 | #endif /* PCIMAC_H_ */ |
r18113 | r18114 | |
---|---|---|
37 | 37 | virtual void machine_reset(); |
38 | 38 | virtual void video_start(); |
39 | 39 | UINT32 screen_update_bk0010(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
40 | TIMER_CALLBACK_MEMBER(keyboard_callback); | |
40 | 41 | }; |
41 | 42 | |
42 | 43 | #endif /* BK_H_ */ |
r18113 | r18114 | |
---|---|---|
125 | 125 | int keyboard_decode(); |
126 | 126 | void update_screen(bitmap_ind16 &bitmap); |
127 | 127 | UINT32 screen_update_rm380z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
128 | TIMER_CALLBACK_MEMBER(static_vblank_timer); | |
128 | 129 | }; |
129 | 130 | |
130 | 131 |
r18113 | r18114 | |
---|---|---|
25 | 25 | int m_power; |
26 | 26 | UINT8 m_reg[0x1000]; |
27 | 27 | UINT32 screen_update_pc1350(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
28 | TIMER_CALLBACK_MEMBER(pc1350_power_up); | |
28 | 29 | }; |
29 | 30 | |
30 | 31 |
r18113 | r18114 | |
---|---|---|
57 | 57 | UINT32 screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
58 | 58 | UINT32 screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
59 | 59 | INTERRUPT_GEN_MEMBER(svision_frame_int); |
60 | TIMER_CALLBACK_MEMBER(svision_pet_timer); | |
61 | TIMER_CALLBACK_MEMBER(svision_timer); | |
60 | 62 | }; |
61 | 63 | |
62 | 64 |
r18113 | r18114 | |
---|---|---|
41 | 41 | DECLARE_DRIVER_INIT(bebox); |
42 | 42 | virtual void machine_start(); |
43 | 43 | virtual void machine_reset(); |
44 | TIMER_CALLBACK_MEMBER(bebox_get_devices); | |
44 | 45 | }; |
45 | 46 | |
46 | 47 |
r18113 | r18114 | |
---|---|---|
262 | 262 | UINT32 screen_update_pdp1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
263 | 263 | void screen_eof_pdp1(screen_device &screen, bool state); |
264 | 264 | INTERRUPT_GEN_MEMBER(pdp1_interrupt); |
265 | TIMER_CALLBACK_MEMBER(reader_callback); | |
266 | TIMER_CALLBACK_MEMBER(puncher_callback); | |
267 | TIMER_CALLBACK_MEMBER(tyo_callback); | |
268 | TIMER_CALLBACK_MEMBER(dpy_callback); | |
269 | TIMER_CALLBACK_MEMBER(il_timer_callback); | |
265 | 270 | }; |
266 | 271 | |
267 | 272 | /*----------- defined in video/pdp1.c -----------*/ |
r18113 | r18114 | |
---|---|---|
65 | 65 | virtual void palette_init(); |
66 | 66 | UINT32 screen_update_vector06(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
67 | 67 | INTERRUPT_GEN_MEMBER(vector06_interrupt); |
68 | TIMER_CALLBACK_MEMBER(reset_check_callback); | |
68 | 69 | }; |
69 | 70 | |
70 | 71 |
r18113 | r18114 | |
---|---|---|
75 | 75 | virtual void video_start(); |
76 | 76 | virtual void palette_init(); |
77 | 77 | UINT32 screen_update_electron(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
78 | TIMER_CALLBACK_MEMBER(electron_tape_timer_handler); | |
79 | TIMER_CALLBACK_MEMBER(setup_beep); | |
80 | TIMER_CALLBACK_MEMBER(electron_scanline_interrupt); | |
78 | 81 | }; |
79 | 82 | |
80 | 83 |
r18113 | r18114 | |
---|---|---|
153 | 153 | UINT32 screen_update_tx0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
154 | 154 | void screen_eof_tx0(screen_device &screen, bool state); |
155 | 155 | INTERRUPT_GEN_MEMBER(tx0_interrupt); |
156 | TIMER_CALLBACK_MEMBER(reader_callback); | |
157 | TIMER_CALLBACK_MEMBER(puncher_callback); | |
158 | TIMER_CALLBACK_MEMBER(prt_callback); | |
159 | TIMER_CALLBACK_MEMBER(dis_callback); | |
156 | 160 | }; |
157 | 161 | |
158 | 162 |
r18113 | r18114 | |
---|---|---|
35 | 35 | |
36 | 36 | */ |
37 | 37 | |
38 | static TIMER_CALLBACK( electron_scanline_interrupt ); | |
39 | 38 | |
40 | 39 | |
40 | ||
41 | 41 | void electron_state::video_start() |
42 | 42 | { |
43 | 43 | int i; |
r18113 | r18114 | |
45 | 45 | m_map4[i] = ( ( i & 0x10 ) >> 3 ) | ( i & 0x01 ); |
46 | 46 | m_map16[i] = ( ( i & 0x40 ) >> 3 ) | ( ( i & 0x10 ) >> 2 ) | ( ( i & 0x04 ) >> 1 ) | ( i & 0x01 ); |
47 | 47 | } |
48 | m_scanline_timer = machine().scheduler().timer_alloc(FUNC(electron_scanline_interrupt)); | |
48 | m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(electron_state::electron_scanline_interrupt),this)); | |
49 | 49 | m_scanline_timer->adjust( machine().primary_screen->time_until_pos(0), 0, machine().primary_screen->scan_period() ); |
50 | 50 | } |
51 | 51 | |
r18113 | r18114 | |
254 | 254 | return 0; |
255 | 255 | } |
256 | 256 | |
257 | ||
257 | TIMER_CALLBACK_MEMBER(electron_state::electron_scanline_interrupt) | |
258 | 258 | { |
259 | electron_state *state = machine.driver_data<electron_state>(); | |
260 | switch (machine.primary_screen->vpos()) | |
259 | switch (machine().primary_screen->vpos()) | |
261 | 260 | { |
262 | 261 | case 43: |
263 | electron_interrupt_handler( machine, INT_SET, INT_RTC ); | |
262 | electron_interrupt_handler( machine(), INT_SET, INT_RTC ); | |
264 | 263 | break; |
265 | 264 | case 199: |
266 | electron_interrupt_handler( machine, INT_SET, INT_DISPLAY_END ); | |
265 | electron_interrupt_handler( machine(), INT_SET, INT_DISPLAY_END ); | |
267 | 266 | break; |
268 | 267 | case 0: |
269 | | |
268 | m_ula.screen_addr = m_ula.screen_start - m_ula.screen_base; | |
270 | 269 | break; |
271 | 270 | } |
272 | 271 | } |
r18113 | r18114 | |
---|---|---|
47 | 47 | |
48 | 48 | |
49 | 49 | /* Prototypes */ |
50 | static TIMER_CALLBACK(gb_lcd_timer_proc); | |
51 | static TIMER_CALLBACK(gbc_lcd_timer_proc); | |
50 | ||
51 | ||
52 | 52 | static void gb_lcd_switch_on( running_machine &machine ); |
53 | 53 | |
54 | 54 | static const unsigned char palette[] = |
r18113 | r18114 | |
1194 | 1194 | GB_LCD_STATE_LY00_M0 |
1195 | 1195 | }; |
1196 | 1196 | |
1197 | ||
1197 | TIMER_CALLBACK_MEMBER(gb_state::gb_video_init_vbl) | |
1198 | 1198 | { |
1199 | machine.device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1199 | machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1200 | 1200 | } |
1201 | 1201 | |
1202 | 1202 | MACHINE_START_MEMBER(gb_state,gb_video) |
1203 | 1203 | { |
1204 | m_lcd.lcd_timer = machine().scheduler().timer_alloc(FUNC(gb_lcd_timer_proc)); | |
1204 | m_lcd.lcd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gb_lcd_timer_proc),this)); | |
1205 | 1205 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
1206 | 1206 | } |
1207 | 1207 | |
1208 | 1208 | MACHINE_START_MEMBER(gb_state,gbc_video) |
1209 | 1209 | { |
1210 | m_lcd.lcd_timer = machine().scheduler().timer_alloc(FUNC(gbc_lcd_timer_proc)); | |
1210 | m_lcd.lcd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gb_state::gbc_lcd_timer_proc),this)); | |
1211 | 1211 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
1212 | 1212 | } |
1213 | 1213 | |
r18113 | r18114 | |
1288 | 1288 | memcpy( state->m_lcd.gb_oam->base(), mgb_oam_fingerprint, 0x100 ); |
1289 | 1289 | |
1290 | 1290 | /* Make sure the VBlank interrupt is set when the first instruction gets executed */ |
1291 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(1), FUNC(gb_video_init_vbl)); | |
1291 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(1), timer_expired_delegate(FUNC(gb_state::gb_video_init_vbl),state)); | |
1292 | 1292 | |
1293 | 1293 | /* Initialize some video registers */ |
1294 | 1294 | state->gb_video_w( space, 0x0, 0x91 ); /* LCDCONT */ |
r18113 | r18114 | |
1367 | 1367 | } |
1368 | 1368 | } |
1369 | 1369 | |
1370 | ||
1370 | TIMER_CALLBACK_MEMBER(gb_state::gb_lcd_timer_proc) | |
1371 | 1371 | { |
1372 | gb_state *state = machine.driver_data<gb_state>(); | |
1372 | gb_state *state = machine().driver_data<gb_state>(); | |
1373 | 1373 | static const int sprite_cycles[] = { 0, 8, 20, 32, 44, 52, 64, 76, 88, 96, 108 }; |
1374 | 1374 | |
1375 | | |
1375 | m_lcd.state = param; | |
1376 | 1376 | |
1377 | 1377 | if ( LCDCONT & 0x80 ) |
1378 | 1378 | { |
1379 | switch( | |
1379 | switch( m_lcd.state ) | |
1380 | 1380 | { |
1381 | 1381 | case GB_LCD_STATE_LYXX_PRE_M0: /* Just before switching to mode 0 */ |
1382 | | |
1382 | m_lcd.mode = 0; | |
1383 | 1383 | if ( LCDSTAT & 0x08 ) |
1384 | 1384 | { |
1385 | if ( ! | |
1385 | if ( ! m_lcd.mode_irq ) | |
1386 | 1386 | { |
1387 | if ( ! | |
1387 | if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq ) | |
1388 | 1388 | { |
1389 | state->m_lcd.mode_irq = 1; | |
1390 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1389 | m_lcd.mode_irq = 1; | |
1390 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1391 | 1391 | } |
1392 | 1392 | } |
1393 | 1393 | else |
1394 | 1394 | { |
1395 | | |
1395 | m_lcd.mode_irq = 0; | |
1396 | 1396 | } |
1397 | 1397 | } |
1398 | | |
1398 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0); | |
1399 | 1399 | break; |
1400 | 1400 | case GB_LCD_STATE_LYXX_M0: /* Switch to mode 0 */ |
1401 | 1401 | /* update current scanline */ |
1402 | (* | |
1402 | (*update_scanline)( machine() ); | |
1403 | 1403 | /* Increment the number of window lines drawn if enabled */ |
1404 | if ( | |
1404 | if ( m_lcd.layer[1].enabled ) | |
1405 | 1405 | { |
1406 | | |
1406 | m_lcd.window_lines_drawn++; | |
1407 | 1407 | } |
1408 | | |
1408 | m_lcd.previous_line = m_lcd.current_line; | |
1409 | 1409 | /* Set Mode 0 lcdstate */ |
1410 | | |
1410 | m_lcd.mode = 0; | |
1411 | 1411 | LCDSTAT &= 0xFC; |
1412 | state->m_lcd.oam_locked = UNLOCKED; | |
1413 | state->m_lcd.vram_locked = UNLOCKED; | |
1412 | m_lcd.oam_locked = UNLOCKED; | |
1413 | m_lcd.vram_locked = UNLOCKED; | |
1414 | 1414 | /* |
1415 | 1415 | There seems to a kind of feature in the Game Boy hardware when the lowest bits of the |
1416 | 1416 | SCROLLX register equals 3 or 7, then the delayed M0 irq is triggered 4 cycles later |
r18113 | r18114 | |
1419 | 1419 | */ |
1420 | 1420 | if ( ( SCROLLX & 0x03 ) == 0x03 ) |
1421 | 1421 | { |
1422 | state->m_lcd.scrollx_adjust += 4; | |
1423 | state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3); | |
1422 | m_lcd.scrollx_adjust += 4; | |
1423 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3); | |
1424 | 1424 | break; |
1425 | 1425 | } |
1426 | 1426 | case GB_LCD_STATE_LYXX_M0_SCX3: |
1427 | 1427 | /* Generate lcd interrupt if requested */ |
1428 | if ( ! state->m_lcd.mode_irq && ( LCDSTAT & 0x08 ) && | |
1429 | ( ( ! state->m_lcd.line_irq && state->m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1428 | if ( ! m_lcd.mode_irq && ( LCDSTAT & 0x08 ) && | |
1429 | ( ( ! m_lcd.line_irq && m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1430 | 1430 | { |
1431 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1431 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1432 | 1432 | } |
1433 | | |
1433 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(196 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC); | |
1434 | 1434 | break; |
1435 | 1435 | case GB_LCD_STATE_LYXX_M0_PRE_INC: /* Just before incrementing the line counter go to mode 2 internally */ |
1436 | 1436 | if ( CURLINE < 143 ) |
1437 | 1437 | { |
1438 | state->m_lcd.mode = 2; | |
1439 | state->m_lcd.triggering_mode_irq = ( LCDSTAT & 0x20 ) ? 1 : 0; | |
1440 | if ( state->m_lcd.triggering_mode_irq ) | |
1438 | m_lcd.mode = 2; | |
1439 | m_lcd.triggering_mode_irq = ( LCDSTAT & 0x20 ) ? 1 : 0; | |
1440 | if ( m_lcd.triggering_mode_irq ) | |
1441 | 1441 | { |
1442 | if ( ! | |
1442 | if ( ! m_lcd.mode_irq ) | |
1443 | 1443 | { |
1444 | if ( ! | |
1444 | if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq ) | |
1445 | 1445 | { |
1446 | state->m_lcd.mode_irq = 1; | |
1447 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1446 | m_lcd.mode_irq = 1; | |
1447 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1448 | 1448 | } |
1449 | 1449 | } |
1450 | 1450 | else |
1451 | 1451 | { |
1452 | | |
1452 | m_lcd.mode_irq = 0; | |
1453 | 1453 | } |
1454 | 1454 | } |
1455 | 1455 | } |
1456 | | |
1456 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC); | |
1457 | 1457 | break; |
1458 | 1458 | case GB_LCD_STATE_LYXX_M0_INC: /* Increment LY, stay in M0 for 4 more cycles */ |
1459 | gb_increment_scanline(state); | |
1460 | state->m_lcd.delayed_line_irq = state->m_lcd.line_irq; | |
1461 | state->m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1462 | state->m_lcd.line_irq = 0; | |
1463 | if ( ! state->m_lcd.mode_irq && ! state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq && ! state->m_lcd.triggering_mode_irq ) | |
1459 | gb_increment_scanline(this); | |
1460 | m_lcd.delayed_line_irq = m_lcd.line_irq; | |
1461 | m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1462 | m_lcd.line_irq = 0; | |
1463 | if ( ! m_lcd.mode_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! m_lcd.triggering_mode_irq ) | |
1464 | 1464 | { |
1465 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1466 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1465 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1466 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1467 | 1467 | } |
1468 | 1468 | /* Reset LY==LYC STAT bit */ |
1469 | 1469 | LCDSTAT &= 0xFB; |
1470 | 1470 | /* Check if we're going into VBlank next */ |
1471 | 1471 | if ( CURLINE == 144 ) |
1472 | 1472 | { |
1473 | | |
1473 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1); | |
1474 | 1474 | } |
1475 | 1475 | else |
1476 | 1476 | { |
1477 | 1477 | /* Internally switch to mode 2 */ |
1478 | | |
1478 | m_lcd.mode = 2; | |
1479 | 1479 | /* Generate lcd interrupt if requested */ |
1480 | if ( ! state->m_lcd.mode_irq && state->m_lcd.triggering_mode_irq && | |
1481 | ( ( ! state->m_lcd.triggering_line_irq && ! state->m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1480 | if ( ! m_lcd.mode_irq && m_lcd.triggering_mode_irq && | |
1481 | ( ( ! m_lcd.triggering_line_irq && ! m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1482 | 1482 | { |
1483 | state->m_lcd.mode_irq = 1; | |
1484 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1483 | m_lcd.mode_irq = 1; | |
1484 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1485 | 1485 | } |
1486 | | |
1486 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2); | |
1487 | 1487 | } |
1488 | 1488 | break; |
1489 | 1489 | case GB_LCD_STATE_LY00_M2: /* Switch to mode 2 on line #0 */ |
1490 | 1490 | /* Set Mode 2 lcdstate */ |
1491 | | |
1491 | m_lcd.mode = 2; | |
1492 | 1492 | LCDSTAT = ( LCDSTAT & 0xFC ) | 0x02; |
1493 | | |
1493 | m_lcd.oam_locked = LOCKED; | |
1494 | 1494 | /* Generate lcd interrupt if requested */ |
1495 | if ( ( LCDSTAT & 0x20 ) && ! | |
1495 | if ( ( LCDSTAT & 0x20 ) && ! m_lcd.line_irq ) | |
1496 | 1496 | { |
1497 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1497 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1498 | 1498 | } |
1499 | 1499 | /* Check for regular compensation of x-scroll register */ |
1500 | | |
1500 | m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0; | |
1501 | 1501 | /* Mode 2 lasts approximately 80 clock cycles */ |
1502 | | |
1502 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3); | |
1503 | 1503 | break; |
1504 | 1504 | case GB_LCD_STATE_LYXX_M2: /* Switch to mode 2 */ |
1505 | 1505 | /* Update STAT register to the correct state */ |
1506 | 1506 | LCDSTAT = (LCDSTAT & 0xFC) | 0x02; |
1507 | | |
1507 | m_lcd.oam_locked = LOCKED; | |
1508 | 1508 | /* Generate lcd interrupt if requested */ |
1509 | if ( ( state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) || | |
1510 | ( ! state->m_lcd.mode_irq && ! state->m_lcd.line_irq && ! state->m_lcd.delayed_line_irq && state->m_lcd.triggering_mode_irq ) ) | |
1509 | if ( ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) || | |
1510 | ( ! m_lcd.mode_irq && ! m_lcd.line_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_mode_irq ) ) | |
1511 | 1511 | { |
1512 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1512 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1513 | 1513 | } |
1514 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1515 | state->m_lcd.triggering_mode_irq = 0; | |
1514 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1515 | m_lcd.triggering_mode_irq = 0; | |
1516 | 1516 | /* Check if LY==LYC STAT bit should be set */ |
1517 | 1517 | if ( CURLINE == CMPLINE ) |
1518 | 1518 | { |
1519 | 1519 | LCDSTAT |= 0x04; |
1520 | 1520 | } |
1521 | 1521 | /* Check for regular compensation of x-scroll register */ |
1522 | | |
1522 | m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0; | |
1523 | 1523 | /* Mode 2 last for approximately 80 clock cycles */ |
1524 | | |
1524 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3); | |
1525 | 1525 | break; |
1526 | 1526 | case GB_LCD_STATE_LYXX_M3: /* Switch to mode 3 */ |
1527 | gb_select_sprites(state); | |
1528 | state->m_lcd.sprite_cycles = sprite_cycles[ state->m_lcd.sprCount ]; | |
1527 | gb_select_sprites(this); | |
1528 | m_lcd.sprite_cycles = sprite_cycles[ m_lcd.sprCount ]; | |
1529 | 1529 | /* Set Mode 3 lcdstate */ |
1530 | | |
1530 | m_lcd.mode = 3; | |
1531 | 1531 | LCDSTAT = (LCDSTAT & 0xFC) | 0x03; |
1532 | | |
1532 | m_lcd.vram_locked = LOCKED; | |
1533 | 1533 | /* Check for compensations of x-scroll register */ |
1534 | 1534 | /* Mode 3 lasts for approximately 172+cycles needed to handle sprites clock cycles */ |
1535 | state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(168 + state->m_lcd.scrollx_adjust + state->m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0); | |
1536 | state->m_lcd.start_x = -1; | |
1535 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0); | |
1536 | m_lcd.start_x = -1; | |
1537 | 1537 | break; |
1538 | 1538 | case GB_LCD_STATE_LY9X_M1: /* Switch to or stay in mode 1 */ |
1539 | 1539 | if ( CURLINE == 144 ) |
1540 | 1540 | { |
1541 | 1541 | /* Trigger VBlank interrupt */ |
1542 | machine.device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1542 | machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1543 | 1543 | /* Set VBlank lcdstate */ |
1544 | | |
1544 | m_lcd.mode = 1; | |
1545 | 1545 | LCDSTAT = (LCDSTAT & 0xFC) | 0x01; |
1546 | 1546 | /* Trigger LCD interrupt if requested */ |
1547 | 1547 | if ( LCDSTAT & 0x10 ) |
1548 | 1548 | { |
1549 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1549 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1550 | 1550 | } |
1551 | 1551 | } |
1552 | 1552 | /* Check if LY==LYC STAT bit should be set */ |
r18113 | r18114 | |
1554 | 1554 | { |
1555 | 1555 | LCDSTAT |= 0x04; |
1556 | 1556 | } |
1557 | if ( | |
1557 | if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1558 | 1558 | { |
1559 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1559 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1560 | 1560 | } |
1561 | | |
1561 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC); | |
1562 | 1562 | break; |
1563 | 1563 | case GB_LCD_STATE_LY9X_M1_INC: /* Increment scanline counter */ |
1564 | gb_increment_scanline(state); | |
1565 | state->m_lcd.delayed_line_irq = state->m_lcd.line_irq; | |
1566 | state->m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1567 | state->m_lcd.line_irq = 0; | |
1568 | if ( ! state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq ) | |
1564 | gb_increment_scanline(this); | |
1565 | m_lcd.delayed_line_irq = m_lcd.line_irq; | |
1566 | m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1567 | m_lcd.line_irq = 0; | |
1568 | if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1569 | 1569 | { |
1570 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1571 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1570 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1571 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1572 | 1572 | } |
1573 | 1573 | /* Reset LY==LYC STAT bit */ |
1574 | 1574 | LCDSTAT &= 0xFB; |
1575 | if ( | |
1575 | if ( m_lcd.current_line == 153 ) | |
1576 | 1576 | { |
1577 | | |
1577 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1); | |
1578 | 1578 | } |
1579 | 1579 | else |
1580 | 1580 | { |
1581 | | |
1581 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1); | |
1582 | 1582 | } |
1583 | 1583 | break; |
1584 | 1584 | case GB_LCD_STATE_LY00_M1: /* we stay in VBlank but current line counter should already be incremented */ |
1585 | 1585 | /* Check LY=LYC for line #153 */ |
1586 | if ( | |
1586 | if ( m_lcd.delayed_line_irq ) | |
1587 | 1587 | { |
1588 | if ( | |
1588 | if ( m_lcd.triggering_line_irq ) | |
1589 | 1589 | { |
1590 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1590 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1591 | 1591 | } |
1592 | 1592 | } |
1593 | | |
1593 | m_lcd.delayed_line_irq = m_lcd.delayed_line_irq | m_lcd.line_irq; | |
1594 | 1594 | if ( CURLINE == CMPLINE ) |
1595 | 1595 | { |
1596 | 1596 | LCDSTAT |= 0x04; |
1597 | 1597 | } |
1598 | gb_increment_scanline(state); | |
1599 | state->m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1600 | state->m_lcd.line_irq = 0; | |
1598 | gb_increment_scanline(this); | |
1599 | m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1600 | m_lcd.line_irq = 0; | |
1601 | 1601 | LCDSTAT &= 0xFB; |
1602 | | |
1602 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4/*8*/), GB_LCD_STATE_LY00_M1_1); | |
1603 | 1603 | break; |
1604 | 1604 | case GB_LCD_STATE_LY00_M1_1: |
1605 | if ( ! | |
1605 | if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1606 | 1606 | { |
1607 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1608 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1607 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1608 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1609 | 1609 | } |
1610 | | |
1610 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2); | |
1611 | 1611 | break; |
1612 | 1612 | case GB_LCD_STATE_LY00_M1_2: /* Rest of line #0 during VBlank */ |
1613 | if ( | |
1613 | if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1614 | 1614 | { |
1615 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1616 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1615 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1616 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1617 | 1617 | } |
1618 | 1618 | if ( CURLINE == CMPLINE ) |
1619 | 1619 | { |
1620 | 1620 | LCDSTAT |= 0x04; |
1621 | 1621 | } |
1622 | | |
1622 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0); | |
1623 | 1623 | break; |
1624 | 1624 | case GB_LCD_STATE_LY00_M0: /* The STAT register seems to go to 0 for about 4 cycles */ |
1625 | 1625 | /* Set Mode 0 lcdstat */ |
1626 | | |
1626 | m_lcd.mode = 0; | |
1627 | 1627 | LCDSTAT = ( LCDSTAT & 0xFC ); |
1628 | | |
1628 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2); | |
1629 | 1629 | break; |
1630 | 1630 | } |
1631 | 1631 | } |
1632 | 1632 | else |
1633 | 1633 | { |
1634 | gb_increment_scanline(state); | |
1635 | if ( state->m_lcd.current_line < 144 ) | |
1634 | gb_increment_scanline(this); | |
1635 | if ( m_lcd.current_line < 144 ) | |
1636 | 1636 | { |
1637 | (* | |
1637 | (*update_scanline)( machine() ); | |
1638 | 1638 | } |
1639 | | |
1639 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(456)); | |
1640 | 1640 | } |
1641 | 1641 | } |
1642 | 1642 | |
1643 | ||
1643 | TIMER_CALLBACK_MEMBER(gb_state::gbc_lcd_timer_proc) | |
1644 | 1644 | { |
1645 | gb_state *state = machine.driver_data<gb_state>(); | |
1645 | gb_state *state = machine().driver_data<gb_state>(); | |
1646 | 1646 | static const int sprite_cycles[] = { 0, 8, 20, 32, 44, 52, 64, 76, 88, 96, 108 }; |
1647 | 1647 | |
1648 | | |
1648 | m_lcd.state = param; | |
1649 | 1649 | |
1650 | 1650 | if ( LCDCONT & 0x80 ) |
1651 | 1651 | { |
1652 | switch( | |
1652 | switch( m_lcd.state ) | |
1653 | 1653 | { |
1654 | 1654 | case GB_LCD_STATE_LYXX_PRE_M0: /* Just before switching to mode 0 */ |
1655 | | |
1655 | m_lcd.mode = 0; | |
1656 | 1656 | if ( LCDSTAT & 0x08 ) |
1657 | 1657 | { |
1658 | if ( ! | |
1658 | if ( ! m_lcd.mode_irq ) | |
1659 | 1659 | { |
1660 | if ( ! | |
1660 | if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq ) | |
1661 | 1661 | { |
1662 | state->m_lcd.mode_irq = 1; | |
1663 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1662 | m_lcd.mode_irq = 1; | |
1663 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1664 | 1664 | } |
1665 | 1665 | } |
1666 | 1666 | else |
1667 | 1667 | { |
1668 | | |
1668 | m_lcd.mode_irq = 0; | |
1669 | 1669 | } |
1670 | 1670 | } |
1671 | | |
1671 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0); | |
1672 | 1672 | break; |
1673 | 1673 | case GB_LCD_STATE_LYXX_M0: /* Switch to mode 0 */ |
1674 | 1674 | /* update current scanline */ |
1675 | (* | |
1675 | (*update_scanline)( machine() ); | |
1676 | 1676 | /* Increment the number of window lines drawn if enabled */ |
1677 | if ( | |
1677 | if ( m_lcd.layer[1].enabled ) | |
1678 | 1678 | { |
1679 | | |
1679 | m_lcd.window_lines_drawn++; | |
1680 | 1680 | } |
1681 | | |
1681 | m_lcd.previous_line = m_lcd.current_line; | |
1682 | 1682 | /* Set Mode 0 lcdstate */ |
1683 | | |
1683 | m_lcd.mode = 0; | |
1684 | 1684 | LCDSTAT &= 0xFC; |
1685 | state->m_lcd.oam_locked = UNLOCKED; | |
1686 | state->m_lcd.vram_locked = UNLOCKED; | |
1685 | m_lcd.oam_locked = UNLOCKED; | |
1686 | m_lcd.vram_locked = UNLOCKED; | |
1687 | 1687 | /* |
1688 | 1688 | There seems to a kind of feature in the Game Boy hardware when the lowest bits of the |
1689 | 1689 | SCROLLX register equals 3 or 7, then the delayed M0 irq is triggered 4 cycles later |
1690 | 1690 | than usual. |
1691 | 1691 | The SGB probably has the same bug. |
1692 | 1692 | */ |
1693 | | |
1693 | m_lcd.triggering_mode_irq = ( LCDSTAT & 0x08 ) ? 1 : 0; | |
1694 | 1694 | if ( ( SCROLLX & 0x03 ) == 0x03 ) |
1695 | 1695 | { |
1696 | state->m_lcd.scrollx_adjust += 4; | |
1697 | state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3); | |
1696 | m_lcd.scrollx_adjust += 4; | |
1697 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3); | |
1698 | 1698 | break; |
1699 | 1699 | } |
1700 | 1700 | case GB_LCD_STATE_LYXX_M0_SCX3: |
1701 | 1701 | /* Generate lcd interrupt if requested */ |
1702 | if ( ! state->m_lcd.mode_irq && state->m_lcd.triggering_mode_irq && | |
1703 | ( ( ! state->m_lcd.line_irq && state->m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1702 | if ( ! m_lcd.mode_irq && m_lcd.triggering_mode_irq && | |
1703 | ( ( ! m_lcd.line_irq && m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1704 | 1704 | { |
1705 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1706 | state->m_lcd.triggering_mode_irq = 0; | |
1705 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1706 | m_lcd.triggering_mode_irq = 0; | |
1707 | 1707 | } |
1708 | 1708 | if ( ( SCROLLX & 0x03 ) == 0x03 ) |
1709 | 1709 | { |
1710 | | |
1710 | m_lcd.pal_locked = UNLOCKED; | |
1711 | 1711 | } |
1712 | | |
1712 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_GBC_PAL); | |
1713 | 1713 | break; |
1714 | 1714 | case GB_LCD_STATE_LYXX_M0_GBC_PAL: |
1715 | | |
1715 | m_lcd.pal_locked = UNLOCKED; | |
1716 | 1716 | /* Check for HBLANK DMA */ |
1717 | if( | |
1717 | if( m_lcd.hdma_enabled ) | |
1718 | 1718 | { |
1719 | gbc_hdma(machine, 0x10); | |
1719 | gbc_hdma(machine(), 0x10); | |
1720 | 1720 | // cpunum_set_reg( 0, LR35902_DMA_CYCLES, 36 ); |
1721 | 1721 | } |
1722 | 1722 | else |
1723 | 1723 | { |
1724 | | |
1724 | m_lcd.hdma_possible = 1; | |
1725 | 1725 | } |
1726 | | |
1726 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(192 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC); | |
1727 | 1727 | break; |
1728 | 1728 | case GB_LCD_STATE_LYXX_M0_PRE_INC: /* Just before incrementing the line counter go to mode 2 internally */ |
1729 | | |
1729 | m_lcd.cmp_line = CMPLINE; | |
1730 | 1730 | if ( CURLINE < 143 ) |
1731 | 1731 | { |
1732 | | |
1732 | m_lcd.mode = 2; | |
1733 | 1733 | if ( LCDSTAT & 0x20 ) |
1734 | 1734 | { |
1735 | if ( ! | |
1735 | if ( ! m_lcd.mode_irq ) | |
1736 | 1736 | { |
1737 | if ( ! | |
1737 | if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq ) | |
1738 | 1738 | { |
1739 | state->m_lcd.mode_irq = 1; | |
1740 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1739 | m_lcd.mode_irq = 1; | |
1740 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1741 | 1741 | } |
1742 | 1742 | } |
1743 | 1743 | else |
1744 | 1744 | { |
1745 | | |
1745 | m_lcd.mode_irq = 0; | |
1746 | 1746 | } |
1747 | 1747 | } |
1748 | 1748 | } |
1749 | | |
1749 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC); | |
1750 | 1750 | break; |
1751 | 1751 | case GB_LCD_STATE_LYXX_M0_INC: /* Increment LY, stay in M0 for 4 more cycles */ |
1752 | gb_increment_scanline(state); | |
1753 | state->m_lcd.delayed_line_irq = state->m_lcd.line_irq; | |
1754 | state->m_lcd.triggering_line_irq = ( ( state->m_lcd.cmp_line == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1755 | state->m_lcd.line_irq = 0; | |
1756 | if ( ! state->m_lcd.mode_irq && ! state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) | |
1752 | gb_increment_scanline(this); | |
1753 | m_lcd.delayed_line_irq = m_lcd.line_irq; | |
1754 | m_lcd.triggering_line_irq = ( ( m_lcd.cmp_line == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1755 | m_lcd.line_irq = 0; | |
1756 | if ( ! m_lcd.mode_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) | |
1757 | 1757 | { |
1758 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1759 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1758 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1759 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1760 | 1760 | } |
1761 | | |
1761 | m_lcd.hdma_possible = 0; | |
1762 | 1762 | /* Check if we're going into VBlank next */ |
1763 | 1763 | if ( CURLINE == 144 ) |
1764 | 1764 | { |
1765 | | |
1765 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1); | |
1766 | 1766 | } |
1767 | 1767 | else |
1768 | 1768 | { |
1769 | 1769 | /* Internally switch to mode 2 */ |
1770 | | |
1770 | m_lcd.mode = 2; | |
1771 | 1771 | /* Generate lcd interrupt if requested */ |
1772 | if ( ! state->m_lcd.mode_irq && ( LCDSTAT & 0x20 ) && | |
1773 | ( ( ! state->m_lcd.triggering_line_irq && ! state->m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1772 | if ( ! m_lcd.mode_irq && ( LCDSTAT & 0x20 ) && | |
1773 | ( ( ! m_lcd.triggering_line_irq && ! m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) ) | |
1774 | 1774 | { |
1775 | state->m_lcd.mode_irq = 1; | |
1776 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1775 | m_lcd.mode_irq = 1; | |
1776 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1777 | 1777 | } |
1778 | | |
1778 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2); | |
1779 | 1779 | } |
1780 | 1780 | break; |
1781 | 1781 | case GB_LCD_STATE_LY00_M2: /* Switch to mode 2 on line #0 */ |
1782 | 1782 | /* Set Mode 2 lcdstate */ |
1783 | | |
1783 | m_lcd.mode = 2; | |
1784 | 1784 | LCDSTAT = ( LCDSTAT & 0xFC ) | 0x02; |
1785 | | |
1785 | m_lcd.oam_locked = LOCKED; | |
1786 | 1786 | /* Generate lcd interrupt if requested */ |
1787 | if ( ( LCDSTAT & 0x20 ) && ! | |
1787 | if ( ( LCDSTAT & 0x20 ) && ! m_lcd.line_irq ) | |
1788 | 1788 | { |
1789 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1789 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1790 | 1790 | } |
1791 | 1791 | /* Check for regular compensation of x-scroll register */ |
1792 | | |
1792 | m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0; | |
1793 | 1793 | /* Mode 2 lasts approximately 80 clock cycles */ |
1794 | | |
1794 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3); | |
1795 | 1795 | break; |
1796 | 1796 | case GB_LCD_STATE_LYXX_M2: /* Switch to mode 2 */ |
1797 | 1797 | /* Update STAT register to the correct state */ |
1798 | 1798 | LCDSTAT = (LCDSTAT & 0xFC) | 0x02; |
1799 | | |
1799 | m_lcd.oam_locked = LOCKED; | |
1800 | 1800 | /* Generate lcd interrupt if requested */ |
1801 | if ( ( state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) || | |
1802 | ( !state->m_lcd.mode_irq && ! state->m_lcd.line_irq && ! state->m_lcd.delayed_line_irq && ( LCDSTAT & 0x20 ) ) ) | |
1801 | if ( ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) || | |
1802 | ( !m_lcd.mode_irq && ! m_lcd.line_irq && ! m_lcd.delayed_line_irq && ( LCDSTAT & 0x20 ) ) ) | |
1803 | 1803 | { |
1804 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1804 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1805 | 1805 | } |
1806 | | |
1806 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1807 | 1807 | /* Check if LY==LYC STAT bit should be set */ |
1808 | 1808 | if ( CURLINE == CMPLINE ) |
1809 | 1809 | { |
r18113 | r18114 | |
1814 | 1814 | LCDSTAT &= ~0x04; |
1815 | 1815 | } |
1816 | 1816 | /* Check for regular compensation of x-scroll register */ |
1817 | | |
1817 | m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0; | |
1818 | 1818 | /* Mode 2 last for approximately 80 clock cycles */ |
1819 | | |
1819 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3); | |
1820 | 1820 | break; |
1821 | 1821 | case GB_LCD_STATE_LYXX_M3: /* Switch to mode 3 */ |
1822 | gb_select_sprites(state); | |
1823 | state->m_lcd.sprite_cycles = sprite_cycles[ state->m_lcd.sprCount ]; | |
1822 | gb_select_sprites(this); | |
1823 | m_lcd.sprite_cycles = sprite_cycles[ m_lcd.sprCount ]; | |
1824 | 1824 | /* Set Mode 3 lcdstate */ |
1825 | | |
1825 | m_lcd.mode = 3; | |
1826 | 1826 | LCDSTAT = (LCDSTAT & 0xFC) | 0x03; |
1827 | state->m_lcd.vram_locked = LOCKED; | |
1828 | state->m_lcd.pal_locked = LOCKED; | |
1827 | m_lcd.vram_locked = LOCKED; | |
1828 | m_lcd.pal_locked = LOCKED; | |
1829 | 1829 | /* Check for compensations of x-scroll register */ |
1830 | 1830 | /* Mode 3 lasts for approximately 172+cycles needed to handle sprites clock cycles */ |
1831 | state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(168 + state->m_lcd.scrollx_adjust + state->m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0); | |
1832 | state->m_lcd.start_x = -1; | |
1831 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0); | |
1832 | m_lcd.start_x = -1; | |
1833 | 1833 | break; |
1834 | 1834 | case GB_LCD_STATE_LY9X_M1: /* Switch to or stay in mode 1 */ |
1835 | 1835 | if ( CURLINE == 144 ) |
1836 | 1836 | { |
1837 | 1837 | /* Trigger VBlank interrupt */ |
1838 | machine.device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1838 | machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE ); | |
1839 | 1839 | /* Set VBlank lcdstate */ |
1840 | | |
1840 | m_lcd.mode = 1; | |
1841 | 1841 | LCDSTAT = (LCDSTAT & 0xFC) | 0x01; |
1842 | 1842 | /* Trigger LCD interrupt if requested */ |
1843 | 1843 | if ( LCDSTAT & 0x10 ) |
1844 | 1844 | { |
1845 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1845 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1846 | 1846 | } |
1847 | 1847 | } |
1848 | 1848 | /* Check if LY==LYC STAT bit should be set */ |
r18113 | r18114 | |
1854 | 1854 | { |
1855 | 1855 | LCDSTAT &= ~0x04; |
1856 | 1856 | } |
1857 | if ( | |
1857 | if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1858 | 1858 | { |
1859 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1859 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1860 | 1860 | } |
1861 | | |
1861 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC); | |
1862 | 1862 | break; |
1863 | 1863 | case GB_LCD_STATE_LY9X_M1_INC: /* Increment scanline counter */ |
1864 | gb_increment_scanline(state); | |
1865 | state->m_lcd.delayed_line_irq = state->m_lcd.line_irq; | |
1866 | state->m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1867 | state->m_lcd.line_irq = 0; | |
1868 | if ( ! state->m_lcd.delayed_line_irq && state->m_lcd.triggering_line_irq ) | |
1864 | gb_increment_scanline(this); | |
1865 | m_lcd.delayed_line_irq = m_lcd.line_irq; | |
1866 | m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1867 | m_lcd.line_irq = 0; | |
1868 | if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1869 | 1869 | { |
1870 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1871 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1870 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1871 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1872 | 1872 | } |
1873 | if ( | |
1873 | if ( m_lcd.current_line == 153 ) | |
1874 | 1874 | { |
1875 | | |
1875 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1); | |
1876 | 1876 | } |
1877 | 1877 | else |
1878 | 1878 | { |
1879 | | |
1879 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1); | |
1880 | 1880 | } |
1881 | 1881 | break; |
1882 | 1882 | case GB_LCD_STATE_LY00_M1: /* we stay in VBlank but current line counter should already be incremented */ |
1883 | 1883 | /* Check LY=LYC for line #153 */ |
1884 | if ( | |
1884 | if ( m_lcd.delayed_line_irq ) | |
1885 | 1885 | { |
1886 | if ( | |
1886 | if ( m_lcd.triggering_line_irq ) | |
1887 | 1887 | { |
1888 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1888 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1889 | 1889 | } |
1890 | 1890 | } |
1891 | | |
1891 | m_lcd.delayed_line_irq = m_lcd.delayed_line_irq | m_lcd.line_irq; | |
1892 | 1892 | if ( CURLINE == CMPLINE ) |
1893 | 1893 | { |
1894 | 1894 | LCDSTAT |= 0x04; |
r18113 | r18114 | |
1897 | 1897 | { |
1898 | 1898 | LCDSTAT &= ~0x04; |
1899 | 1899 | } |
1900 | gb_increment_scanline(state); | |
1901 | state->m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1902 | state->m_lcd.line_irq = 0; | |
1900 | gb_increment_scanline(this); | |
1901 | m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0; | |
1902 | m_lcd.line_irq = 0; | |
1903 | 1903 | LCDSTAT &= 0xFB; |
1904 | | |
1904 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_1); | |
1905 | 1905 | break; |
1906 | 1906 | case GB_LCD_STATE_LY00_M1_1: |
1907 | if ( ! | |
1907 | if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1908 | 1908 | { |
1909 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1910 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1909 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1910 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1911 | 1911 | } |
1912 | | |
1912 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2); | |
1913 | 1913 | break; |
1914 | 1914 | case GB_LCD_STATE_LY00_M1_2: /* Rest of line #0 during VBlank */ |
1915 | if ( | |
1915 | if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq ) | |
1916 | 1916 | { |
1917 | state->m_lcd.line_irq = state->m_lcd.triggering_line_irq; | |
1918 | machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1917 | m_lcd.line_irq = m_lcd.triggering_line_irq; | |
1918 | machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE ); | |
1919 | 1919 | } |
1920 | 1920 | if ( CURLINE == CMPLINE ) |
1921 | 1921 | { |
r18113 | r18114 | |
1925 | 1925 | { |
1926 | 1926 | LCDSTAT &= ~0x04; |
1927 | 1927 | } |
1928 | | |
1928 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0); | |
1929 | 1929 | break; |
1930 | 1930 | case GB_LCD_STATE_LY00_M0: /* The STAT register seems to go to 0 for about 4 cycles */ |
1931 | 1931 | /* Set Mode 0 lcdstat */ |
1932 | state->m_lcd.mode = 0; | |
1933 | state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2); | |
1932 | m_lcd.mode = 0; | |
1933 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2); | |
1934 | 1934 | break; |
1935 | 1935 | } |
1936 | 1936 | } |
1937 | 1937 | else |
1938 | 1938 | { |
1939 | gb_increment_scanline(state); | |
1940 | if ( state->m_lcd.current_line < 144 ) | |
1939 | gb_increment_scanline(this); | |
1940 | if ( m_lcd.current_line < 144 ) | |
1941 | 1941 | { |
1942 | (* | |
1942 | (*update_scanline)( machine() ); | |
1943 | 1943 | } |
1944 | | |
1944 | m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(456)); | |
1945 | 1945 | } |
1946 | 1946 | } |
1947 | 1947 |
r18113 | r18114 | |
---|---|---|
94 | 94 | m_video.vram_access = 0; |
95 | 95 | } |
96 | 96 | |
97 | ||
97 | TIMER_CALLBACK_MEMBER(fm7_state::fm77av_alu_task_end) | |
98 | 98 | { |
99 | fm7_state *state = machine.driver_data<fm7_state>(); | |
100 | state->m_alu.busy = 0; | |
99 | m_alu.busy = 0; | |
101 | 100 | } |
102 | 101 | |
103 | 102 | static void fm7_alu_mask_write(fm7_state *state, UINT32 offset, int bank, UINT8 dat) |
r18113 | r18114 | |
628 | 627 | |
629 | 628 | // set timer to disable busy flag |
630 | 629 | // 1/16 us for each byte changed |
631 | machine.scheduler().timer_set(attotime::from_usec(byte_count/16), FUNC(fm77av_alu_task_end)); | |
630 | machine.scheduler().timer_set(attotime::from_usec(byte_count/16), timer_expired_delegate(FUNC(fm7_state::fm77av_alu_task_end),state)); | |
632 | 631 | } |
633 | 632 | |
634 | 633 | READ8_MEMBER(fm7_state::fm7_vram_r) |
r18113 | r18114 | |
1350 | 1349 | } |
1351 | 1350 | } |
1352 | 1351 | |
1353 | TIMER_CALLBACK( | |
1352 | TIMER_CALLBACK_MEMBER(fm7_state::fm77av_vsync) | |
1354 | 1353 | { |
1355 | fm7_state *state = machine.driver_data<fm7_state>(); | |
1356 | 1354 | if(param == 0) // start of vsync |
1357 | 1355 | { |
1358 | state->m_video.vsync_flag = 1; | |
1359 | state->m_fm77av_vsync_timer->adjust(attotime::from_usec(510),1); // VSync length for 200 line modes = 0.51ms | |
1356 | m_video.vsync_flag = 1; | |
1357 | m_fm77av_vsync_timer->adjust(attotime::from_usec(510),1); // VSync length for 200 line modes = 0.51ms | |
1360 | 1358 | } |
1361 | 1359 | else |
1362 | 1360 | { |
1363 | state->m_video.vsync_flag = 0; | |
1364 | state->m_fm77av_vsync_timer->adjust(machine.primary_screen->time_until_vblank_end()); | |
1361 | m_video.vsync_flag = 0; | |
1362 | m_fm77av_vsync_timer->adjust(machine().primary_screen->time_until_vblank_end()); | |
1365 | 1363 | } |
1366 | 1364 | } |
1367 | 1365 |
r18113 | r18114 | |
---|---|---|
125 | 125 | draw_mode12_block(state, state->m_bitmap, y, hpos, mask); |
126 | 126 | } |
127 | 127 | |
128 | TIMER_CALLBACK( | |
128 | TIMER_CALLBACK_MEMBER(samcoupe_state::sam_video_update_callback) | |
129 | 129 | { |
130 | samcoupe_state *state = machine.driver_data<samcoupe_state>(); | |
131 | int vpos = machine.primary_screen->vpos(); | |
132 | int hpos = machine.primary_screen->hpos(); | |
130 | int vpos = machine().primary_screen->vpos(); | |
131 | int hpos = machine().primary_screen->hpos(); | |
133 | 132 | |
134 | 133 | int next_vpos = vpos; |
135 | 134 | int next_hpos = hpos + SAM_BLOCK*2; |
r18113 | r18114 | |
142 | 141 | } |
143 | 142 | |
144 | 143 | /* display disabled? (only in mode 3 or 4) */ |
145 | if (BIT( | |
144 | if (BIT(m_vmpr, 6) && BIT(m_border, 7)) | |
146 | 145 | { |
147 | | |
146 | m_bitmap.plot_box(hpos, vpos, SAM_BLOCK*2, 1, 0); | |
148 | 147 | } |
149 | 148 | else |
150 | 149 | { |
151 | 150 | /* border area? */ |
152 | 151 | if (vpos < SAM_BORDER_TOP || vpos >= SAM_BORDER_TOP + SAM_SCREEN_HEIGHT || hpos < SAM_BORDER_LEFT || hpos >= SAM_BORDER_LEFT + SAM_SCREEN_WIDTH) |
153 | 152 | { |
154 | state->m_attribute = 0xff; | |
155 | state->m_bitmap.plot_box(hpos, vpos, SAM_BLOCK*2, 1, state->m_clut[BORDER_COLOR(state->m_border)]); | |
153 | m_attribute = 0xff; | |
154 | m_bitmap.plot_box(hpos, vpos, SAM_BLOCK*2, 1, m_clut[BORDER_COLOR(m_border)]); | |
156 | 155 | } |
157 | 156 | else |
158 | 157 | { |
159 | 158 | /* main screen area */ |
160 | switch (( | |
159 | switch ((m_vmpr & 0x60) >> 5) | |
161 | 160 | { |
162 | case 0: draw_mode1_line(machine, vpos, hpos); break; | |
163 | case 1: draw_mode2_line(machine, vpos, hpos); break; | |
164 | case 2: draw_mode3_line(machine, vpos, hpos); break; | |
165 | case 3: draw_mode4_line(machine, vpos, hpos); break; | |
161 | case 0: draw_mode1_line(machine(), vpos, hpos); break; | |
162 | case 1: draw_mode2_line(machine(), vpos, hpos); break; | |
163 | case 2: draw_mode3_line(machine(), vpos, hpos); break; | |
164 | case 3: draw_mode4_line(machine(), vpos, hpos); break; | |
166 | 165 | } |
167 | 166 | } |
168 | 167 | } |
169 | 168 | |
170 | 169 | /* do we need to trigger the scanline interrupt (interrupt happens at the start of the right border before the specified line)? */ |
171 | if (state->m_line_int < SAM_SCREEN_HEIGHT && hpos == SAM_BORDER_LEFT + SAM_SCREEN_WIDTH && vpos == (state->m_line_int + SAM_BORDER_TOP - 1)) | |
172 | samcoupe_irq(machine.firstcpu, SAM_LINE_INT); | |
170 | if (m_line_int < SAM_SCREEN_HEIGHT && hpos == SAM_BORDER_LEFT + SAM_SCREEN_WIDTH && vpos == (m_line_int + SAM_BORDER_TOP - 1)) | |
171 | samcoupe_irq(machine().firstcpu, SAM_LINE_INT); | |
173 | 172 | |
174 | 173 | /* schedule next update */ |
175 | | |
174 | m_video_update_timer->adjust(machine().primary_screen->time_until_pos(next_vpos, next_hpos)); | |
176 | 175 | } |
r18113 | r18114 | |
---|---|---|
249 | 249 | return 0; |
250 | 250 | } |
251 | 251 | |
252 | ||
252 | TIMER_CALLBACK_MEMBER(odyssey2_state::i824x_scanline_callback) | |
253 | 253 | { |
254 | odyssey2_state *state = machine.driver_data<odyssey2_state>(); | |
255 | 254 | UINT8 collision_map[160]; |
256 | int vpos = machine.primary_screen->vpos(); | |
255 | int vpos = machine().primary_screen->vpos(); | |
257 | 256 | |
258 | if ( vpos < | |
257 | if ( vpos < m_start_vpos ) | |
259 | 258 | return; |
260 | 259 | |
261 | if ( vpos == | |
260 | if ( vpos == m_start_vpos ) | |
262 | 261 | { |
263 | | |
262 | m_control_status &= ~0x08; | |
264 | 263 | } |
265 | 264 | |
266 | if ( vpos < | |
265 | if ( vpos < m_start_vblank ) | |
267 | 266 | { |
268 | 267 | rectangle rect; |
269 | 268 | //static const int sprite_width[4] = { 8, 8, 8, 8 }; |
270 | 269 | int i; |
271 | 270 | |
272 | | |
271 | m_control_status &= ~ 0x01; | |
273 | 272 | |
274 | 273 | /* Draw a line */ |
275 | 274 | rect.set(I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN - 1, vpos, vpos); |
276 | | |
275 | m_tmp_bitmap.fill(( (m_o2_vdc.s.color >> 3) & 0x7 ) | ( ( m_lum << 3 ) ^ 0x08 ), rect ); | |
277 | 276 | |
278 | 277 | /* Clear collision map */ |
279 | 278 | memset( collision_map, 0, sizeof( collision_map ) ); |
280 | 279 | |
281 | 280 | /* Display grid if enabled */ |
282 | if ( | |
281 | if ( m_o2_vdc.s.control & 0x08 ) | |
283 | 282 | { |
284 | UINT16 color = ( | |
283 | UINT16 color = ( m_o2_vdc.s.color & 7 ) | ( ( m_o2_vdc.s.color >> 3 ) & 0x08 ) | ( ( m_lum << 3 ) ^ 0x08 ); | |
285 | 284 | int x_grid_offset = 8; |
286 | 285 | int y_grid_offset = 24; |
287 | 286 | int width = 16; |
288 | 287 | int height = 24; |
289 | int w = ( | |
288 | int w = ( m_o2_vdc.s.control & 0x80 ) ? width : 2; | |
290 | 289 | int j, k, y; |
291 | 290 | |
292 | 291 | /* Draw horizontal part of grid */ |
293 | 292 | for ( j = 1, y = 0; y < 9; y++, j <<= 1 ) |
294 | 293 | { |
295 | if ( y_grid_offset + y * height <= ( vpos - | |
294 | if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + y * height + 3 ) | |
296 | 295 | { |
297 | 296 | for ( i = 0; i < 9; i++ ) |
298 | 297 | { |
299 | if ( ( | |
298 | if ( ( m_o2_vdc.s.hgrid[0][i] & j ) || ( m_o2_vdc.s.hgrid[1][i] & ( j >> 8 ) ) ) | |
300 | 299 | { |
301 | 300 | for ( k = 0; k < width + 2; k++ ) |
302 | 301 | { |
303 | 302 | int px = x_grid_offset + i * width + k; |
304 | 303 | collision_map[ px ] |= COLLISION_HORIZ_GRID_DOTS; |
305 | | |
304 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color; | |
306 | 305 | } |
307 | 306 | } |
308 | 307 | } |
r18113 | r18114 | |
312 | 311 | /* Draw vertical part of grid */ |
313 | 312 | for( j = 1, y = 0; y < 8; y++, j <<= 1 ) |
314 | 313 | { |
315 | if ( y_grid_offset + y * height <= ( vpos - | |
314 | if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + ( y + 1 ) * height ) | |
316 | 315 | { |
317 | 316 | for ( i = 0; i < 10; i++ ) |
318 | 317 | { |
319 | if ( | |
318 | if ( m_o2_vdc.s.vgrid[i] & j ) | |
320 | 319 | { |
321 | 320 | for ( k = 0; k < w; k++ ) |
322 | 321 | { |
323 | 322 | int px = x_grid_offset + i * width + k; |
324 | 323 | |
325 | 324 | /* Check if we collide with an already drawn source object */ |
326 | if ( collision_map[ px ] & | |
325 | if ( collision_map[ px ] & m_o2_vdc.s.collision ) | |
327 | 326 | { |
328 | | |
327 | m_collision_status |= COLLISION_VERTICAL_GRID; | |
329 | 328 | } |
330 | 329 | /* Check if an already drawn object would collide with us */ |
331 | if ( COLLISION_VERTICAL_GRID & | |
330 | if ( COLLISION_VERTICAL_GRID & m_o2_vdc.s.collision && collision_map[ px ] ) | |
332 | 331 | { |
333 | | |
332 | m_collision_status |= collision_map[ px ]; | |
334 | 333 | } |
335 | 334 | collision_map[ px ] |= COLLISION_VERTICAL_GRID; |
336 | | |
335 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color; | |
337 | 336 | } |
338 | 337 | } |
339 | 338 | } |
r18113 | r18114 | |
342 | 341 | } |
343 | 342 | |
344 | 343 | /* Display objects if enabled */ |
345 | if ( | |
344 | if ( m_o2_vdc.s.control & 0x20 ) | |
346 | 345 | { |
347 | 346 | /* Regular foreground objects */ |
348 | for ( i = 0; i < ARRAY_LENGTH( | |
347 | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.foreground ); i++ ) | |
349 | 348 | { |
350 | int y = state->m_o2_vdc.s.foreground[i].y; | |
351 | int height = 8 - ( ( ( y >> 1 ) + state->m_o2_vdc.s.foreground[i].ptr ) & 7 ); | |
349 | int y = m_o2_vdc.s.foreground[i].y; | |
350 | int height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.foreground[i].ptr ) & 7 ); | |
352 | 351 | |
353 | if ( y <= ( vpos - | |
352 | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) | |
354 | 353 | { |
355 | UINT16 color = 16 + ( ( state->m_o2_vdc.s.foreground[i].color & 0x0E ) >> 1 ); | |
356 | int offset = ( state->m_o2_vdc.s.foreground[i].ptr | ( ( state->m_o2_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - state->m_start_vpos - y ) >> 1 ); | |
354 | UINT16 color = 16 + ( ( m_o2_vdc.s.foreground[i].color & 0x0E ) >> 1 ); | |
355 | int offset = ( m_o2_vdc.s.foreground[i].ptr | ( ( m_o2_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 ); | |
357 | 356 | UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ]; |
358 | int x = | |
357 | int x = m_o2_vdc.s.foreground[i].x; | |
359 | 358 | UINT8 m; |
360 | 359 | |
361 | 360 | for ( m = 0x80; m > 0; m >>= 1, x++ ) |
r18113 | r18114 | |
365 | 364 | if ( x >= 0 && x < 160 ) |
366 | 365 | { |
367 | 366 | /* Check if we collide with an already drawn source object */ |
368 | if ( collision_map[ x ] & | |
367 | if ( collision_map[ x ] & m_o2_vdc.s.collision ) | |
369 | 368 | { |
370 | | |
369 | m_collision_status |= COLLISION_CHARACTERS; | |
371 | 370 | } |
372 | 371 | /* Check if an already drawn object would collide with us */ |
373 | if ( COLLISION_CHARACTERS & | |
372 | if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] ) | |
374 | 373 | { |
375 | | |
374 | m_collision_status |= collision_map[ x ]; | |
376 | 375 | } |
377 | 376 | collision_map[ x ] |= COLLISION_CHARACTERS; |
378 | | |
377 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; | |
379 | 378 | } |
380 | 379 | } |
381 | 380 | } |
r18113 | r18114 | |
383 | 382 | } |
384 | 383 | |
385 | 384 | /* Quad objects */ |
386 | for ( i = 0; i < ARRAY_LENGTH( | |
385 | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.quad ); i++ ) | |
387 | 386 | { |
388 | int y = | |
387 | int y = m_o2_vdc.s.quad[i].single[0].y; | |
389 | 388 | int height = 8; |
390 | 389 | |
391 | if ( y <= ( vpos - | |
390 | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) | |
392 | 391 | { |
393 | int x = | |
392 | int x = m_o2_vdc.s.quad[i].single[0].x; | |
394 | 393 | int j; |
395 | 394 | |
396 | 395 | // Charaecter height is always determined by the height of the 4th character |
397 | int char_height = 8 - ( ( ( y >> 1 ) + | |
396 | int char_height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.quad[i].single[3].ptr ) & 7 ); | |
398 | 397 | |
399 | for ( j = 0; j < ARRAY_LENGTH( | |
398 | for ( j = 0; j < ARRAY_LENGTH( m_o2_vdc.s.quad[0].single ); j++, x += 8 ) | |
400 | 399 | { |
401 | 400 | |
402 | 401 | |
403 | if ( y <= ( vpos - | |
402 | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + char_height * 2 ) | |
404 | 403 | { |
405 | 404 | |
406 | UINT16 color = 16 + ( ( | |
405 | UINT16 color = 16 + ( ( m_o2_vdc.s.quad[i].single[j].color & 0x0E ) >> 1 ); | |
407 | 406 | |
408 | 407 | |
409 | int offset = ( | |
408 | int offset = ( m_o2_vdc.s.quad[i].single[j].ptr | ( ( m_o2_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 ); | |
410 | 409 | |
411 | 410 | UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ]; |
412 | 411 | |
r18113 | r18114 | |
418 | 417 | if ( x >= 0 && x < 160 ) |
419 | 418 | { |
420 | 419 | /* Check if we collide with an already drawn source object */ |
421 | if ( collision_map[ x ] & | |
420 | if ( collision_map[ x ] & m_o2_vdc.s.collision ) | |
422 | 421 | { |
423 | | |
422 | m_collision_status |= COLLISION_CHARACTERS; | |
424 | 423 | } |
425 | 424 | /* Check if an already drawn object would collide with us */ |
426 | if ( COLLISION_CHARACTERS & | |
425 | if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] ) | |
427 | 426 | { |
428 | | |
427 | m_collision_status |= collision_map[ x ]; | |
429 | 428 | } |
430 | 429 | collision_map[ x ] |= COLLISION_CHARACTERS; |
431 | | |
430 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; | |
432 | 431 | } |
433 | 432 | } |
434 | 433 | } |
r18113 | r18114 | |
442 | 441 | } |
443 | 442 | |
444 | 443 | /* Sprites */ |
445 | for ( i = 0; i < ARRAY_LENGTH( | |
444 | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.sprites ); i++ ) | |
446 | 445 | { |
447 | int y = | |
446 | int y = m_o2_vdc.s.sprites[i].y; | |
448 | 447 | int height = 8; |
449 | if ( | |
448 | if ( m_o2_vdc.s.sprites[i].color & 4 ) | |
450 | 449 | { |
451 | 450 | /* Zoomed sprite */ |
452 | 451 | //sprite_width[i] = 16; |
453 | if ( y <= ( vpos - | |
452 | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 4 ) | |
454 | 453 | { |
455 | UINT16 color = 16 + ( ( state->m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); | |
456 | UINT8 chr = state->m_o2_vdc.s.shape[i][ ( ( vpos - state->m_start_vpos - y ) >> 2 ) ]; | |
457 | int x = state->m_o2_vdc.s.sprites[i].x; | |
454 | UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); | |
455 | UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 2 ) ]; | |
456 | int x = m_o2_vdc.s.sprites[i].x; | |
458 | 457 | UINT8 m; |
459 | 458 | |
460 | 459 | for ( m = 0x01; m > 0; m <<= 1, x += 2 ) |
r18113 | r18114 | |
464 | 463 | if ( x >= 0 && x < 160 ) |
465 | 464 | { |
466 | 465 | /* Check if we collide with an already drawn source object */ |
467 | if ( collision_map[ x ] & | |
466 | if ( collision_map[ x ] & m_o2_vdc.s.collision ) | |
468 | 467 | { |
469 | | |
468 | m_collision_status |= ( 1 << i ); | |
470 | 469 | } |
471 | 470 | /* Check if an already drawn object would collide with us */ |
472 | if ( ( 1 << i ) & | |
471 | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) | |
473 | 472 | { |
474 | | |
473 | m_collision_status |= collision_map[ x ]; | |
475 | 474 | } |
476 | 475 | collision_map[ x ] |= ( 1 << i ); |
477 | | |
476 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; | |
478 | 477 | } |
479 | 478 | if ( x >= -1 && x < 159 ) |
480 | 479 | { |
481 | 480 | /* Check if we collide with an already drawn source object */ |
482 | if ( collision_map[ x ] & | |
481 | if ( collision_map[ x ] & m_o2_vdc.s.collision ) | |
483 | 482 | { |
484 | | |
483 | m_collision_status |= ( 1 << i ); | |
485 | 484 | } |
486 | 485 | /* Check if an already drawn object would collide with us */ |
487 | if ( ( 1 << i ) & | |
486 | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) | |
488 | 487 | { |
489 | | |
488 | m_collision_status |= collision_map[ x ]; | |
490 | 489 | } |
491 | 490 | collision_map[ x ] |= ( 1 << i ); |
492 | | |
491 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x + 1 ) = color; | |
493 | 492 | } |
494 | 493 | } |
495 | 494 | } |
r18113 | r18114 | |
498 | 497 | else |
499 | 498 | { |
500 | 499 | /* Regular sprite */ |
501 | if ( y <= ( vpos - | |
500 | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) | |
502 | 501 | { |
503 | UINT16 color = 16 + ( ( state->m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); | |
504 | UINT8 chr = state->m_o2_vdc.s.shape[i][ ( ( vpos - state->m_start_vpos - y ) >> 1 ) ]; | |
505 | int x = state->m_o2_vdc.s.sprites[i].x; | |
502 | UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); | |
503 | UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 1 ) ]; | |
504 | int x = m_o2_vdc.s.sprites[i].x; | |
506 | 505 | UINT8 m; |
507 | 506 | |
508 | 507 | for ( m = 0x01; m > 0; m <<= 1, x++ ) |
r18113 | r18114 | |
512 | 511 | if ( x >= 0 && x < 160 ) |
513 | 512 | { |
514 | 513 | /* Check if we collide with an already drawn source object */ |
515 | if ( collision_map[ x ] & | |
514 | if ( collision_map[ x ] & m_o2_vdc.s.collision ) | |
516 | 515 | { |
517 | | |
516 | m_collision_status |= ( 1 << i ); | |
518 | 517 | } |
519 | 518 | /* Check if an already drawn object would collide with us */ |
520 | if ( ( 1 << i ) & | |
519 | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) | |
521 | 520 | { |
522 | | |
521 | m_collision_status |= collision_map[ x ]; | |
523 | 522 | } |
524 | 523 | collision_map[ x ] |= ( 1 << i ); |
525 | | |
524 | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; | |
526 | 525 | } |
527 | 526 | } |
528 | 527 | } |
r18113 | r18114 | |
533 | 532 | } |
534 | 533 | |
535 | 534 | /* Check for start of VBlank */ |
536 | if ( vpos == | |
535 | if ( vpos == m_start_vblank ) | |
537 | 536 | { |
538 | state->m_control_status |= 0x08; | |
539 | if ( ! state->m_iff ) | |
537 | m_control_status |= 0x08; | |
538 | if ( ! m_iff ) | |
540 | 539 | { |
541 | machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); | |
542 | state->m_iff = 1; | |
540 | machine().device("maincpu")->execute().set_input_line(0, ASSERT_LINE); | |
541 | m_iff = 1; | |
543 | 542 | } |
544 | 543 | } |
545 | 544 | } |
546 | 545 | |
547 | ||
546 | TIMER_CALLBACK_MEMBER(odyssey2_state::i824x_hblank_callback) | |
548 | 547 | { |
549 | odyssey2_state *state = machine.driver_data<odyssey2_state>(); | |
550 | int vpos = machine.primary_screen->vpos(); | |
548 | int vpos = machine().primary_screen->vpos(); | |
551 | 549 | |
552 | if ( vpos < | |
550 | if ( vpos < m_start_vpos - 1 ) | |
553 | 551 | return; |
554 | 552 | |
555 | if ( vpos < | |
553 | if ( vpos < m_start_vblank - 1 ) | |
556 | 554 | { |
557 | | |
555 | m_control_status |= 0x01; | |
558 | 556 | } |
559 | 557 | } |
560 | 558 | |
r18113 | r18114 | |
590 | 588 | |
591 | 589 | screen->register_screen_bitmap(m_tmp_bitmap); |
592 | 590 | |
593 | m_i824x_line_timer = machine().scheduler().timer_alloc(FUNC(i824x_scanline_callback)); | |
591 | m_i824x_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(odyssey2_state::i824x_scanline_callback),this)); | |
594 | 592 | m_i824x_line_timer->adjust( machine().primary_screen->time_until_pos(1, I824X_START_ACTIVE_SCAN ), 0, machine().primary_screen->scan_period() ); |
595 | 593 | |
596 | m_i824x_hblank_timer = machine().scheduler().timer_alloc(FUNC(i824x_hblank_callback)); | |
594 | m_i824x_hblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(odyssey2_state::i824x_hblank_callback),this)); | |
597 | 595 | m_i824x_hblank_timer->adjust( machine().primary_screen->time_until_pos(1, I824X_END_ACTIVE_SCAN + 18 ), 0, machine().primary_screen->scan_period() ); |
598 | 596 | } |
599 | 597 |
r18113 | r18114 | |
---|---|---|
651 | 651 | } |
652 | 652 | } |
653 | 653 | |
654 | ||
654 | TIMER_CALLBACK_MEMBER(mac_state::dafb_vbl_tick) | |
655 | 655 | { |
656 | mac_state *mac = machine.driver_data<mac_state>(); | |
657 | 656 | |
658 | mac->m_dafb_int_status |= 1; | |
659 | dafb_recalc_ints(mac); | |
657 | m_dafb_int_status |= 1; | |
658 | dafb_recalc_ints(this); | |
660 | 659 | |
661 | m | |
660 | m_vbl_timer->adjust(m_screen->time_until_pos(480, 0), 0); | |
662 | 661 | } |
663 | 662 | |
664 | ||
663 | TIMER_CALLBACK_MEMBER(mac_state::dafb_cursor_tick) | |
665 | 664 | { |
666 | mac_state *mac = machine.driver_data<mac_state>(); | |
667 | 665 | |
668 | mac->m_dafb_int_status |= 4; | |
669 | dafb_recalc_ints(mac); | |
666 | m_dafb_int_status |= 4; | |
667 | dafb_recalc_ints(this); | |
670 | 668 | |
671 | m | |
669 | m_cursor_timer->adjust(m_screen->time_until_pos(m_cursor_line, 0), 0); | |
672 | 670 | } |
673 | 671 | |
674 | 672 | VIDEO_START_MEMBER(mac_state,macdafb) |
675 | 673 | { |
676 | m_vbl_timer = machine().scheduler().timer_alloc(FUNC(dafb_vbl_tick)); | |
677 | m_cursor_timer = machine().scheduler().timer_alloc(FUNC(dafb_cursor_tick)); | |
674 | m_vbl_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::dafb_vbl_tick),this)); | |
675 | m_cursor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::dafb_cursor_tick),this)); | |
678 | 676 | |
679 | 677 | m_vbl_timer->adjust(attotime::never); |
680 | 678 | m_cursor_timer->adjust(attotime::never); |
r18113 | r18114 | |
---|---|---|
4 | 4 | #define Y_PIXELS 200 |
5 | 5 | |
6 | 6 | |
7 | ||
7 | TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_scanline) | |
8 | 8 | { |
9 | gamecom_state *state = machine.driver_data<gamecom_state>(); | |
10 | 9 | // draw line |
11 | if ( state->m_scanline == 0 ) | |
12 | state->m_base_address = ( state->m_p_ram[SM8521_LCDC] & 0x40 ) ? 0x2000 : 0x0000; | |
10 | if ( m_scanline == 0 ) | |
11 | m_base_address = ( m_p_ram[SM8521_LCDC] & 0x40 ) ? 0x2000 : 0x0000; | |
13 | 12 | |
14 | if ( ~ | |
13 | if ( ~m_p_ram[SM8521_LCDC] & 0x80 ) | |
15 | 14 | { |
16 | rectangle rec(0, Y_PIXELS - 1, state->m_scanline, state->m_scanline); | |
17 | state->m_bitmap.fill(0, rec ); | |
15 | rectangle rec(0, Y_PIXELS - 1, m_scanline, m_scanline); | |
16 | m_bitmap.fill(0, rec ); | |
18 | 17 | return; |
19 | 18 | } |
20 | 19 | else |
21 | 20 | { |
22 | UINT8 *line = & | |
21 | UINT8 *line = &m_p_videoram[ m_base_address + 40 * m_scanline ]; | |
23 | 22 | int pal[4]; |
24 | 23 | int i; |
25 | 24 | |
26 | switch( | |
25 | switch( m_p_ram[SM8521_LCDC] & 0x30 ) | |
27 | 26 | { |
28 | 27 | case 0x00: |
29 | 28 | pal[0] = 4; |
r18113 | r18114 | |
53 | 52 | for( i = 0; i < 40; i++ ) |
54 | 53 | { |
55 | 54 | UINT8 p = line[i]; |
56 | state->m_bitmap.pix16(i * 4 + 0, state->m_scanline) = pal[ ( p >> 6 ) & 3 ]; | |
57 | state->m_bitmap.pix16(i * 4 + 1, state->m_scanline) = pal[ ( p >> 4 ) & 3 ]; | |
58 | state->m_bitmap.pix16(i * 4 + 2, state->m_scanline) = pal[ ( p >> 2 ) & 3 ]; | |
59 | state->m_bitmap.pix16(i * 4 + 3, state->m_scanline) = pal[ ( p ) & 3 ]; | |
55 | m_bitmap.pix16(i * 4 + 0, m_scanline) = pal[ ( p >> 6 ) & 3 ]; | |
56 | m_bitmap.pix16(i * 4 + 1, m_scanline) = pal[ ( p >> 4 ) & 3 ]; | |
57 | m_bitmap.pix16(i * 4 + 2, m_scanline) = pal[ ( p >> 2 ) & 3 ]; | |
58 | m_bitmap.pix16(i * 4 + 3, m_scanline) = pal[ ( p ) & 3 ]; | |
60 | 59 | } |
61 | 60 | } |
62 | 61 | |
63 | | |
62 | m_scanline = ( m_scanline + 1 ) % Y_PIXELS; | |
64 | 63 | } |
65 | 64 | |
66 | 65 | void gamecom_state::video_start() |
67 | 66 | { |
68 | m_scanline_timer = machine().scheduler().timer_alloc(FUNC(gamecom_scanline)); | |
67 | m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamecom_state::gamecom_scanline),this)); | |
69 | 68 | m_scanline_timer->adjust( machine().primary_screen->time_until_pos(0 ), 0, machine().primary_screen->scan_period() ); |
70 | 69 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
71 | 70 | } |
r18113 | r18114 | |
---|---|---|
166 | 166 | // TIMER_CALLBACK( atarist_shifter_tick ) |
167 | 167 | //------------------------------------------------- |
168 | 168 | |
169 | ||
169 | TIMER_CALLBACK_MEMBER(st_state::atarist_shifter_tick) | |
170 | 170 | { |
171 | st_state *state = machine.driver_data<st_state>(); | |
172 | 171 | |
173 | s | |
172 | shifter_tick(); | |
174 | 173 | } |
175 | 174 | |
176 | 175 | |
r18113 | r18114 | |
298 | 297 | // TIMER_CALLBACK( atarist_glue_tick ) |
299 | 298 | //------------------------------------------------- |
300 | 299 | |
301 | ||
300 | TIMER_CALLBACK_MEMBER(st_state::atarist_glue_tick) | |
302 | 301 | { |
303 | st_state *state = machine.driver_data<st_state>(); | |
304 | 302 | |
305 | | |
303 | glue_tick(); | |
306 | 304 | } |
307 | 305 | |
308 | 306 | |
r18113 | r18114 | |
752 | 750 | // TIMER_CALLBACK( atarist_blitter_tick ) |
753 | 751 | //------------------------------------------------- |
754 | 752 | |
755 | ||
753 | TIMER_CALLBACK_MEMBER(st_state::atarist_blitter_tick) | |
756 | 754 | { |
757 | st_state *state = machine.driver_data<st_state>(); | |
758 | 755 | |
759 | | |
756 | blitter_tick(); | |
760 | 757 | } |
761 | 758 | |
762 | 759 | |
r18113 | r18114 | |
1086 | 1083 | m_mfp->i3_w(m_blitter_done); |
1087 | 1084 | |
1088 | 1085 | int nops = BLITTER_NOPS[m_blitter_op][m_blitter_hop]; // each NOP takes 4 cycles |
1089 | machine().scheduler().timer_set(attotime::from_hz((Y2/4)/(4*nops)), FUNC(atarist_blitter_tick)); | |
1086 | machine().scheduler().timer_set(attotime::from_hz((Y2/4)/(4*nops)), timer_expired_delegate(FUNC(st_state::atarist_blitter_tick),this)); | |
1090 | 1087 | } |
1091 | 1088 | } |
1092 | 1089 | } |
r18113 | r18114 | |
1108 | 1105 | |
1109 | 1106 | void st_state::video_start() |
1110 | 1107 | { |
1111 | m_shifter_timer = machine().scheduler().timer_alloc(FUNC(atarist_shifter_tick)); | |
1112 | m_glue_timer = machine().scheduler().timer_alloc(FUNC(atarist_glue_tick)); | |
1108 | m_shifter_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_state::atarist_shifter_tick),this)); | |
1109 | m_glue_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_state::atarist_glue_tick),this)); | |
1113 | 1110 | |
1114 | 1111 | // m_shifter_timer->adjust(machine().primary_screen->time_until_pos(0), 0, attotime::from_hz(Y2/4)); // 125 ns |
1115 | 1112 | m_glue_timer->adjust(machine().primary_screen->time_until_pos(0), 0, attotime::from_hz(Y2/16)); // 500 ns |
r18113 | r18114 | |
---|---|---|
1766 | 1766 | } |
1767 | 1767 | } |
1768 | 1768 | |
1769 | ||
1769 | TIMER_CALLBACK_MEMBER(towns_state::towns_sprite_done) | |
1770 | 1770 | { |
1771 | 1771 | // sprite drawing is complete, lower flag |
1772 | towns_state* state = machine.driver_data<towns_state>(); | |
1773 | state->m_video.towns_sprite_flag = 0; | |
1774 | if(state->m_video.towns_sprite_page != 0) | |
1775 | state->m_video.towns_crtc_reg[21] |= 0x8000; | |
1772 | m_video.towns_sprite_flag = 0; | |
1773 | if(m_video.towns_sprite_page != 0) | |
1774 | m_video.towns_crtc_reg[21] |= 0x8000; | |
1776 | 1775 | else |
1777 | | |
1776 | m_video.towns_crtc_reg[21] &= ~0x8000; | |
1778 | 1777 | } |
1779 | 1778 | |
1780 | ||
1779 | TIMER_CALLBACK_MEMBER(towns_state::towns_vblank_end) | |
1781 | 1780 | { |
1782 | 1781 | // here we'll clear the vsync signal, I presume it goes low on it's own eventually |
1783 | towns_state* state = machine.driver_data<towns_state>(); | |
1784 | 1782 | device_t* dev = (device_t*)ptr; |
1785 | 1783 | pic8259_ir3_w(dev, 0); // IRQ11 = VSync |
1786 | 1784 | if(IRQ_LOG) logerror("PIC: IRQ11 (VSync) set low\n"); |
1787 | | |
1785 | m_video.towns_vblank_flag = 0; | |
1788 | 1786 | } |
1789 | 1787 | |
1790 | 1788 | INTERRUPT_GEN_MEMBER(towns_state::towns_vsync_irq) |
r18113 | r18114 | |
1793 | 1791 | pic8259_ir3_w(dev, 1); // IRQ11 = VSync |
1794 | 1792 | if(IRQ_LOG) logerror("PIC: IRQ11 (VSync) set high\n"); |
1795 | 1793 | m_video.towns_vblank_flag = 1; |
1796 | machine().scheduler().timer_set(machine().primary_screen->time_until_vblank_end(), FUNC(towns_vblank_end), 0, (void*)dev); | |
1794 | machine().scheduler().timer_set(machine().primary_screen->time_until_vblank_end(), timer_expired_delegate(FUNC(towns_state::towns_vblank_end),this), 0, (void*)dev); | |
1797 | 1795 | if(m_video.towns_tvram_enable) |
1798 | 1796 | draw_text_layer(dev->machine()); |
1799 | 1797 | if(m_video.towns_sprite_reg[1] & 0x80) |
r18113 | r18114 | |
1804 | 1802 | { |
1805 | 1803 | m_video.towns_vram_wplane = 0x00; |
1806 | 1804 | m_video.towns_sprite_page = 0; |
1807 | m_video.sprite_timer = machine().scheduler().timer_alloc(FUNC(towns_sprite_done)); | |
1805 | m_video.sprite_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(towns_state::towns_sprite_done),this)); | |
1808 | 1806 | } |
1809 | 1807 | |
1810 | 1808 | UINT32 towns_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
r18113 | r18114 | |
---|---|---|
108 | 108 | |
109 | 109 | } |
110 | 110 | |
111 | ||
111 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_operation_end) | |
112 | 112 | { |
113 | x68k_state *state = machine.driver_data<x68k_state>(); | |
114 | 113 | int bit = param; |
115 | | |
114 | m_crtc.operation &= ~bit; | |
116 | 115 | } |
117 | 116 | |
118 | 117 | static void x68k_crtc_refresh_mode(running_machine &machine) |
r18113 | r18114 | |
174 | 173 | machine.primary_screen->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45)); |
175 | 174 | } |
176 | 175 | |
177 | TIMER_CALLBACK(x68k_hsync) | |
176 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync) | |
178 | 177 | { |
179 | x68k_state *state = machine.driver_data<x68k_state>(); | |
180 | 178 | int hstate = param; |
181 | 179 | attotime hsync_time; |
182 | 180 | |
183 | state->m_crtc.hblank = hstate; | |
184 | state->m_mfpdev->i7_w(!state->m_crtc.hblank); | |
185 | if(state->m_crtc.vmultiple == 2) // 256-line (doublescan) | |
181 | m_crtc.hblank = hstate; | |
182 | m_mfpdev->i7_w(!m_crtc.hblank); | |
183 | if(m_crtc.vmultiple == 2) // 256-line (doublescan) | |
186 | 184 | { |
187 | 185 | if(hstate == 1) |
188 | 186 | { |
189 | if( | |
187 | if(m_oddscanline == 1) | |
190 | 188 | { |
191 | int scan = machine.primary_screen->vpos(); | |
192 | if(scan > state->m_crtc.vend) | |
193 | scan = state->m_crtc.vbegin; | |
194 | hsync_time = machine.primary_screen->time_until_pos(scan,(state->m_crtc.htotal + state->m_crtc.hend) / 2); | |
195 | state->m_scanline_timer->adjust(hsync_time); | |
189 | int scan = machine().primary_screen->vpos(); | |
190 | if(scan > m_crtc.vend) | |
191 | scan = m_crtc.vbegin; | |
192 | hsync_time = machine().primary_screen->time_until_pos(scan,(m_crtc.htotal + m_crtc.hend) / 2); | |
193 | m_scanline_timer->adjust(hsync_time); | |
196 | 194 | if(scan != 0) |
197 | 195 | { |
198 | if((machine.root_device().ioport("options")->read() & 0x04)) | |
196 | if((machine().root_device().ioport("options")->read() & 0x04)) | |
199 | 197 | { |
200 | machine.primary_screen->update_partial(scan); | |
198 | machine().primary_screen->update_partial(scan); | |
201 | 199 | } |
202 | 200 | } |
203 | 201 | } |
204 | 202 | else |
205 | 203 | { |
206 | int scan = machine.primary_screen->vpos(); | |
207 | if(scan > state->m_crtc.vend) | |
208 | scan = state->m_crtc.vbegin; | |
209 | hsync_time = machine.primary_screen->time_until_pos(scan,state->m_crtc.hend / 2); | |
210 | state->m_scanline_timer->adjust(hsync_time); | |
204 | int scan = machine().primary_screen->vpos(); | |
205 | if(scan > m_crtc.vend) | |
206 | scan = m_crtc.vbegin; | |
207 | hsync_time = machine().primary_screen->time_until_pos(scan,m_crtc.hend / 2); | |
208 | m_scanline_timer->adjust(hsync_time); | |
211 | 209 | if(scan != 0) |
212 | 210 | { |
213 | if((machine.root_device().ioport("options")->read() & 0x04)) | |
211 | if((machine().root_device().ioport("options")->read() & 0x04)) | |
214 | 212 | { |
215 | machine.primary_screen->update_partial(scan); | |
213 | machine().primary_screen->update_partial(scan); | |
216 | 214 | } |
217 | 215 | } |
218 | 216 | } |
219 | 217 | } |
220 | 218 | if(hstate == 0) |
221 | 219 | { |
222 | if( | |
220 | if(m_oddscanline == 1) | |
223 | 221 | { |
224 | int scan = machine.primary_screen->vpos(); | |
225 | if(scan > state->m_crtc.vend) | |
226 | scan = state->m_crtc.vbegin; | |
222 | int scan = machine().primary_screen->vpos(); | |
223 | if(scan > m_crtc.vend) | |
224 | scan = m_crtc.vbegin; | |
227 | 225 | else |
228 | 226 | scan++; |
229 | hsync_time = machine.primary_screen->time_until_pos(scan,state->m_crtc.hbegin / 2); | |
230 | state->m_scanline_timer->adjust(hsync_time, 1); | |
231 | state->m_oddscanline = 0; | |
227 | hsync_time = machine().primary_screen->time_until_pos(scan,m_crtc.hbegin / 2); | |
228 | m_scanline_timer->adjust(hsync_time, 1); | |
229 | m_oddscanline = 0; | |
232 | 230 | } |
233 | 231 | else |
234 | 232 | { |
235 | hsync_time = machine.primary_screen->time_until_pos(machine.primary_screen->vpos(),(state->m_crtc.htotal + state->m_crtc.hbegin) / 2); | |
236 | state->m_scanline_timer->adjust(hsync_time, 1); | |
237 | state->m_oddscanline = 1; | |
233 | hsync_time = machine().primary_screen->time_until_pos(machine().primary_screen->vpos(),(m_crtc.htotal + m_crtc.hbegin) / 2); | |
234 | m_scanline_timer->adjust(hsync_time, 1); | |
235 | m_oddscanline = 1; | |
238 | 236 | } |
239 | 237 | } |
240 | 238 | } |
r18113 | r18114 | |
242 | 240 | { |
243 | 241 | if(hstate == 1) |
244 | 242 | { |
245 | int scan = machine.primary_screen->vpos(); | |
246 | if(scan > state->m_crtc.vend) | |
243 | int scan = machine().primary_screen->vpos(); | |
244 | if(scan > m_crtc.vend) | |
247 | 245 | scan = 0; |
248 | hsync_time = machine.primary_screen->time_until_pos(scan,state->m_crtc.hend); | |
249 | state->m_scanline_timer->adjust(hsync_time); | |
246 | hsync_time = machine().primary_screen->time_until_pos(scan,m_crtc.hend); | |
247 | m_scanline_timer->adjust(hsync_time); | |
250 | 248 | if(scan != 0) |
251 | 249 | { |
252 | if((machine.root_device().ioport("options")->read() & 0x04)) | |
250 | if((machine().root_device().ioport("options")->read() & 0x04)) | |
253 | 251 | { |
254 | machine.primary_screen->update_partial(scan); | |
252 | machine().primary_screen->update_partial(scan); | |
255 | 253 | } |
256 | 254 | } |
257 | 255 | } |
258 | 256 | if(hstate == 0) |
259 | 257 | { |
260 | hsync_time = machine.primary_screen->time_until_pos(machine.primary_screen->vpos()+1,state->m_crtc.hbegin); | |
261 | state->m_scanline_timer->adjust(hsync_time, 1); | |
262 | // if(!(state->m_mfp.gpio & 0x40)) // if GPIP6 is active, clear it | |
263 | // state->m_mfp.gpio |= 0x40; | |
258 | hsync_time = machine().primary_screen->time_until_pos(machine().primary_screen->vpos()+1,m_crtc.hbegin); | |
259 | m_scanline_timer->adjust(hsync_time, 1); | |
260 | // if(!(m_mfp.gpio & 0x40)) // if GPIP6 is active, clear it | |
261 | // m_mfp.gpio |= 0x40; | |
264 | 262 | } |
265 | 263 | } |
266 | 264 | } |
267 | 265 | |
268 | ||
266 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_raster_end) | |
269 | 267 | { |
270 | x68k_state *state = machine.driver_data<x68k_state>(); | |
271 | state->m_mfp.gpio |= 0x40; | |
272 | state->m_mfpdev->i6_w(1); | |
268 | m_mfp.gpio |= 0x40; | |
269 | m_mfpdev->i6_w(1); | |
273 | 270 | } |
274 | 271 | |
275 | TIMER_CALLBACK(x68k_crtc_raster_irq) | |
272 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_raster_irq) | |
276 | 273 | { |
277 | x68k_state *state = machine.driver_data<x68k_state>(); | |
278 | 274 | int scan = param; |
279 | 275 | attotime irq_time; |
280 | 276 | attotime end_time; |
281 | 277 | |
282 | if(scan <= | |
278 | if(scan <= m_crtc.vtotal) | |
283 | 279 | { |
284 | state->m_mfp.gpio &= ~0x40; // GPIP6 | |
285 | state->m_mfpdev->i6_w(0); | |
286 | machine.primary_screen->update_partial(scan); | |
287 | irq_time = machine.primary_screen->time_until_pos(scan,state->m_crtc.hbegin); | |
280 | m_mfp.gpio &= ~0x40; // GPIP6 | |
281 | m_mfpdev->i6_w(0); | |
282 | machine().primary_screen->update_partial(scan); | |
283 | irq_time = machine().primary_screen->time_until_pos(scan,m_crtc.hbegin); | |
288 | 284 | // end of HBlank period clears GPIP6 also? |
289 | end_time = machine.primary_screen->time_until_pos(scan,state->m_crtc.hend); | |
290 | state->m_raster_irq->adjust(irq_time, scan); | |
291 | machine.scheduler().timer_set(end_time, FUNC(x68k_crtc_raster_end)); | |
292 | logerror("GPIP6: Raster triggered at line %i (%i)\n",scan,machine.primary_screen->vpos()); | |
285 | end_time = machine().primary_screen->time_until_pos(scan,m_crtc.hend); | |
286 | m_raster_irq->adjust(irq_time, scan); | |
287 | machine().scheduler().timer_set(end_time, timer_expired_delegate(FUNC(x68k_state::x68k_crtc_raster_end),this)); | |
288 | logerror("GPIP6: Raster triggered at line %i (%i)\n",scan,machine().primary_screen->vpos()); | |
293 | 289 | } |
294 | 290 | } |
295 | 291 | |
296 | TIMER_CALLBACK(x68k_crtc_vblank_irq) | |
292 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_vblank_irq) | |
297 | 293 | { |
298 | x68k_state *state = machine.driver_data<x68k_state>(); | |
299 | device_t *x68k_mfp = machine.device(MC68901_TAG); | |
294 | device_t *x68k_mfp = machine().device(MC68901_TAG); | |
300 | 295 | int val = param; |
301 | 296 | attotime irq_time; |
302 | 297 | int vblank_line; |
303 | 298 | |
304 | 299 | if(val == 1) // V-DISP on |
305 | 300 | { |
306 | state->m_crtc.vblank = 1; | |
307 | vblank_line = state->m_crtc.vbegin; | |
308 | irq_time = machine.primary_screen->time_until_pos(vblank_line,2); | |
309 | state->m_vblank_irq->adjust(irq_time); | |
301 | m_crtc.vblank = 1; | |
302 | vblank_line = m_crtc.vbegin; | |
303 | irq_time = machine().primary_screen->time_until_pos(vblank_line,2); | |
304 | m_vblank_irq->adjust(irq_time); | |
310 | 305 | logerror("CRTC: VBlank on\n"); |
311 | 306 | } |
312 | 307 | if(val == 0) // V-DISP off |
313 | 308 | { |
314 | state->m_crtc.vblank = 0; | |
315 | vblank_line = state->m_crtc.vend; | |
316 | if(vblank_line > state->m_crtc.vtotal) | |
317 | vblank_line = state->m_crtc.vtotal; | |
318 | irq_time = machine.primary_screen->time_until_pos(vblank_line,2); | |
319 | state->m_vblank_irq->adjust(irq_time, 1); | |
309 | m_crtc.vblank = 0; | |
310 | vblank_line = m_crtc.vend; | |
311 | if(vblank_line > m_crtc.vtotal) | |
312 | vblank_line = m_crtc.vtotal; | |
313 | irq_time = machine().primary_screen->time_until_pos(vblank_line,2); | |
314 | m_vblank_irq->adjust(irq_time, 1); | |
320 | 315 | logerror("CRTC: VBlank off\n"); |
321 | 316 | } |
322 | 317 | |
323 | 318 | if (x68k_mfp != NULL) |
324 | 319 | { |
325 | state->m_mfpdev->tai_w(!state->m_crtc.vblank); | |
326 | state->m_mfpdev->i4_w(!state->m_crtc.vblank); | |
320 | m_mfpdev->tai_w(!m_crtc.vblank); | |
321 | m_mfpdev->i4_w(!m_crtc.vblank); | |
327 | 322 | } |
328 | 323 | } |
329 | 324 | |
r18113 | r18114 | |
449 | 444 | if(data & 0x08) // text screen raster copy |
450 | 445 | { |
451 | 446 | x68k_crtc_text_copy(state, (state->m_crtc.reg[22] & 0xff00) >> 8,(state->m_crtc.reg[22] & 0x00ff)); |
452 | space.machine().scheduler().timer_set(attotime::from_msec(1), FUNC(x68k_crtc_operation_end), 0x02); // time taken to do operation is a complete guess. | |
447 | space.machine().scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(x68k_state::x68k_crtc_operation_end),state), 0x02); // time taken to do operation is a complete guess. | |
453 | 448 | } |
454 | 449 | if(data & 0x02) // high-speed graphic screen clear |
455 | 450 | { |
r18113 | r18114 | |
457 | 452 | memset(state->m_gvram32,0,0x40000); |
458 | 453 | else |
459 | 454 | memset(state->m_gvram16,0,0x40000); |
460 | space.machine().scheduler().timer_set(attotime::from_msec(10), FUNC(x68k_crtc_operation_end), 0x02); // time taken to do operation is a complete guess. | |
455 | space.machine().scheduler().timer_set(attotime::from_msec(10), timer_expired_delegate(FUNC(x68k_state::x68k_crtc_operation_end),state), 0x02); // time taken to do operation is a complete guess. | |
461 | 456 | } |
462 | 457 | break; |
463 | 458 | } |
r18113 | r18114 | |
---|---|---|
13 | 13 | #include "cpu/z80/z80.h" |
14 | 14 | |
15 | 15 | |
16 | ||
16 | TIMER_CALLBACK_MEMBER(galaxy_state::gal_video) | |
17 | 17 | { |
18 | galaxy_state *state = machine.driver_data<galaxy_state>(); | |
19 | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); | |
18 | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); | |
20 | 19 | int y, x; |
21 | if ( | |
20 | if (m_interrupts_enabled == TRUE) | |
22 | 21 | { |
23 | UINT8 *gfx = state->memregion("gfx1")->base(); | |
24 | UINT8 dat = (state->m_latch_value & 0x3c) >> 2; | |
25 | if ((state->m_gal_cnt >= 48 * 2) && (state->m_gal_cnt < 48 * 210)) // display on screen just state->m_first 208 lines | |
22 | UINT8 *gfx = memregion("gfx1")->base(); | |
23 | UINT8 dat = (m_latch_value & 0x3c) >> 2; | |
24 | if ((m_gal_cnt >= 48 * 2) && (m_gal_cnt < 48 * 210)) // display on screen just m_first 208 lines | |
26 | 25 | { |
27 | UINT8 mode = (state->m_latch_value >> 1) & 1; // bit 2 latch represents mode | |
28 | UINT16 addr = (machine.device("maincpu")->state().state_int(Z80_I) << 8) | machine.device("maincpu")->state().state_int(Z80_R) | ((state->m_latch_value & 0x80) ^ 0x80); | |
26 | UINT8 mode = (m_latch_value >> 1) & 1; // bit 2 latch represents mode | |
27 | UINT16 addr = (machine().device("maincpu")->state().state_int(Z80_I) << 8) | machine().device("maincpu")->state().state_int(Z80_R) | ((m_latch_value & 0x80) ^ 0x80); | |
29 | 28 | if (mode == 0) |
30 | 29 | { |
31 | 30 | // Text mode |
32 | if ( | |
31 | if (m_first == 0 && (machine().device("maincpu")->state().state_int(Z80_R) & 0x1f) == 0) | |
33 | 32 | { |
34 | 33 | // Due to a fact that on real processor latch value is set at |
35 | 34 | // the end of last cycle we need to skip dusplay of double |
36 | // state->m_first char in each row | |
37 | state->m_code = 0x00; | |
38 | state->m_first = 1; | |
35 | // m_first char in each row | |
36 | m_code = 0x00; | |
37 | m_first = 1; | |
39 | 38 | } |
40 | 39 | else |
41 | 40 | { |
42 | state->m_code = space.read_byte(addr) & 0xbf; | |
43 | state->m_code += (state->m_code & 0x80) >> 1; | |
44 | state->m_code = gfx[(state->m_code & 0x7f) +(dat << 7 )] ^ 0xff; | |
45 | state->m_first = 0; | |
41 | m_code = space.read_byte(addr) & 0xbf; | |
42 | m_code += (m_code & 0x80) >> 1; | |
43 | m_code = gfx[(m_code & 0x7f) +(dat << 7 )] ^ 0xff; | |
44 | m_first = 0; | |
46 | 45 | } |
47 | y = state->m_gal_cnt / 48 - 2; | |
48 | x = (state->m_gal_cnt % 48) * 8; | |
46 | y = m_gal_cnt / 48 - 2; | |
47 | x = (m_gal_cnt % 48) * 8; | |
49 | 48 | |
50 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 0) & 1; x++; | |
51 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 1) & 1; x++; | |
52 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 2) & 1; x++; | |
53 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 3) & 1; x++; | |
54 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 4) & 1; x++; | |
55 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 5) & 1; x++; | |
56 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 6) & 1; x++; | |
57 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 7) & 1; | |
49 | m_bitmap.pix16(y, x ) = (m_code >> 0) & 1; x++; | |
50 | m_bitmap.pix16(y, x ) = (m_code >> 1) & 1; x++; | |
51 | m_bitmap.pix16(y, x ) = (m_code >> 2) & 1; x++; | |
52 | m_bitmap.pix16(y, x ) = (m_code >> 3) & 1; x++; | |
53 | m_bitmap.pix16(y, x ) = (m_code >> 4) & 1; x++; | |
54 | m_bitmap.pix16(y, x ) = (m_code >> 5) & 1; x++; | |
55 | m_bitmap.pix16(y, x ) = (m_code >> 6) & 1; x++; | |
56 | m_bitmap.pix16(y, x ) = (m_code >> 7) & 1; | |
58 | 57 | } |
59 | 58 | else |
60 | 59 | { // Graphics mode |
61 | if ( | |
60 | if (m_first < 4 && (machine().device("maincpu")->state().state_int(Z80_R) & 0x1f) == 0) | |
62 | 61 | { |
63 | 62 | // Due to a fact that on real processor latch value is set at |
64 | 63 | // the end of last cycle we need to skip dusplay of 4 times |
65 | // state->m_first char in each row | |
66 | state->m_code = 0x00; | |
67 | state->m_first++; | |
64 | // m_first char in each row | |
65 | m_code = 0x00; | |
66 | m_first++; | |
68 | 67 | } |
69 | 68 | else |
70 | 69 | { |
71 | state->m_code = space.read_byte(addr) ^ 0xff; | |
72 | state->m_first = 0; | |
70 | m_code = space.read_byte(addr) ^ 0xff; | |
71 | m_first = 0; | |
73 | 72 | } |
74 | y = state->m_gal_cnt / 48 - 2; | |
75 | x = (state->m_gal_cnt % 48) * 8; | |
73 | y = m_gal_cnt / 48 - 2; | |
74 | x = (m_gal_cnt % 48) * 8; | |
76 | 75 | |
77 | 76 | /* hack - until calc of R is fixed in Z80 */ |
78 | 77 | if (x == 11 * 8 && y == 0) |
79 | 78 | { |
80 | | |
79 | m_start_addr = addr; | |
81 | 80 | } |
82 | 81 | if ((x / 8 >= 11) && (x / 8 < 44)) |
83 | 82 | { |
84 | | |
83 | m_code = space.read_byte(m_start_addr + y * 32 + (m_gal_cnt % 48) - 11) ^ 0xff; | |
85 | 84 | } |
86 | 85 | else |
87 | 86 | { |
88 | | |
87 | m_code = 0x00; | |
89 | 88 | } |
90 | 89 | /* end of hack */ |
91 | 90 | |
92 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 0) & 1; x++; | |
93 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 1) & 1; x++; | |
94 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 2) & 1; x++; | |
95 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 3) & 1; x++; | |
96 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 4) & 1; x++; | |
97 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 5) & 1; x++; | |
98 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 6) & 1; x++; | |
99 | state->m_bitmap.pix16(y, x ) = (state->m_code >> 7) & 1; | |
91 | m_bitmap.pix16(y, x ) = (m_code >> 0) & 1; x++; | |
92 | m_bitmap.pix16(y, x ) = (m_code >> 1) & 1; x++; | |
93 | m_bitmap.pix16(y, x ) = (m_code >> 2) & 1; x++; | |
94 | m_bitmap.pix16(y, x ) = (m_code >> 3) & 1; x++; | |
95 | m_bitmap.pix16(y, x ) = (m_code >> 4) & 1; x++; | |
96 | m_bitmap.pix16(y, x ) = (m_code >> 5) & 1; x++; | |
97 | m_bitmap.pix16(y, x ) = (m_code >> 6) & 1; x++; | |
98 | m_bitmap.pix16(y, x ) = (m_code >> 7) & 1; | |
100 | 99 | } |
101 | 100 | } |
102 | | |
101 | m_gal_cnt++; | |
103 | 102 | } |
104 | 103 | } |
105 | 104 | |
r18113 | r18114 | |
114 | 113 | { |
115 | 114 | m_gal_cnt = 0; |
116 | 115 | |
117 | m_gal_video_timer = machine().scheduler().timer_alloc(FUNC(gal_video)); | |
116 | m_gal_video_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(galaxy_state::gal_video),this)); | |
118 | 117 | m_gal_video_timer->adjust(attotime::zero, 0, attotime::never); |
119 | 118 | |
120 | 119 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
r18113 | r18114 | |
---|---|---|
12 | 12 | |
13 | 13 | #include "includes/oric.h" |
14 | 14 | |
15 | ||
15 | TIMER_CALLBACK_MEMBER(oric_state::oric_vh_timer_callback) | |
16 | 16 | { |
17 | oric_state *state = machine.driver_data<oric_state>(); | |
18 | 17 | /* update flash count */ |
19 | | |
18 | m_vh_state.flash_count++; | |
20 | 19 | } |
21 | 20 | |
22 | 21 | static void oric_vh_update_flash(oric_state *state) |
r18113 | r18114 | |
299 | 298 | m_vh_state.char_base = 0; |
300 | 299 | /* initialise flash timer */ |
301 | 300 | m_vh_state.flash_count = 0; |
302 | machine().scheduler().timer_pulse(attotime::from_hz(50), FUNC(oric_vh_timer_callback)); | |
301 | machine().scheduler().timer_pulse(attotime::from_hz(50), timer_expired_delegate(FUNC(oric_state::oric_vh_timer_callback),this)); | |
303 | 302 | /* mode */ |
304 | 303 | oric_vh_update_attribute(machine(),(1<<3)|(1<<4)); |
305 | 304 | } |
r18113 | r18114 | |
---|---|---|
84 | 84 | * 32..223 192 visible lines |
85 | 85 | * 224..233 vblank |
86 | 86 | */ |
87 | ||
87 | TIMER_CALLBACK_MEMBER(zx_state::zx_ula_nmi) | |
88 | 88 | { |
89 | zx_state *state = machine.driver_data<zx_state>(); | |
90 | 89 | /* |
91 | 90 | * An NMI is issued on the ZX81 every 64us for the blanked |
92 | 91 | * scanlines at the top and bottom of the display. |
93 | 92 | */ |
94 | screen_device *screen = machine.first_screen(); | |
93 | screen_device *screen = machine().first_screen(); | |
95 | 94 | int height = screen->height(); |
96 | 95 | const rectangle& r1 = screen->visible_area(); |
97 | 96 | rectangle r; |
98 | 97 | |
99 | bitmap_ind16 &bitmap = state->m_bitmap; | |
100 | r.set(r1.min_x, r1.max_x, state->m_ula_scanline_count, state->m_ula_scanline_count); | |
98 | bitmap_ind16 &bitmap = m_bitmap; | |
99 | r.set(r1.min_x, r1.max_x, m_ula_scanline_count, m_ula_scanline_count); | |
101 | 100 | bitmap.fill(1, r); |
102 | // logerror("ULA %3d[%d] NMI, R:$%02X, $%04x\n", machine.primary_screen->vpos(), ula_scancode_count, (unsigned) machine.device("maincpu")->state().state_int(Z80_R), (unsigned) machine.device("maincpu")->state().state_int(Z80_PC)); | |
103 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
104 | if (++state->m_ula_scanline_count == height) | |
105 | state->m_ula_scanline_count = 0; | |
101 | // logerror("ULA %3d[%d] NMI, R:$%02X, $%04x\n", machine().primary_screen->vpos(), ula_scancode_count, (unsigned) machine().device("maincpu")->state().state_int(Z80_R), (unsigned) machine().device("maincpu")->state().state_int(Z80_PC)); | |
102 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
103 | if (++m_ula_scanline_count == height) | |
104 | m_ula_scanline_count = 0; | |
106 | 105 | } |
107 | 106 | |
108 | ||
107 | TIMER_CALLBACK_MEMBER(zx_state::zx_ula_irq) | |
109 | 108 | { |
110 | zx_state *state = machine.driver_data<zx_state>(); | |
111 | 109 | |
112 | 110 | /* |
113 | 111 | * An IRQ is issued on the ZX80/81 whenever the R registers |
114 | 112 | * bit 6 goes low. In MESS this IRQ timed from the first read |
115 | 113 | * from the copy of the DFILE in the upper 32K in zx_ula_r(). |
116 | 114 | */ |
117 | if ( | |
115 | if (m_ula_irq_active) | |
118 | 116 | { |
119 | // logerror("ULA %3d[%d] IRQ, R:$%02X, $%04x\n", machine.primary_screen->vpos(), ula_scancode_count, (unsigned) machine.device("maincpu")->state().state_int(Z80_R), (unsigned) machine.device("maincpu")->state().state_int(Z80_PC)); | |
117 | // logerror("ULA %3d[%d] IRQ, R:$%02X, $%04x\n", machine().primary_screen->vpos(), ula_scancode_count, (unsigned) machine().device("maincpu")->state().state_int(Z80_R), (unsigned) machine().device("maincpu")->state().state_int(Z80_PC)); | |
120 | 118 | |
121 | state->m_ula_irq_active = 0; | |
122 | machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
119 | m_ula_irq_active = 0; | |
120 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); | |
123 | 121 | } |
124 | 122 | } |
125 | 123 | |
r18113 | r18114 | |
163 | 161 | for (y = state->m_charline_ptr; y < ARRAY_LENGTH(state->m_charline); y++) |
164 | 162 | state->m_charline[y] = 0; |
165 | 163 | |
166 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(((32 - state->m_charline_ptr) << 2)), FUNC(zx_ula_irq)); | |
164 | machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(((32 - state->m_charline_ptr) << 2)), timer_expired_delegate(FUNC(zx_state::zx_ula_irq),state)); | |
167 | 165 | state->m_ula_irq_active++; |
168 | 166 | |
169 | 167 | scanline = &bitmap.pix16(state->m_ula_scanline_count); |
r18113 | r18114 | |
192 | 190 | |
193 | 191 | void zx_state::video_start() |
194 | 192 | { |
195 | m_ula_nmi = machine().scheduler().timer_alloc(FUNC(zx_ula_nmi)); | |
193 | m_ula_nmi = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(zx_state::zx_ula_nmi),this)); | |
196 | 194 | m_ula_irq_active = 0; |
197 | 195 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
198 | 196 | } |
r18113 | r18114 | |
---|---|---|
1025 | 1025 | TIMER_CALLBACK( lightgun_tick ) |
1026 | 1026 | -------------------------------------------------*/ |
1027 | 1027 | |
1028 | ||
1028 | TIMER_CALLBACK_MEMBER(sg1000_state::lightgun_tick) | |
1029 | 1029 | { |
1030 | UINT8 *rom = machine.root_device().memregion(Z80_TAG)->base(); | |
1030 | UINT8 *rom = machine().root_device().memregion(Z80_TAG)->base(); | |
1031 | 1031 | |
1032 | 1032 | if (IS_CARTRIDGE_TV_DRAW(rom)) |
1033 | 1033 | { |
1034 | 1034 | /* enable crosshair for TV Draw */ |
1035 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL); | |
1035 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); | |
1036 | 1036 | } |
1037 | 1037 | else |
1038 | 1038 | { |
1039 | 1039 | /* disable crosshair for other cartridges */ |
1040 | crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE); | |
1040 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); | |
1041 | 1041 | } |
1042 | 1042 | } |
1043 | 1043 | |
r18113 | r18114 | |
1048 | 1048 | void sg1000_state::machine_start() |
1049 | 1049 | { |
1050 | 1050 | /* toggle light gun crosshair */ |
1051 | machine().scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); | |
1051 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sg1000_state::lightgun_tick),this)); | |
1052 | 1052 | |
1053 | 1053 | /* register for state saving */ |
1054 | 1054 | save_item(NAME(m_tvdraw_data)); |
r18113 | r18114 | |
1061 | 1061 | void sc3000_state::machine_start() |
1062 | 1062 | { |
1063 | 1063 | /* toggle light gun crosshair */ |
1064 | machine().scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); | |
1064 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sg1000_state::lightgun_tick),this)); | |
1065 | 1065 | |
1066 | 1066 | /* register for state saving */ |
1067 | 1067 | save_item(NAME(m_tvdraw_data)); |
r18113 | r18114 | |
---|---|---|
84 | 84 | |
85 | 85 | /* M6532 Interface */ |
86 | 86 | |
87 | ||
87 | TIMER_CALLBACK_MEMBER(beta_state::led_refresh) | |
88 | 88 | { |
89 | beta_state *state = machine.driver_data<beta_state>(); | |
90 | 89 | |
91 | if ( | |
90 | if (m_ls145_p < 6) | |
92 | 91 | { |
93 | output_set_digit_value( | |
92 | output_set_digit_value(m_ls145_p, m_segment); | |
94 | 93 | } |
95 | 94 | } |
96 | 95 | |
r18113 | r18114 | |
237 | 236 | |
238 | 237 | void beta_state::machine_start() |
239 | 238 | { |
240 | m_led_refresh_timer = machine().scheduler().timer_alloc(FUNC(led_refresh)); | |
239 | m_led_refresh_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(beta_state::led_refresh),this)); | |
241 | 240 | |
242 | 241 | /* register for state saving */ |
243 | 242 | save_item(NAME(m_eprom_oe)); |
r18113 | r18114 | |
---|---|---|
666 | 666 | m_cass_data = m_regs_w[7]; |
667 | 667 | } |
668 | 668 | |
669 | ||
669 | TIMER_CALLBACK_MEMBER(x07_state::cassette_tick) | |
670 | 670 | { |
671 | x07_state *state = machine.driver_data<x07_state>(); | |
672 | state->m_cass_clk++; | |
671 | m_cass_clk++; | |
673 | 672 | } |
674 | 673 | |
675 | ||
674 | TIMER_CALLBACK_MEMBER(x07_state::cassette_poll) | |
676 | 675 | { |
677 | x07_state *state = machine.driver_data<x07_state>(); | |
678 | 676 | |
679 | if ((state->m_cassette->get_state() & 0x03) == CASSETTE_PLAY) | |
680 | state->cassette_load(); | |
681 | else if ((state->m_cassette->get_state() & 0x03) == CASSETTE_RECORD) | |
682 | state->cassette_save(); | |
677 | if ((m_cassette->get_state() & 0x03) == CASSETTE_PLAY) | |
678 | cassette_load(); | |
679 | else if ((m_cassette->get_state() & 0x03) == CASSETTE_RECORD) | |
680 | cassette_save(); | |
683 | 681 | } |
684 | 682 | |
685 | 683 | void x07_state::cassette_load() |
r18113 | r18114 | |
1367 | 1365 | state->m_blink = !state->m_blink; |
1368 | 1366 | } |
1369 | 1367 | |
1370 | ||
1368 | TIMER_CALLBACK_MEMBER(x07_state::rsta_clear) | |
1371 | 1369 | { |
1372 | x07_state *state = machine.driver_data<x07_state>(); | |
1373 | state->m_maincpu->set_input_line(NSC800_RSTA, CLEAR_LINE); | |
1370 | m_maincpu->set_input_line(NSC800_RSTA, CLEAR_LINE); | |
1374 | 1371 | |
1375 | if (state->m_kb_size) | |
1376 | state->kb_irq(); | |
1372 | if (m_kb_size) | |
1373 | kb_irq(); | |
1377 | 1374 | } |
1378 | 1375 | |
1379 | ||
1376 | TIMER_CALLBACK_MEMBER(x07_state::rstb_clear) | |
1380 | 1377 | { |
1381 | x07_state *state = machine.driver_data<x07_state>(); | |
1382 | state->m_maincpu->set_input_line(NSC800_RSTB, CLEAR_LINE); | |
1378 | m_maincpu->set_input_line(NSC800_RSTB, CLEAR_LINE); | |
1383 | 1379 | } |
1384 | 1380 | |
1385 | ||
1381 | TIMER_CALLBACK_MEMBER(x07_state::beep_stop) | |
1386 | 1382 | { |
1387 | x07_state *state = machine.driver_data<x07_state>(); | |
1388 | 1383 | |
1389 | beep_set_state( | |
1384 | beep_set_state(m_beep, 0); | |
1390 | 1385 | } |
1391 | 1386 | |
1392 | 1387 | static const gfx_layout x07_charlayout = |
r18113 | r18114 | |
1406 | 1401 | |
1407 | 1402 | void x07_state::machine_start() |
1408 | 1403 | { |
1409 | m_rsta_clear = machine().scheduler().timer_alloc(FUNC(rsta_clear)); | |
1410 | m_rstb_clear = machine().scheduler().timer_alloc(FUNC(rstb_clear)); | |
1411 | m_beep_stop = machine().scheduler().timer_alloc(FUNC(beep_stop)); | |
1412 | m_cass_poll = machine().scheduler().timer_alloc(FUNC(cassette_poll)); | |
1413 | m_cass_tick = machine().scheduler().timer_alloc(FUNC(cassette_tick)); | |
1404 | m_rsta_clear = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x07_state::rsta_clear),this)); | |
1405 | m_rstb_clear = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x07_state::rstb_clear),this)); | |
1406 | m_beep_stop = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x07_state::beep_stop),this)); | |
1407 | m_cass_poll = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x07_state::cassette_poll),this)); | |
1408 | m_cass_tick = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x07_state::cassette_tick),this)); | |
1414 | 1409 | |
1415 | 1410 | /* Save State */ |
1416 | 1411 | save_item(NAME(m_sleep)); |
r18113 | r18114 | |
---|---|---|
234 | 234 | return ret; |
235 | 235 | } |
236 | 236 | |
237 | ||
237 | TIMER_CALLBACK_MEMBER(fm7_state::fm7_beeper_off) | |
238 | 238 | { |
239 | beep_set_state(machine.device(BEEPER_TAG),0); | |
239 | beep_set_state(machine().device(BEEPER_TAG),0); | |
240 | 240 | logerror("timed beeper off\n"); |
241 | 241 | } |
242 | 242 | |
r18113 | r18114 | |
264 | 264 | { |
265 | 265 | beep_set_state(machine().device(BEEPER_TAG),1); |
266 | 266 | logerror("timed beeper on\n"); |
267 | machine().scheduler().timer_set(attotime::from_msec(205), FUNC(fm7_beeper_off)); | |
267 | machine().scheduler().timer_set(attotime::from_msec(205), timer_expired_delegate(FUNC(fm7_state::fm7_beeper_off),this)); | |
268 | 268 | } |
269 | 269 | } |
270 | 270 | logerror("beeper state: %02x\n",data); |
r18113 | r18114 | |
281 | 281 | { |
282 | 282 | beep_set_state(machine().device(BEEPER_TAG),1); |
283 | 283 | logerror("timed beeper on\n"); |
284 | machine().scheduler().timer_set(attotime::from_msec(205), FUNC(fm7_beeper_off)); | |
284 | machine().scheduler().timer_set(attotime::from_msec(205), timer_expired_delegate(FUNC(fm7_state::fm7_beeper_off),this)); | |
285 | 285 | } |
286 | 286 | return 0xff; |
287 | 287 | } |
r18113 | r18114 | |
628 | 628 | } |
629 | 629 | } |
630 | 630 | |
631 | ||
631 | TIMER_CALLBACK_MEMBER(fm7_state::fm77av_encoder_ack) | |
632 | 632 | { |
633 | fm7_state *state = machine.driver_data<fm7_state>(); | |
634 | state->m_encoder.ack = 1; | |
633 | m_encoder.ack = 1; | |
635 | 634 | } |
636 | 635 | |
637 | 636 | void fm7_state::fm77av_encoder_handle_command() |
r18113 | r18114 | |
716 | 715 | fm77av_encoder_handle_command(); |
717 | 716 | |
718 | 717 | // wait 5us to set ACK flag |
719 | machine().scheduler().timer_set(attotime::from_usec(5), FUNC(fm77av_encoder_ack)); | |
718 | machine().scheduler().timer_set(attotime::from_usec(5), timer_expired_delegate(FUNC(fm7_state::fm77av_encoder_ack),this)); | |
720 | 719 | |
721 | 720 | //logerror("ENC: write 0x%02x to data register, moved to pos %i\n",data,m_encoder.position); |
722 | 721 | } |
r18113 | r18114 | |
1204 | 1203 | } |
1205 | 1204 | } |
1206 | 1205 | |
1207 | ||
1206 | TIMER_CALLBACK_MEMBER(fm7_state::fm7_timer_irq) | |
1208 | 1207 | { |
1209 | fm7_state *state = machine.driver_data<fm7_state>(); | |
1210 | if(state->m_irq_mask & IRQ_FLAG_TIMER) | |
1208 | if(m_irq_mask & IRQ_FLAG_TIMER) | |
1211 | 1209 | { |
1212 | main_irq_set_flag(machine,IRQ_FLAG_TIMER); | |
1210 | main_irq_set_flag(machine(),IRQ_FLAG_TIMER); | |
1213 | 1211 | } |
1214 | 1212 | } |
1215 | 1213 | |
1216 | ||
1214 | TIMER_CALLBACK_MEMBER(fm7_state::fm7_subtimer_irq) | |
1217 | 1215 | { |
1218 | fm7_state *state = machine.driver_data<fm7_state>(); | |
1219 | if(state->m_video.nmi_mask == 0 && state->m_video.sub_halt == 0) | |
1220 | machine.device("sub")->execute().set_input_line(INPUT_LINE_NMI,PULSE_LINE); | |
1216 | if(m_video.nmi_mask == 0 && m_video.sub_halt == 0) | |
1217 | machine().device("sub")->execute().set_input_line(INPUT_LINE_NMI,PULSE_LINE); | |
1221 | 1218 | } |
1222 | 1219 | |
1223 | 1220 | // When a key is pressed or released (in scan mode only), an IRQ is generated on the main CPU, |
r18113 | r18114 | |
1288 | 1285 | state->m_mod_data = modifiers; |
1289 | 1286 | } |
1290 | 1287 | |
1291 | ||
1288 | TIMER_CALLBACK_MEMBER(fm7_state::fm7_keyboard_poll) | |
1292 | 1289 | { |
1293 | fm7_state *state = machine.driver_data<fm7_state>(); | |
1294 | 1290 | static const char *const portnames[3] = { "key1","key2","key3" }; |
1295 | 1291 | int x,y; |
1296 | 1292 | int bit = 0; |
1297 | 1293 | int mod = 0; |
1298 | 1294 | UINT32 keys; |
1299 | UINT32 modifiers = machine.root_device().ioport("key_modifiers")->read(); | |
1295 | UINT32 modifiers = machine().root_device().ioport("key_modifiers")->read(); | |
1300 | 1296 | |
1301 | if(machine.root_device().ioport("key3")->read() & 0x40000) | |
1297 | if(machine().root_device().ioport("key3")->read() & 0x40000) | |
1302 | 1298 | { |
1303 | state->m_break_flag = 1; | |
1304 | machine.device("maincpu")->execute().set_input_line(M6809_FIRQ_LINE,ASSERT_LINE); | |
1299 | m_break_flag = 1; | |
1300 | machine().device("maincpu")->execute().set_input_line(M6809_FIRQ_LINE,ASSERT_LINE); | |
1305 | 1301 | } |
1306 | 1302 | else |
1307 | | |
1303 | m_break_flag = 0; | |
1308 | 1304 | |
1309 | if( | |
1305 | if(m_key_scan_mode == KEY_MODE_SCAN) | |
1310 | 1306 | { |
1311 | 1307 | // handle scancode mode |
1312 | fm7_keyboard_poll_scan(machine); | |
1308 | fm7_keyboard_poll_scan(machine()); | |
1313 | 1309 | return; |
1314 | 1310 | } |
1315 | 1311 | |
r18113 | r18114 | |
1327 | 1323 | |
1328 | 1324 | for(x=0;x<3;x++) |
1329 | 1325 | { |
1330 | keys = machine.root_device().ioport(portnames[x])->read(); | |
1326 | keys = machine().root_device().ioport(portnames[x])->read(); | |
1331 | 1327 | |
1332 | 1328 | for(y=0;y<32;y++) // loop through each bit in the port |
1333 | 1329 | { |
1334 | if((keys & (1<<y)) != 0 && ( | |
1330 | if((keys & (1<<y)) != 0 && (m_key_data[x] & (1<<y)) == 0) | |
1335 | 1331 | { |
1336 | key_press(machine,fm7_key_list[bit][mod]); // key press | |
1332 | key_press(machine(),fm7_key_list[bit][mod]); // key press | |
1337 | 1333 | } |
1338 | 1334 | bit++; |
1339 | 1335 | } |
1340 | 1336 | |
1341 | | |
1337 | m_key_data[x] = keys; | |
1342 | 1338 | } |
1343 | 1339 | } |
1344 | 1340 | |
r18113 | r18114 | |
1834 | 1830 | { |
1835 | 1831 | // m_shared_ram = auto_alloc_array(machine(),UINT8,0x80); |
1836 | 1832 | m_video_ram = auto_alloc_array(machine(),UINT8,0x18000); // 2 pages on some systems |
1837 | m_timer = machine().scheduler().timer_alloc(FUNC(fm7_timer_irq)); | |
1838 | m_subtimer = machine().scheduler().timer_alloc(FUNC(fm7_subtimer_irq)); | |
1839 | m_keyboard_timer = machine().scheduler().timer_alloc(FUNC(fm7_keyboard_poll)); | |
1840 | m_fm77av_vsync_timer = machine().scheduler().timer_alloc(FUNC(fm77av_vsync)); | |
1833 | m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(fm7_state::fm7_timer_irq),this)); | |
1834 | m_subtimer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(fm7_state::fm7_subtimer_irq),this)); | |
1835 | m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(fm7_state::fm7_keyboard_poll),this)); | |
1836 | m_fm77av_vsync_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(fm7_state::fm77av_vsync),this)); | |
1841 | 1837 | machine().device("maincpu")->execute().set_irq_acknowledge_callback(fm7_irq_ack); |
1842 | 1838 | machine().device("sub")->execute().set_irq_acknowledge_callback(fm7_sub_irq_ack); |
1843 | 1839 | } |
r18113 | r18114 | |
---|---|---|
257 | 257 | } |
258 | 258 | } |
259 | 259 | |
260 | ||
260 | TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_lcd_timer_exp) | |
261 | 261 | { |
262 | gp32_state *state = machine.driver_data<gp32_state>(); | |
263 | screen_device *screen = machine.primary_screen; | |
264 | verboselog( machine, 2, "LCD timer callback\n"); | |
265 | state->m_s3c240x_lcd.vpos = screen->vpos(); | |
266 | state->m_s3c240x_lcd.hpos = screen->hpos(); | |
267 | verboselog( machine, 3, "LCD - vpos %d hpos %d\n", state->m_s3c240x_lcd.vpos, state->m_s3c240x_lcd.hpos); | |
268 | if (state->m_s3c240x_lcd.vramaddr_cur >= state->m_s3c240x_lcd.vramaddr_max) | |
262 | screen_device *screen = machine().primary_screen; | |
263 | verboselog( machine(), 2, "LCD timer callback\n"); | |
264 | m_s3c240x_lcd.vpos = screen->vpos(); | |
265 | m_s3c240x_lcd.hpos = screen->hpos(); | |
266 | verboselog( machine(), 3, "LCD - vpos %d hpos %d\n", m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos); | |
267 | if (m_s3c240x_lcd.vramaddr_cur >= m_s3c240x_lcd.vramaddr_max) | |
269 | 268 | { |
270 | s3c240x_lcd_dma_reload( machine); | |
269 | s3c240x_lcd_dma_reload( machine()); | |
271 | 270 | } |
272 | verboselog( machine, 3, "LCD - vramaddr %08X\n", state->m_s3c240x_lcd.vramaddr_cur); | |
273 | while (state->m_s3c240x_lcd.vramaddr_cur < state->m_s3c240x_lcd.vramaddr_max) | |
271 | verboselog( machine(), 3, "LCD - vramaddr %08X\n", m_s3c240x_lcd.vramaddr_cur); | |
272 | while (m_s3c240x_lcd.vramaddr_cur < m_s3c240x_lcd.vramaddr_max) | |
274 | 273 | { |
275 | switch ( | |
274 | switch (m_s3c240x_lcd.bppmode) | |
276 | 275 | { |
277 | case BPPMODE_TFT_01 : s3c240x_lcd_render_01( machine); break; | |
278 | case BPPMODE_TFT_02 : s3c240x_lcd_render_02( machine); break; | |
279 | case BPPMODE_TFT_04 : s3c240x_lcd_render_04( machine); break; | |
280 | case BPPMODE_TFT_08 : s3c240x_lcd_render_08( machine); break; | |
281 | case BPPMODE_TFT_16 : s3c240x_lcd_render_16( machine); break; | |
282 | default : verboselog( machine, 0, "s3c240x_lcd_timer_exp: bppmode %d not supported\n", state->m_s3c240x_lcd.bppmode); break; | |
276 | case BPPMODE_TFT_01 : s3c240x_lcd_render_01( machine()); break; | |
277 | case BPPMODE_TFT_02 : s3c240x_lcd_render_02( machine()); break; | |
278 | case BPPMODE_TFT_04 : s3c240x_lcd_render_04( machine()); break; | |
279 | case BPPMODE_TFT_08 : s3c240x_lcd_render_08( machine()); break; | |
280 | case BPPMODE_TFT_16 : s3c240x_lcd_render_16( machine()); break; | |
281 | default : verboselog( machine(), 0, "s3c240x_lcd_timer_exp: bppmode %d not supported\n", m_s3c240x_lcd.bppmode); break; | |
283 | 282 | } |
284 | if (( | |
283 | if ((m_s3c240x_lcd.vpos == 0) && (m_s3c240x_lcd.hpos == 0)) break; | |
285 | 284 | } |
286 | | |
285 | m_s3c240x_lcd_timer->adjust( screen->time_until_pos(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos)); | |
287 | 286 | } |
288 | 287 | |
289 | 288 | void gp32_state::video_start() |
r18113 | r18114 | |
673 | 672 | } |
674 | 673 | } |
675 | 674 | |
676 | ||
675 | TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_pwm_timer_exp) | |
677 | 676 | { |
678 | gp32_state *state = machine.driver_data<gp32_state>(); | |
679 | 677 | int ch = param; |
680 | 678 | static const int ch_int[] = { INT_TIMER0, INT_TIMER1, INT_TIMER2, INT_TIMER3, INT_TIMER4 }; |
681 | verboselog( machine, 2, "PWM %d timer callback\n", ch); | |
682 | if (BITS( state->m_s3c240x_pwm_regs[1], 23, 20) == (ch + 1)) | |
679 | verboselog( machine(), 2, "PWM %d timer callback\n", ch); | |
680 | if (BITS( m_s3c240x_pwm_regs[1], 23, 20) == (ch + 1)) | |
683 | 681 | { |
684 | s3c240x_dma_request_pwm( machine); | |
682 | s3c240x_dma_request_pwm( machine()); | |
685 | 683 | } |
686 | 684 | else |
687 | 685 | { |
688 | s3c240x_request_irq( machine, ch_int[ch]); | |
686 | s3c240x_request_irq( machine(), ch_int[ch]); | |
689 | 687 | } |
690 | 688 | } |
691 | 689 | |
r18113 | r18114 | |
911 | 909 | } |
912 | 910 | } |
913 | 911 | |
914 | ||
912 | TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_dma_timer_exp) | |
915 | 913 | { |
916 | 914 | int ch = param; |
917 | verboselog( machine, 2, "DMA %d timer callback\n", ch); | |
915 | verboselog( machine(), 2, "DMA %d timer callback\n", ch); | |
918 | 916 | } |
919 | 917 | |
920 | 918 | // SMARTMEDIA |
r18113 | r18114 | |
1439 | 1437 | } |
1440 | 1438 | } |
1441 | 1439 | |
1442 | ||
1440 | TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_iic_timer_exp) | |
1443 | 1441 | { |
1444 | gp32_state *state = machine.driver_data<gp32_state>(); | |
1445 | 1442 | int enable_interrupt, mode_selection; |
1446 | verboselog( machine, 2, "IIC timer callback\n"); | |
1447 | mode_selection = BITS( state->m_s3c240x_iic_regs[1], 7, 6); | |
1443 | verboselog( machine(), 2, "IIC timer callback\n"); | |
1444 | mode_selection = BITS( m_s3c240x_iic_regs[1], 7, 6); | |
1448 | 1445 | switch (mode_selection) |
1449 | 1446 | { |
1450 | 1447 | // master receive mode |
1451 | 1448 | case 2 : |
1452 | 1449 | { |
1453 | if ( | |
1450 | if (m_s3c240x_iic.data_index == 0) | |
1454 | 1451 | { |
1455 | UINT8 data_shift = state->m_s3c240x_iic_regs[3] & 0xFF; | |
1456 | verboselog( machine, 5, "IIC write %02X\n", data_shift); | |
1452 | UINT8 data_shift = m_s3c240x_iic_regs[3] & 0xFF; | |
1453 | verboselog( machine(), 5, "IIC write %02X\n", data_shift); | |
1457 | 1454 | } |
1458 | 1455 | else |
1459 | 1456 | { |
1460 | UINT8 data_shift = eeprom_read( machine, state->m_s3c240x_iic.address); | |
1461 | verboselog( machine, 5, "IIC read %02X\n", data_shift); | |
1462 | state->m_s3c240x_iic_regs[3] = (state->m_s3c240x_iic_regs[3] & ~0xFF) | data_shift; | |
1457 | UINT8 data_shift = eeprom_read( machine(), m_s3c240x_iic.address); | |
1458 | verboselog( machine(), 5, "IIC read %02X\n", data_shift); | |
1459 | m_s3c240x_iic_regs[3] = (m_s3c240x_iic_regs[3] & ~0xFF) | data_shift; | |
1463 | 1460 | } |
1464 | | |
1461 | m_s3c240x_iic.data_index++; | |
1465 | 1462 | } |
1466 | 1463 | break; |
1467 | 1464 | // master transmit mode |
1468 | 1465 | case 3 : |
1469 | 1466 | { |
1470 | UINT8 data_shift = state->m_s3c240x_iic_regs[3] & 0xFF; | |
1471 | verboselog( machine, 5, "IIC write %02X\n", data_shift); | |
1472 | state->m_s3c240x_iic.data[state->m_s3c240x_iic.data_index++] = data_shift; | |
1473 | if (state->m_s3c240x_iic.data_index == 3) | |
1467 | UINT8 data_shift = m_s3c240x_iic_regs[3] & 0xFF; | |
1468 | verboselog( machine(), 5, "IIC write %02X\n", data_shift); | |
1469 | m_s3c240x_iic.data[m_s3c240x_iic.data_index++] = data_shift; | |
1470 | if (m_s3c240x_iic.data_index == 3) | |
1474 | 1471 | { |
1475 | | |
1472 | m_s3c240x_iic.address = (m_s3c240x_iic.data[1] << 8) | m_s3c240x_iic.data[2]; | |
1476 | 1473 | } |
1477 | if (( | |
1474 | if ((m_s3c240x_iic.data_index == 4) && (m_s3c240x_iic.data[0] == 0xA0)) | |
1478 | 1475 | { |
1479 | eeprom_write( machine, | |
1476 | eeprom_write( machine(), m_s3c240x_iic.address, data_shift); | |
1480 | 1477 | } |
1481 | 1478 | } |
1482 | 1479 | break; |
1483 | 1480 | } |
1484 | enable_interrupt = BIT( | |
1481 | enable_interrupt = BIT( m_s3c240x_iic_regs[0], 5); | |
1485 | 1482 | if (enable_interrupt) |
1486 | 1483 | { |
1487 | s3c240x_request_irq( machine, INT_IIC); | |
1484 | s3c240x_request_irq( machine(), INT_IIC); | |
1488 | 1485 | } |
1489 | 1486 | } |
1490 | 1487 | |
r18113 | r18114 | |
1582 | 1579 | } |
1583 | 1580 | } |
1584 | 1581 | |
1585 | ||
1582 | TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_iis_timer_exp) | |
1586 | 1583 | { |
1587 | verboselog( machine, 2, "IIS timer callback\n"); | |
1588 | s3c240x_dma_request_iis( machine); | |
1584 | verboselog( machine(), 2, "IIS timer callback\n"); | |
1585 | s3c240x_dma_request_iis( machine()); | |
1589 | 1586 | } |
1590 | 1587 | |
1591 | 1588 | // RTC |
r18113 | r18114 | |
1657 | 1654 | static void s3c240x_machine_start( running_machine &machine) |
1658 | 1655 | { |
1659 | 1656 | gp32_state *state = machine.driver_data<gp32_state>(); |
1660 | state->m_s3c240x_pwm_timer[0] = machine.scheduler().timer_alloc(FUNC(s3c240x_pwm_timer_exp), (void *)(FPTR)0); | |
1661 | state->m_s3c240x_pwm_timer[1] = machine.scheduler().timer_alloc(FUNC(s3c240x_pwm_timer_exp), (void *)(FPTR)1); | |
1662 | state->m_s3c240x_pwm_timer[2] = machine.scheduler().timer_alloc(FUNC(s3c240x_pwm_timer_exp), (void *)(FPTR)2); | |
1663 | state->m_s3c240x_pwm_timer[3] = machine.scheduler().timer_alloc(FUNC(s3c240x_pwm_timer_exp), (void *)(FPTR)3); | |
1664 | state->m_s3c240x_pwm_timer[4] = machine.scheduler().timer_alloc(FUNC(s3c240x_pwm_timer_exp), (void *)(FPTR)4); | |
1665 | state->m_s3c240x_dma_timer[0] = machine.scheduler().timer_alloc(FUNC(s3c240x_dma_timer_exp), (void *)(FPTR)0); | |
1666 | state->m_s3c240x_dma_timer[1] = machine.scheduler().timer_alloc(FUNC(s3c240x_dma_timer_exp), (void *)(FPTR)1); | |
1667 | state->m_s3c240x_dma_timer[2] = machine.scheduler().timer_alloc(FUNC(s3c240x_dma_timer_exp), (void *)(FPTR)2); | |
1668 | state->m_s3c240x_dma_timer[3] = machine.scheduler().timer_alloc(FUNC(s3c240x_dma_timer_exp), (void *)(FPTR)3); | |
1669 | state->m_s3c240x_iic_timer = machine.scheduler().timer_alloc(FUNC(s3c240x_iic_timer_exp), (void *)(FPTR)0); | |
1670 | state->m_s3c240x_iis_timer = machine.scheduler().timer_alloc(FUNC(s3c240x_iis_timer_exp), (void *)(FPTR)0); | |
1671 | state->m_s3c240x_lcd_timer = machine.scheduler().timer_alloc(FUNC(s3c240x_lcd_timer_exp), (void *)(FPTR)0); | |
1657 | state->m_s3c240x_pwm_timer[0] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),state), (void *)(FPTR)0); | |
1658 | state->m_s3c240x_pwm_timer[1] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),state), (void *)(FPTR)1); | |
1659 | state->m_s3c240x_pwm_timer[2] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),state), (void *)(FPTR)2); | |
1660 | state->m_s3c240x_pwm_timer[3] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),state), (void *)(FPTR)3); | |
1661 | state->m_s3c240x_pwm_timer[4] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),state), (void *)(FPTR)4); | |
1662 | state->m_s3c240x_dma_timer[0] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),state), (void *)(FPTR)0); | |
1663 | state->m_s3c240x_dma_timer[1] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),state), (void *)(FPTR)1); | |
1664 | state->m_s3c240x_dma_timer[2] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),state), (void *)(FPTR)2); | |
1665 | state->m_s3c240x_dma_timer[3] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),state), (void *)(FPTR)3); | |
1666 | state->m_s3c240x_iic_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_iic_timer_exp),state), (void *)(FPTR)0); | |
1667 | state->m_s3c240x_iis_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_iis_timer_exp),state), (void *)(FPTR)0); | |
1668 | state->m_s3c240x_lcd_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_lcd_timer_exp),state), (void *)(FPTR)0); | |
1672 | 1669 | state->m_eeprom_data = auto_alloc_array( machine, UINT8, 0x2000); |
1673 | 1670 | machine.device<nvram_device>("nvram")->set_base(state->m_eeprom_data, 0x2000); |
1674 | 1671 | smc_init( machine); |
r18113 | r18114 | |
---|---|---|
796 | 796 | /* This is needed because MAME core does not allow PULSE_LINE. |
797 | 797 | The time interval is not critical, although it should be below 1000. */ |
798 | 798 | |
799 | ||
799 | TIMER_CALLBACK_MEMBER(intv_state::intv_interrupt2_complete) | |
800 | 800 | { |
801 | machine.device("keyboard")->execute().set_input_line(0, CLEAR_LINE); | |
801 | machine().device("keyboard")->execute().set_input_line(0, CLEAR_LINE); | |
802 | 802 | } |
803 | 803 | |
804 | 804 | INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt2) |
805 | 805 | { |
806 | 806 | machine().device("keyboard")->execute().set_input_line(0, ASSERT_LINE); |
807 | machine().scheduler().timer_set(machine().device<cpu_device>("keyboard")->cycles_to_attotime(100), FUNC(intv_interrupt2_complete)); | |
807 | machine().scheduler().timer_set(machine().device<cpu_device>("keyboard")->cycles_to_attotime(100), timer_expired_delegate(FUNC(intv_state::intv_interrupt2_complete),this)); | |
808 | 808 | } |
809 | 809 | |
810 | 810 | static MACHINE_CONFIG_START( intv, intv_state ) |
r18113 | r18114 | |
---|---|---|
301 | 301 | COMBINE_DATA(&m_extdesc_regs[offset]); |
302 | 302 | } |
303 | 303 | |
304 | ||
304 | TIMER_CALLBACK_MEMBER(cxhumax_state::timer_tick) | |
305 | 305 | { |
306 | cxhumax_state *state = machine.driver_data<cxhumax_state>(); | |
307 | state->m_timer_regs.timer[param].value++; | |
308 | if(state->m_timer_regs.timer[param].value==state->m_timer_regs.timer[param].limit) { | |
306 | m_timer_regs.timer[param].value++; | |
307 | if(m_timer_regs.timer[param].value==m_timer_regs.timer[param].limit) { | |
309 | 308 | /* Reset counter when reaching limit and RESET_CNTR bit is cleared */ |
310 | if(!(state->m_timer_regs.timer[param].mode & 2)) | |
311 | state->m_timer_regs.timer[param].value=0; | |
309 | if(!(m_timer_regs.timer[param].mode & 2)) | |
310 | m_timer_regs.timer[param].value=0; | |
312 | 311 | |
313 | 312 | /* Indicate interrupt request if EN_INT bit is set */ |
314 | if ( | |
313 | if (m_timer_regs.timer[param].mode & 8) { | |
315 | 314 | //printf( "IRQ on Timer %d\n", param ); |
316 | verboselog( machine, 9, "(TIMER%d) Interrupt\n", param); | |
317 | state->m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
318 | state->m_intctrl_regs[INTREG(INTGROUP2, INTSTATCLR)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
319 | state->m_intctrl_regs[INTREG(INTGROUP2, INTSTATSET)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
315 | verboselog( machine(), 9, "(TIMER%d) Interrupt\n", param); | |
316 | m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
317 | m_intctrl_regs[INTREG(INTGROUP2, INTSTATCLR)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
318 | m_intctrl_regs[INTREG(INTGROUP2, INTSTATSET)] |= INT_TIMER_BIT; /* Timer interrupt */ | |
320 | 319 | |
321 | | |
320 | m_timer_regs.timer_irq |= 1<<param; /* Indicate which timer interrupted */ | |
322 | 321 | |
323 | 322 | /* Interrupt if Timer interrupt is not masked in ITC_INTENABLE_REG */ |
324 | if (state->m_intctrl_regs[INTREG(INTGROUP2, INTENABLE)] & INT_TIMER_BIT) | |
325 | machine.device("maincpu")->execute().set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); | |
323 | if (m_intctrl_regs[INTREG(INTGROUP2, INTENABLE)] & INT_TIMER_BIT) | |
324 | machine().device("maincpu")->execute().set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); | |
326 | 325 | } |
327 | 326 | } |
328 | attotime period = attotime::from_hz(XTAL_54MHz)*state->m_timer_regs.timer[param].timebase; | |
329 | state->m_timer_regs.timer[param].timer->adjust(period,param); | |
327 | attotime period = attotime::from_hz(XTAL_54MHz)*m_timer_regs.timer[param].timebase; | |
328 | m_timer_regs.timer[param].timer->adjust(period,param); | |
330 | 329 | } |
331 | 330 | |
332 | 331 | READ32_MEMBER( cxhumax_state::cx_timers_r ) |
r18113 | r18114 | |
983 | 982 | int index = 0; |
984 | 983 | for(index = 0; index < MAX_CX_TIMERS; index++) |
985 | 984 | { |
986 | m_timer_regs.timer[index].timer = machine().scheduler().timer_alloc(FUNC(timer_tick)); | |
985 | m_timer_regs.timer[index].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cxhumax_state::timer_tick),this)); | |
987 | 986 | m_timer_regs.timer[index].timer->adjust(attotime::never, index); |
988 | 987 | } |
989 | 988 | } |
r18113 | r18114 | |
---|---|---|
386 | 386 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RIGHT CTRL") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL)) |
387 | 387 | INPUT_PORTS_END |
388 | 388 | |
389 | ||
389 | TIMER_CALLBACK_MEMBER(xerox820_state::bigboard_beepoff) | |
390 | 390 | { |
391 | xerox820_state *state = machine.driver_data<xerox820_state>(); | |
392 | beep_set_state(state->m_beeper, 0); | |
391 | beep_set_state(m_beeper, 0); | |
393 | 392 | } |
394 | 393 | |
395 | 394 | /* Z80 PIO */ |
r18113 | r18114 | |
461 | 460 | /* beeper on bigboard */ |
462 | 461 | if (BIT(data, 5) & (!m_bit5)) |
463 | 462 | { |
464 | machine().scheduler().timer_set(attotime::from_msec(40), FUNC(bigboard_beepoff)); | |
463 | machine().scheduler().timer_set(attotime::from_msec(40), timer_expired_delegate(FUNC(xerox820_state::bigboard_beepoff),this)); | |
465 | 464 | beep_set_state(m_beeper, 1 ); |
466 | 465 | } |
467 | 466 | m_bit5 = BIT(data, 5); |
r18113 | r18114 | |
---|---|---|
383 | 383 | |
384 | 384 | |
385 | 385 | static int tape_read(pdp1_state *state, UINT8 *reply); |
386 | static TIMER_CALLBACK(reader_callback); | |
387 | static TIMER_CALLBACK(puncher_callback); | |
388 | static TIMER_CALLBACK(tyo_callback); | |
389 | static TIMER_CALLBACK(dpy_callback); | |
386 | ||
387 | ||
388 | ||
389 | ||
390 | 390 | static void pdp1_machine_stop(running_machine &machine); |
391 | 391 | |
392 | 392 | static void pdp1_tape_read_binary(device_t *device); |
r18113 | r18114 | |
658 | 658 | |
659 | 659 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(pdp1_machine_stop),&machine())); |
660 | 660 | |
661 | m_tape_reader.timer = machine().scheduler().timer_alloc(FUNC(reader_callback)); | |
662 | m_tape_puncher.timer = machine().scheduler().timer_alloc(FUNC(puncher_callback)); | |
663 | m_typewriter.tyo_timer = machine().scheduler().timer_alloc(FUNC(tyo_callback)); | |
664 | m_dpy_timer = machine().scheduler().timer_alloc(FUNC(dpy_callback)); | |
661 | m_tape_reader.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pdp1_state::reader_callback),this)); | |
662 | m_tape_puncher.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pdp1_state::puncher_callback),this)); | |
663 | m_typewriter.tyo_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pdp1_state::tyo_callback),this)); | |
664 | m_dpy_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pdp1_state::dpy_callback),this)); | |
665 | 665 | m_tape_reader.timer->adjust(attotime::zero, 0, attotime::from_hz(2500)); |
666 | 666 | m_tape_reader.timer->enable(0); |
667 | 667 | } |
r18113 | r18114 | |
902 | 902 | /* |
903 | 903 | timer callback to simulate reader IO |
904 | 904 | */ |
905 | ||
905 | TIMER_CALLBACK_MEMBER(pdp1_state::reader_callback) | |
906 | 906 | { |
907 | pdp1_state *state = machine.driver_data<pdp1_state>(); | |
908 | 907 | int not_ready; |
909 | 908 | UINT8 data; |
910 | 909 | |
911 | if ( | |
910 | if (m_tape_reader.rc) | |
912 | 911 | { |
913 | not_ready = tape_read( | |
912 | not_ready = tape_read(this, & data); | |
914 | 913 | if (not_ready) |
915 | 914 | { |
916 | | |
915 | m_tape_reader.motor_on = 0; /* let us stop the motor */ | |
917 | 916 | } |
918 | 917 | else |
919 | 918 | { |
920 | if ((! | |
919 | if ((! m_tape_reader.rby) || (data & 0200)) | |
921 | 920 | { |
922 | | |
921 | m_tape_reader.rb |= (m_tape_reader.rby) ? (data & 077) : data; | |
923 | 922 | |
924 | if ( | |
923 | if (m_tape_reader.rc != 3) | |
925 | 924 | { |
926 | | |
925 | m_tape_reader.rb <<= 6; | |
927 | 926 | } |
928 | 927 | |
929 | | |
928 | m_tape_reader.rc = (m_tape_reader.rc+1) & 3; | |
930 | 929 | |
931 | if ( | |
930 | if (m_tape_reader.rc == 0) | |
932 | 931 | { /* IO complete */ |
933 | state->m_tape_reader.rcl = 0; | |
934 | if (state->m_tape_reader.rcp) | |
932 | m_tape_reader.rcl = 0; | |
933 | if (m_tape_reader.rcp) | |
935 | 934 | { |
936 | machine.device("maincpu")->state().set_state_int(PDP1_IO, state->m_tape_reader.rb); /* transfer reader buffer to IO */ | |
937 | pdp1_pulse_iot_done(machine.device("maincpu")); | |
935 | machine().device("maincpu")->state().set_state_int(PDP1_IO, m_tape_reader.rb); /* transfer reader buffer to IO */ | |
936 | pdp1_pulse_iot_done(machine().device("maincpu")); | |
938 | 937 | } |
939 | 938 | else |
940 | | |
939 | m_io_status |= io_st_ptr; | |
941 | 940 | } |
942 | 941 | } |
943 | 942 | } |
944 | 943 | } |
945 | 944 | |
946 | if ( | |
945 | if (m_tape_reader.motor_on && m_tape_reader.rcl) | |
947 | 946 | { |
948 | | |
947 | m_tape_reader.timer->enable(1); | |
949 | 948 | } |
950 | 949 | else |
951 | 950 | { |
952 | | |
951 | m_tape_reader.timer->enable(0); | |
953 | 952 | } |
954 | 953 | } |
955 | 954 | |
r18113 | r18114 | |
1080 | 1079 | /* |
1081 | 1080 | timer callback to generate punch completion pulse |
1082 | 1081 | */ |
1083 | ||
1082 | TIMER_CALLBACK_MEMBER(pdp1_state::puncher_callback) | |
1084 | 1083 | { |
1085 | pdp1_state *state = machine.driver_data<pdp1_state>(); | |
1086 | 1084 | int nac = param; |
1087 | | |
1085 | m_io_status |= io_st_ptp; | |
1088 | 1086 | if (nac) |
1089 | 1087 | { |
1090 | pdp1_pulse_iot_done(machine.device("maincpu")); | |
1088 | pdp1_pulse_iot_done(machine().device("maincpu")); | |
1091 | 1089 | } |
1092 | 1090 | } |
1093 | 1091 | |
r18113 | r18114 | |
1290 | 1288 | /* |
1291 | 1289 | timer callback to generate typewriter completion pulse |
1292 | 1290 | */ |
1293 | ||
1291 | TIMER_CALLBACK_MEMBER(pdp1_state::tyo_callback) | |
1294 | 1292 | { |
1295 | pdp1_state *state = machine.driver_data<pdp1_state>(); | |
1296 | 1293 | int nac = param; |
1297 | | |
1294 | m_io_status |= io_st_tyo; | |
1298 | 1295 | if (nac) |
1299 | 1296 | { |
1300 | pdp1_pulse_iot_done(machine.device("maincpu")); | |
1297 | pdp1_pulse_iot_done(machine().device("maincpu")); | |
1301 | 1298 | } |
1302 | 1299 | } |
1303 | 1300 | |
r18113 | r18114 | |
1413 | 1410 | /* |
1414 | 1411 | timer callback to generate crt completion pulse |
1415 | 1412 | */ |
1416 | ||
1413 | TIMER_CALLBACK_MEMBER(pdp1_state::dpy_callback) | |
1417 | 1414 | { |
1418 | pdp1_pulse_iot_done(machine.device("maincpu")); | |
1415 | pdp1_pulse_iot_done(machine().device("maincpu")); | |
1419 | 1416 | } |
1420 | 1417 | |
1421 | 1418 | |
r18113 | r18114 | |
1478 | 1475 | } |
1479 | 1476 | |
1480 | 1477 | #ifdef UNUSED_FUNCTION |
1481 | ||
1478 | TIMER_CALLBACK_MEMBER(pdp1_state::il_timer_callback) | |
1482 | 1479 | { |
1483 | pdp1_state *state = machine.driver_data<pdp1_state>(); | |
1484 | if (state->m_parallel_drum.dba) | |
1480 | if (m_parallel_drum.dba) | |
1485 | 1481 | { |
1486 | 1482 | /* set break request and status bit 5 */ |
1487 | 1483 | /* ... */ |
r18113 | r18114 | |
1493 | 1489 | state->m_parallel_drum.rotation_timer = machine.scheduler().timer_alloc(); |
1494 | 1490 | state->m_parallel_drum.rotation_timer->adjust(PARALLEL_DRUM_ROTATION_TIME, 0, PARALLEL_DRUM_ROTATION_TIME); |
1495 | 1491 | |
1496 | state->m_parallel_drum.il_timer = machine.scheduler().timer_alloc(FUNC(il_timer_callback)); | |
1492 | state->m_parallel_drum.il_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(pdp1_state::il_timer_callback),this)); | |
1497 | 1493 | parallel_drum_set_il(0); |
1498 | 1494 | } |
1499 | 1495 | #endif |
r18113 | r18114 | |
---|---|---|
296 | 296 | } |
297 | 297 | } |
298 | 298 | |
299 | ||
299 | TIMER_CALLBACK_MEMBER(nc_state::nc_keyboard_timer_callback) | |
300 | 300 | { |
301 | nc_state *state = machine.driver_data<nc_state>(); | |
302 | 301 | LOG(("keyboard int\n")); |
303 | 302 | |
304 | 303 | /* set int */ |
305 | | |
304 | m_irq_status |= (1<<3); | |
306 | 305 | |
307 | 306 | /* update ints */ |
308 | nc_update_interrupts(machine); | |
307 | nc_update_interrupts(machine()); | |
309 | 308 | |
310 | 309 | /* don't trigger again, but don't free it */ |
311 | | |
310 | m_keyboard_timer->reset(); | |
312 | 311 | } |
313 | 312 | |
314 | 313 | |
r18113 | r18114 | |
539 | 538 | state->m_previous_inputport_10_state = inputport_10_state; |
540 | 539 | } |
541 | 540 | |
542 | static TIMER_CALLBACK(nc_serial_timer_callback); | |
543 | 541 | |
542 | ||
544 | 543 | static void nc_common_init_machine(running_machine &machine) |
545 | 544 | { |
546 | 545 | nc_state *state = machine.driver_data<nc_state>(); |
r18113 | r18114 | |
767 | 766 | 19200 |
768 | 767 | }; |
769 | 768 | |
770 | ||
769 | TIMER_CALLBACK_MEMBER(nc_state::nc_serial_timer_callback) | |
771 | 770 | { |
772 | i8251_device *uart = machine.device<i8251_device>("uart"); | |
771 | i8251_device *uart = machine().device<i8251_device>("uart"); | |
773 | 772 | |
774 | 773 | uart->transmit_clock(); |
775 | 774 | uart->receive_clock(); |
r18113 | r18114 | |
952 | 951 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(nc100_machine_stop),&machine())); |
953 | 952 | |
954 | 953 | /* keyboard timer */ |
955 | m_keyboard_timer = machine().scheduler().timer_alloc(FUNC(nc_keyboard_timer_callback)); | |
954 | m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_keyboard_timer_callback),this)); | |
956 | 955 | m_keyboard_timer->adjust(attotime::from_msec(10)); |
957 | 956 | |
958 | 957 | /* serial timer */ |
959 | m_serial_timer = machine().scheduler().timer_alloc(FUNC(nc_serial_timer_callback)); | |
958 | m_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_serial_timer_callback),this)); | |
960 | 959 | } |
961 | 960 | |
962 | 961 | |
r18113 | r18114 | |
1342 | 1341 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(nc200_machine_stop),&machine())); |
1343 | 1342 | |
1344 | 1343 | /* keyboard timer */ |
1345 | m_keyboard_timer = machine().scheduler().timer_alloc(FUNC(nc_keyboard_timer_callback)); | |
1344 | m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_keyboard_timer_callback),this)); | |
1346 | 1345 | m_keyboard_timer->adjust(attotime::from_msec(10)); |
1347 | 1346 | |
1348 | 1347 | /* serial timer */ |
1349 | m_serial_timer = machine().scheduler().timer_alloc(FUNC(nc_serial_timer_callback)); | |
1348 | m_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_serial_timer_callback),this)); | |
1350 | 1349 | } |
1351 | 1350 | |
1352 | 1351 | /* |
r18113 | r18114 | |
---|---|---|
24 | 24 | #define YPOS state->m_reg[3] |
25 | 25 | #define BANK m_reg[0x26] |
26 | 26 | |
27 | ||
27 | TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer) | |
28 | 28 | { |
29 | svision_state *state = machine.driver_data<svision_state>(); | |
30 | switch (state->m_pet.state) | |
29 | switch (m_pet.state) | |
31 | 30 | { |
32 | 31 | case 0: |
33 | | |
32 | m_pet.input = machine().root_device().ioport("JOY2")->read(); | |
34 | 33 | /* fall through */ |
35 | 34 | |
36 | 35 | case 2: case 4: case 6: case 8: |
37 | 36 | case 10: case 12: case 14: |
38 | state->m_pet.clock=state->m_pet.state&2; | |
39 | state->m_pet.data=state->m_pet.input&1; | |
40 | state->m_pet.input>>=1; | |
41 | state->m_pet.state++; | |
37 | m_pet.clock=m_pet.state&2; | |
38 | m_pet.data=m_pet.input&1; | |
39 | m_pet.input>>=1; | |
40 | m_pet.state++; | |
42 | 41 | break; |
43 | 42 | |
44 | 43 | case 16+15: |
45 | | |
44 | m_pet.state = 0; | |
46 | 45 | break; |
47 | 46 | |
48 | 47 | default: |
49 | | |
48 | m_pet.state++; | |
50 | 49 | break; |
51 | 50 | } |
52 | 51 | } |
53 | 52 | |
54 | 53 | static TIMER_DEVICE_CALLBACK(svision_pet_timer_dev) |
55 | 54 | { |
56 | svision_pet_timer(timer.machine(),ptr,param); | |
55 | svision_state *state = timer.machine().driver_data<svision_state>(); | |
56 | state->svision_pet_timer(ptr,param); | |
57 | 57 | } |
58 | 58 | |
59 | 59 | void svision_irq(running_machine &machine) |
r18113 | r18114 | |
65 | 65 | machine.device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE); |
66 | 66 | } |
67 | 67 | |
68 | ||
68 | TIMER_CALLBACK_MEMBER(svision_state::svision_timer) | |
69 | 69 | { |
70 | svision_state *state = machine.driver_data<svision_state>(); | |
71 | state->m_svision.timer_shot = TRUE; | |
72 | state->m_svision.timer1->enable(FALSE); | |
73 | svision_irq( machine ); | |
70 | m_svision.timer_shot = TRUE; | |
71 | m_svision.timer1->enable(FALSE); | |
72 | svision_irq( machine() ); | |
74 | 73 | } |
75 | 74 | |
76 | 75 | READ8_MEMBER(svision_state::svision_r) |
r18113 | r18114 | |
424 | 423 | |
425 | 424 | DRIVER_INIT_MEMBER(svision_state,svision) |
426 | 425 | { |
427 | m_svision.timer1 = machine().scheduler().timer_alloc(FUNC(svision_timer)); | |
426 | m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this)); | |
428 | 427 | m_sound = machine().device("custom"); |
429 | 428 | m_dma_finished = svision_dma_finished(m_sound); |
430 | 429 | m_pet.on = FALSE; |
r18113 | r18114 | |
433 | 432 | |
434 | 433 | DRIVER_INIT_MEMBER(svision_state,svisions) |
435 | 434 | { |
436 | m_svision.timer1 = machine().scheduler().timer_alloc(FUNC(svision_timer)); | |
435 | m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this)); | |
437 | 436 | m_sound = machine().device("custom"); |
438 | 437 | m_dma_finished = svision_dma_finished(m_sound); |
439 | 438 | membank("bank2")->set_base(memregion("user1")->base() + 0x1c000); |
440 | m_svision.timer1 = machine().scheduler().timer_alloc(FUNC(svision_timer)); | |
439 | m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this)); | |
441 | 440 | m_pet.on = TRUE; |
442 | m_pet.timer = machine().scheduler().timer_alloc(FUNC(svision_pet_timer)); | |
441 | m_pet.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_pet_timer),this)); | |
443 | 442 | } |
444 | 443 | |
445 | 444 | static DEVICE_IMAGE_LOAD( svision_cart ) |
r18113 | r18114 | |
---|---|---|
203 | 203 | |
204 | 204 | /* Intel 8255A Interface */ |
205 | 205 | |
206 | ||
206 | TIMER_CALLBACK_MEMBER(mpf1_state::led_refresh) | |
207 | 207 | { |
208 | mpf1_state *state = machine.driver_data<mpf1_state>(); | |
209 | 208 | |
210 | if (BIT(state->m_lednum, 5)) output_set_digit_value(0, param); | |
211 | if (BIT(state->m_lednum, 4)) output_set_digit_value(1, param); | |
212 | if (BIT(state->m_lednum, 3)) output_set_digit_value(2, param); | |
213 | if (BIT(state->m_lednum, 2)) output_set_digit_value(3, param); | |
214 | if (BIT(state->m_lednum, 1)) output_set_digit_value(4, param); | |
215 | if (BIT(state->m_lednum, 0)) output_set_digit_value(5, param); | |
209 | if (BIT(m_lednum, 5)) output_set_digit_value(0, param); | |
210 | if (BIT(m_lednum, 4)) output_set_digit_value(1, param); | |
211 | if (BIT(m_lednum, 3)) output_set_digit_value(2, param); | |
212 | if (BIT(m_lednum, 2)) output_set_digit_value(3, param); | |
213 | if (BIT(m_lednum, 1)) output_set_digit_value(4, param); | |
214 | if (BIT(m_lednum, 0)) output_set_digit_value(5, param); | |
216 | 215 | } |
217 | 216 | |
218 | 217 | READ8_MEMBER( mpf1_state::ppi_pa_r ) |
r18113 | r18114 | |
346 | 345 | |
347 | 346 | void mpf1_state::machine_start() |
348 | 347 | { |
349 | m_led_refresh_timer = machine().scheduler().timer_alloc(FUNC(led_refresh)); | |
348 | m_led_refresh_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mpf1_state::led_refresh),this)); | |
350 | 349 | |
351 | 350 | /* register for state saving */ |
352 | 351 | save_item(NAME(m_break)); |
r18113 | r18114 | |
---|---|---|
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
107 | ||
107 | TIMER_CALLBACK_MEMBER(gba_state::dma_complete) | |
108 | 108 | { |
109 | 109 | int ctrl; |
110 | 110 | FPTR ch; |
111 | 111 | static const UINT32 ch_int[4] = { INT_DMA0, INT_DMA1, INT_DMA2, INT_DMA3 }; |
112 | gba_state *state = machine.driver_data<gba_state>(); | |
113 | 112 | |
114 | 113 | ch = param; |
115 | 114 | |
116 | 115 | // printf("dma complete: ch %d\n", ch); |
117 | 116 | |
118 | | |
117 | m_dma_timer[ch]->adjust(attotime::never); | |
119 | 118 | |
120 | ctrl = | |
119 | ctrl = m_dma_regs[(ch*3)+2] >> 16; | |
121 | 120 | |
122 | 121 | // IRQ |
123 | 122 | if (ctrl & 0x4000) |
124 | 123 | { |
125 | gba_request_irq(machine, ch_int[ch]); | |
124 | gba_request_irq(machine(), ch_int[ch]); | |
126 | 125 | } |
127 | 126 | |
128 | 127 | // if we're supposed to repeat, don't clear "active" and then the next vbl/hbl will retrigger us |
r18113 | r18114 | |
130 | 129 | if (!((ctrl>>9) & 1) || ((ctrl & 0x3000) == 0)) |
131 | 130 | { |
132 | 131 | // printf("clear active for ch %d\n", ch); |
133 | | |
132 | m_dma_regs[(ch*3)+2] &= ~0x80000000; // clear "active" bit | |
134 | 133 | } |
135 | 134 | else |
136 | 135 | { |
137 | 136 | // if repeat, reload the count |
138 | 137 | if ((ctrl>>9) & 1) |
139 | 138 | { |
140 | | |
139 | m_dma_cnt[ch] = m_dma_regs[(ch*3)+2]&0xffff; | |
141 | 140 | |
142 | 141 | // if increment & reload mode, reload the destination |
143 | 142 | if (((ctrl>>5)&3) == 3) |
144 | 143 | { |
145 | | |
144 | m_dma_dst[ch] = m_dma_regs[(ch*3)+1]; | |
146 | 145 | } |
147 | 146 | } |
148 | 147 | } |
r18113 | r18114 | |
278 | 277 | |
279 | 278 | // printf("settng DMA timer %d for %d cycs (tmr %x)\n", ch, cnt, (UINT32)state->m_dma_timer[ch]); |
280 | 279 | // state->m_dma_timer[ch]->adjust(ATTOTIME_IN_CYCLES(0, cnt), ch); |
281 | dma_complete( | |
280 | state->dma_complete(NULL, ch); | |
282 | 281 | } |
283 | 282 | |
284 | 283 | static void audio_tick(running_machine &machine, int ref) |
r18113 | r18114 | |
371 | 370 | } |
372 | 371 | } |
373 | 372 | |
374 | ||
373 | TIMER_CALLBACK_MEMBER(gba_state::timer_expire) | |
375 | 374 | { |
376 | 375 | static const UINT32 tmr_ints[4] = { INT_TM0_OVERFLOW, INT_TM1_OVERFLOW, INT_TM2_OVERFLOW, INT_TM3_OVERFLOW }; |
377 | 376 | FPTR tmr = (FPTR) param; |
378 | gba_state *state = machine.driver_data<gba_state>(); | |
379 | 377 | |
380 | // printf("Timer %d expired, SOUNDCNT_H %04x\n", tmr, | |
378 | // printf("Timer %d expired, SOUNDCNT_H %04x\n", tmr, m_SOUNDCNT_H); | |
381 | 379 | |
382 | 380 | // "The reload value is copied into the counter only upon following two situations: Automatically upon timer overflows," |
383 | 381 | // "or when the timer start bit becomes changed from 0 to 1." |
384 | if ( | |
382 | if (m_timer_recalc[tmr] != 0) | |
385 | 383 | { |
386 | 384 | double rate, clocksel, final; |
387 | 385 | attotime time; |
388 | state->m_timer_recalc[tmr] = 0; | |
389 | state->m_timer_regs[tmr] = (state->m_timer_regs[tmr] & 0xFFFF0000) | (state->m_timer_reload[tmr] & 0x0000FFFF); | |
390 | rate = 0x10000 - (state->m_timer_regs[tmr] & 0xffff); | |
391 | clocksel = timer_clks[(state->m_timer_regs[tmr] >> 16) & 3]; | |
386 | m_timer_recalc[tmr] = 0; | |
387 | m_timer_regs[tmr] = (m_timer_regs[tmr] & 0xFFFF0000) | (m_timer_reload[tmr] & 0x0000FFFF); | |
388 | rate = 0x10000 - (m_timer_regs[tmr] & 0xffff); | |
389 | clocksel = timer_clks[(m_timer_regs[tmr] >> 16) & 3]; | |
392 | 390 | final = clocksel / rate; |
393 | | |
391 | m_timer_hz[tmr] = final; | |
394 | 392 | time = attotime::from_hz(final); |
395 | 393 | GBA_ATTOTIME_NORMALIZE(time); |
396 | | |
394 | m_tmr_timer[tmr]->adjust(time, tmr, time); | |
397 | 395 | } |
398 | 396 | |
399 | 397 | // check if timers 0 or 1 are feeding directsound |
400 | 398 | if (tmr == 0) |
401 | 399 | { |
402 | if (( | |
400 | if ((m_SOUNDCNT_H & 0x400) == 0) | |
403 | 401 | { |
404 | audio_tick(machine, 0); | |
402 | audio_tick(machine(), 0); | |
405 | 403 | } |
406 | 404 | |
407 | if (( | |
405 | if ((m_SOUNDCNT_H & 0x4000) == 0) | |
408 | 406 | { |
409 | audio_tick(machine, 1); | |
407 | audio_tick(machine(), 1); | |
410 | 408 | } |
411 | 409 | } |
412 | 410 | |
413 | 411 | if (tmr == 1) |
414 | 412 | { |
415 | if (( | |
413 | if ((m_SOUNDCNT_H & 0x400) == 0x400) | |
416 | 414 | { |
417 | audio_tick(machine, 0); | |
415 | audio_tick(machine(), 0); | |
418 | 416 | } |
419 | 417 | |
420 | if (( | |
418 | if ((m_SOUNDCNT_H & 0x4000) == 0x4000) | |
421 | 419 | { |
422 | audio_tick(machine, 1); | |
420 | audio_tick(machine(), 1); | |
423 | 421 | } |
424 | 422 | } |
425 | 423 | |
r18113 | r18114 | |
427 | 425 | switch (tmr) |
428 | 426 | { |
429 | 427 | case 0: |
430 | if ( | |
428 | if (m_timer_regs[1] & 0x40000) | |
431 | 429 | { |
432 | state->m_timer_regs[1] = (( ( state->m_timer_regs[1] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[1] & 0xffff0000); | |
433 | if( ( state->m_timer_regs[1] & 0x0000ffff ) == 0 ) | |
430 | m_timer_regs[1] = (( ( m_timer_regs[1] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[1] & 0xffff0000); | |
431 | if( ( m_timer_regs[1] & 0x0000ffff ) == 0 ) | |
434 | 432 | { |
435 | state->m_timer_regs[1] |= state->m_timer_reload[1]; | |
436 | if( ( state->m_timer_regs[1] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
433 | m_timer_regs[1] |= m_timer_reload[1]; | |
434 | if( ( m_timer_regs[1] & 0x400000 ) && ( m_IME != 0 ) ) | |
437 | 435 | { |
438 | gba_request_irq( machine, tmr_ints[1] ); | |
436 | gba_request_irq( machine(), tmr_ints[1] ); | |
439 | 437 | } |
440 | if( ( | |
438 | if( ( m_timer_regs[2] & 0x40000 ) ) | |
441 | 439 | { |
442 | state->m_timer_regs[2] = (( ( state->m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[2] & 0xffff0000); | |
443 | if( ( state->m_timer_regs[2] & 0x0000ffff ) == 0 ) | |
440 | m_timer_regs[2] = (( ( m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[2] & 0xffff0000); | |
441 | if( ( m_timer_regs[2] & 0x0000ffff ) == 0 ) | |
444 | 442 | { |
445 | state->m_timer_regs[2] |= state->m_timer_reload[2]; | |
446 | if( ( state->m_timer_regs[2] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
443 | m_timer_regs[2] |= m_timer_reload[2]; | |
444 | if( ( m_timer_regs[2] & 0x400000 ) && ( m_IME != 0 ) ) | |
447 | 445 | { |
448 | gba_request_irq( machine, tmr_ints[2] ); | |
446 | gba_request_irq( machine(), tmr_ints[2] ); | |
449 | 447 | } |
450 | if( ( | |
448 | if( ( m_timer_regs[3] & 0x40000 ) ) | |
451 | 449 | { |
452 | state->m_timer_regs[3] = (( ( state->m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[3] & 0xffff0000); | |
453 | if( ( state->m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
450 | m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); | |
451 | if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
454 | 452 | { |
455 | state->m_timer_regs[3] |= state->m_timer_reload[3]; | |
456 | if( ( state->m_timer_regs[3] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
453 | m_timer_regs[3] |= m_timer_reload[3]; | |
454 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) | |
457 | 455 | { |
458 | gba_request_irq( machine, tmr_ints[3] ); | |
456 | gba_request_irq( machine(), tmr_ints[3] ); | |
459 | 457 | } |
460 | 458 | } |
461 | 459 | } |
r18113 | r18114 | |
465 | 463 | } |
466 | 464 | break; |
467 | 465 | case 1: |
468 | if ( | |
466 | if (m_timer_regs[2] & 0x40000) | |
469 | 467 | { |
470 | state->m_timer_regs[2] = (( ( state->m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[2] & 0xffff0000); | |
471 | if( ( state->m_timer_regs[2] & 0x0000ffff ) == 0 ) | |
468 | m_timer_regs[2] = (( ( m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[2] & 0xffff0000); | |
469 | if( ( m_timer_regs[2] & 0x0000ffff ) == 0 ) | |
472 | 470 | { |
473 | state->m_timer_regs[2] |= state->m_timer_reload[2]; | |
474 | if( ( state->m_timer_regs[2] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
471 | m_timer_regs[2] |= m_timer_reload[2]; | |
472 | if( ( m_timer_regs[2] & 0x400000 ) && ( m_IME != 0 ) ) | |
475 | 473 | { |
476 | gba_request_irq( machine, tmr_ints[2] ); | |
474 | gba_request_irq( machine(), tmr_ints[2] ); | |
477 | 475 | } |
478 | if( ( | |
476 | if( ( m_timer_regs[3] & 0x40000 ) ) | |
479 | 477 | { |
480 | state->m_timer_regs[3] = (( ( state->m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[3] & 0xffff0000); | |
481 | if( ( state->m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
478 | m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); | |
479 | if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
482 | 480 | { |
483 | state->m_timer_regs[3] |= state->m_timer_reload[3]; | |
484 | if( ( state->m_timer_regs[3] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
481 | m_timer_regs[3] |= m_timer_reload[3]; | |
482 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) | |
485 | 483 | { |
486 | gba_request_irq( machine, tmr_ints[3] ); | |
484 | gba_request_irq( machine(), tmr_ints[3] ); | |
487 | 485 | } |
488 | 486 | } |
489 | 487 | } |
r18113 | r18114 | |
491 | 489 | } |
492 | 490 | break; |
493 | 491 | case 2: |
494 | if ( | |
492 | if (m_timer_regs[3] & 0x40000) | |
495 | 493 | { |
496 | state->m_timer_regs[3] = (( ( state->m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (state->m_timer_regs[3] & 0xffff0000); | |
497 | if( ( state->m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
494 | m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); | |
495 | if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) | |
498 | 496 | { |
499 | state->m_timer_regs[3] |= state->m_timer_reload[3]; | |
500 | if( ( state->m_timer_regs[3] & 0x400000 ) && ( state->m_IME != 0 ) ) | |
497 | m_timer_regs[3] |= m_timer_reload[3]; | |
498 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) | |
501 | 499 | { |
502 | gba_request_irq( machine, tmr_ints[3] ); | |
500 | gba_request_irq( machine(), tmr_ints[3] ); | |
503 | 501 | } |
504 | 502 | } |
505 | 503 | } |
r18113 | r18114 | |
507 | 505 | } |
508 | 506 | |
509 | 507 | // are we supposed to IRQ? |
510 | if (( | |
508 | if ((m_timer_regs[tmr] & 0x400000) && (m_IME != 0)) | |
511 | 509 | { |
512 | gba_request_irq(machine, tmr_ints[tmr]); | |
510 | gba_request_irq(machine(), tmr_ints[tmr]); | |
513 | 511 | } |
514 | 512 | } |
515 | 513 | |
516 | ||
514 | TIMER_CALLBACK_MEMBER(gba_state::handle_irq) | |
517 | 515 | { |
518 | gba_state *state = machine.driver_data<gba_state>(); | |
519 | 516 | |
520 | gba_request_irq(machine, | |
517 | gba_request_irq(machine(), m_IF); | |
521 | 518 | |
522 | | |
519 | m_irq_timer->adjust(attotime::never); | |
523 | 520 | } |
524 | 521 | |
525 | 522 | READ32_MEMBER(gba_state::gba_io_r) |
r18113 | r18114 | |
2004 | 2001 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("A") PORT_PLAYER(1) // A |
2005 | 2002 | INPUT_PORTS_END |
2006 | 2003 | |
2007 | ||
2004 | TIMER_CALLBACK_MEMBER(gba_state::perform_hbl) | |
2008 | 2005 | { |
2009 | 2006 | int ch, ctrl; |
2010 | gba_state *state = machine.driver_data<gba_state>(); | |
2011 | int scanline = machine.primary_screen->vpos(); | |
2007 | int scanline = machine().primary_screen->vpos(); | |
2012 | 2008 | |
2013 | 2009 | // draw only visible scanlines |
2014 | 2010 | if (scanline < 160) |
2015 | 2011 | { |
2016 | gba_draw_scanline(machine, scanline); | |
2012 | gba_draw_scanline(machine(), scanline); | |
2017 | 2013 | } |
2018 | state->m_DISPSTAT |= DISPSTAT_HBL; | |
2019 | if ((state->m_DISPSTAT & DISPSTAT_HBL_IRQ_EN ) != 0) | |
2014 | m_DISPSTAT |= DISPSTAT_HBL; | |
2015 | if ((m_DISPSTAT & DISPSTAT_HBL_IRQ_EN ) != 0) | |
2020 | 2016 | { |
2021 | gba_request_irq(machine, INT_HBL); | |
2017 | gba_request_irq(machine(), INT_HBL); | |
2022 | 2018 | } |
2023 | 2019 | |
2024 | 2020 | for (ch = 0; ch < 4; ch++) |
2025 | 2021 | { |
2026 | ctrl = | |
2022 | ctrl = m_dma_regs[(ch*3)+2]>>16; | |
2027 | 2023 | |
2028 | 2024 | // HBL-triggered DMA? |
2029 | 2025 | if ((ctrl & 0x8000) && ((ctrl & 0x3000) == 0x2000)) |
2030 | 2026 | { |
2031 | dma_exec(machine, ch); | |
2027 | dma_exec(machine(), ch); | |
2032 | 2028 | } |
2033 | 2029 | } |
2034 | 2030 | |
2035 | | |
2031 | m_hbl_timer->adjust(attotime::never); | |
2036 | 2032 | } |
2037 | 2033 | |
2038 | ||
2034 | TIMER_CALLBACK_MEMBER(gba_state::perform_scan) | |
2039 | 2035 | { |
2040 | 2036 | int scanline; |
2041 | gba_state *state = machine.driver_data<gba_state>(); | |
2042 | 2037 | |
2043 | 2038 | // clear hblank and raster IRQ flags |
2044 | | |
2039 | m_DISPSTAT &= ~(DISPSTAT_HBL|DISPSTAT_VCNT); | |
2045 | 2040 | |
2046 | scanline = machine.primary_screen->vpos(); | |
2041 | scanline = machine().primary_screen->vpos(); | |
2047 | 2042 | |
2048 | 2043 | // VBL is set for scanlines 160 through 226 (but not 227, which is the last line) |
2049 | 2044 | if (scanline >= 160 && scanline < 227) |
2050 | 2045 | { |
2051 | | |
2046 | m_DISPSTAT |= DISPSTAT_VBL; | |
2052 | 2047 | } |
2053 | 2048 | else |
2054 | 2049 | { |
2055 | | |
2050 | m_DISPSTAT &= ~DISPSTAT_VBL; | |
2056 | 2051 | } |
2057 | 2052 | |
2058 | 2053 | // handle VCNT match interrupt/flag |
2059 | if (scanline == (( | |
2054 | if (scanline == ((m_DISPSTAT >> 8) & 0xff)) | |
2060 | 2055 | { |
2061 | state->m_DISPSTAT |= DISPSTAT_VCNT; | |
2062 | if (state->m_DISPSTAT & DISPSTAT_VCNT_IRQ_EN) | |
2056 | m_DISPSTAT |= DISPSTAT_VCNT; | |
2057 | if (m_DISPSTAT & DISPSTAT_VCNT_IRQ_EN) | |
2063 | 2058 | { |
2064 | gba_request_irq(machine, INT_VCNT); | |
2059 | gba_request_irq(machine(), INT_VCNT); | |
2065 | 2060 | } |
2066 | 2061 | } |
2067 | 2062 | |
r18113 | r18114 | |
2092 | 2087 | // More work on IRQs is definitely necessary! |
2093 | 2088 | int ch, ctrl; |
2094 | 2089 | |
2095 | if ( | |
2090 | if (m_DISPSTAT & DISPSTAT_VBL_IRQ_EN) | |
2096 | 2091 | { |
2097 | gba_request_irq(machine, INT_VBL); | |
2092 | gba_request_irq(machine(), INT_VBL); | |
2098 | 2093 | } |
2099 | 2094 | |
2100 | 2095 | for (ch = 0; ch < 4; ch++) |
2101 | 2096 | { |
2102 | ctrl = | |
2097 | ctrl = m_dma_regs[(ch*3)+2]>>16; | |
2103 | 2098 | |
2104 | 2099 | // VBL-triggered DMA? |
2105 | 2100 | if ((ctrl & 0x8000) && ((ctrl & 0x3000) == 0x1000)) |
2106 | 2101 | { |
2107 | dma_exec(machine, ch); | |
2102 | dma_exec(machine(), ch); | |
2108 | 2103 | } |
2109 | 2104 | } |
2110 | 2105 | } |
2111 | 2106 | |
2112 | state->m_hbl_timer->adjust(machine.primary_screen->time_until_pos(scanline, 240)); | |
2113 | state->m_scan_timer->adjust(machine.primary_screen->time_until_pos(( scanline + 1 ) % 228, 0)); | |
2107 | m_hbl_timer->adjust(machine().primary_screen->time_until_pos(scanline, 240)); | |
2108 | m_scan_timer->adjust(machine().primary_screen->time_until_pos(( scanline + 1 ) % 228, 0)); | |
2114 | 2109 | } |
2115 | 2110 | |
2116 | 2111 | void gba_state::machine_reset() |
r18113 | r18114 | |
2179 | 2174 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gba_machine_stop),&machine())); |
2180 | 2175 | |
2181 | 2176 | /* create a timer to fire scanline functions */ |
2182 | m_scan_timer = machine().scheduler().timer_alloc(FUNC(perform_scan)); | |
2183 | m_hbl_timer = machine().scheduler().timer_alloc(FUNC(perform_hbl)); | |
2177 | m_scan_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::perform_scan),this)); | |
2178 | m_hbl_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::perform_hbl),this)); | |
2184 | 2179 | m_scan_timer->adjust(machine().primary_screen->time_until_pos(0, 0)); |
2185 | 2180 | |
2186 | 2181 | /* and one for each DMA channel */ |
2187 | m_dma_timer[0] = machine().scheduler().timer_alloc(FUNC(dma_complete)); | |
2188 | m_dma_timer[1] = machine().scheduler().timer_alloc(FUNC(dma_complete)); | |
2189 | m_dma_timer[2] = machine().scheduler().timer_alloc(FUNC(dma_complete)); | |
2190 | m_dma_timer[3] = machine().scheduler().timer_alloc(FUNC(dma_complete)); | |
2182 | m_dma_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::dma_complete),this)); | |
2183 | m_dma_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::dma_complete),this)); | |
2184 | m_dma_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::dma_complete),this)); | |
2185 | m_dma_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::dma_complete),this)); | |
2191 | 2186 | m_dma_timer[0]->adjust(attotime::never); |
2192 | 2187 | m_dma_timer[1]->adjust(attotime::never, 1); |
2193 | 2188 | m_dma_timer[2]->adjust(attotime::never, 2); |
2194 | 2189 | m_dma_timer[3]->adjust(attotime::never, 3); |
2195 | 2190 | |
2196 | 2191 | /* also one for each timer (heh) */ |
2197 | m_tmr_timer[0] = machine().scheduler().timer_alloc(FUNC(timer_expire)); | |
2198 | m_tmr_timer[1] = machine().scheduler().timer_alloc(FUNC(timer_expire)); | |
2199 | m_tmr_timer[2] = machine().scheduler().timer_alloc(FUNC(timer_expire)); | |
2200 | m_tmr_timer[3] = machine().scheduler().timer_alloc(FUNC(timer_expire)); | |
2192 | m_tmr_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::timer_expire),this)); | |
2193 | m_tmr_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::timer_expire),this)); | |
2194 | m_tmr_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::timer_expire),this)); | |
2195 | m_tmr_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::timer_expire),this)); | |
2201 | 2196 | m_tmr_timer[0]->adjust(attotime::never); |
2202 | 2197 | m_tmr_timer[1]->adjust(attotime::never, 1); |
2203 | 2198 | m_tmr_timer[2]->adjust(attotime::never, 2); |
2204 | 2199 | m_tmr_timer[3]->adjust(attotime::never, 3); |
2205 | 2200 | |
2206 | 2201 | /* and an IRQ handling timer */ |
2207 | m_irq_timer = machine().scheduler().timer_alloc(FUNC(handle_irq)); | |
2202 | m_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gba_state::handle_irq),this)); | |
2208 | 2203 | m_irq_timer->adjust(attotime::never); |
2209 | 2204 | } |
2210 | 2205 |
r18113 | r18114 | |
---|---|---|
176 | 176 | drvstate->m_last_nmi_state = state; |
177 | 177 | } |
178 | 178 | |
179 | ||
179 | TIMER_CALLBACK_MEMBER(coleco_state::paddle_d7reset_callback) | |
180 | 180 | { |
181 | coleco_state *state = machine.driver_data<coleco_state>(); | |
182 | 181 | |
183 | state->m_joy_d7_state[param] = 0; | |
184 | state->m_joy_analog_state[param] = 0; | |
182 | m_joy_d7_state[param] = 0; | |
183 | m_joy_analog_state[param] = 0; | |
185 | 184 | } |
186 | 185 | |
187 | ||
186 | TIMER_CALLBACK_MEMBER(coleco_state::paddle_irqreset_callback) | |
188 | 187 | { |
189 | coleco_state *state = machine.driver_data<coleco_state>(); | |
190 | 188 | |
191 | | |
189 | m_joy_irq_state[param] = 0; | |
192 | 190 | |
193 | if (!state->m_joy_irq_state[param ^ 1]) | |
194 | state->m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); | |
191 | if (!m_joy_irq_state[param ^ 1]) | |
192 | m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); | |
195 | 193 | } |
196 | 194 | |
197 | ||
195 | TIMER_CALLBACK_MEMBER(coleco_state::paddle_pulse_callback) | |
198 | 196 | { |
199 | coleco_state *state = machine.driver_data<coleco_state>(); | |
200 | 197 | |
201 | if ( | |
198 | if (m_joy_analog_reload[param]) | |
202 | 199 | { |
203 | | |
200 | m_joy_analog_state[param] = m_joy_analog_reload[param]; | |
204 | 201 | |
205 | 202 | // on movement, controller port d7 is set for a short period and an irq is fired on d7 rising edge |
206 | state->m_joy_d7_state[param] = 0x80; | |
207 | state->m_joy_d7_timer[param]->adjust(attotime::from_usec(500), param); // TODO: measure duration | |
203 | m_joy_d7_state[param] = 0x80; | |
204 | m_joy_d7_timer[param]->adjust(attotime::from_usec(500), param); // TODO: measure duration | |
208 | 205 | |
209 | 206 | // irq on rising edge, PULSE_LINE is not supported in this case, so clear it manually |
210 | state->m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); | |
211 | state->m_joy_irq_timer[param]->adjust(attotime::from_usec(11), param); // TODO: measure duration | |
212 | state->m_joy_irq_state[param] = 1; | |
207 | m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); | |
208 | m_joy_irq_timer[param]->adjust(attotime::from_usec(11), param); // TODO: measure duration | |
209 | m_joy_irq_state[param] = 1; | |
213 | 210 | |
214 | 211 | // reload timer |
215 | | |
212 | m_joy_pulse_timer[param]->adjust(m_joy_pulse_reload[param], param); | |
216 | 213 | } |
217 | 214 | } |
218 | 215 | |
r18113 | r18114 | |
264 | 261 | // init paddles |
265 | 262 | for (int port = 0; port < 2; port++) |
266 | 263 | { |
267 | m_joy_pulse_timer[port] = machine().scheduler().timer_alloc(FUNC(paddle_pulse_callback)); | |
268 | m_joy_d7_timer[port] = machine().scheduler().timer_alloc(FUNC(paddle_d7reset_callback)); | |
269 | m_joy_irq_timer[port] = machine().scheduler().timer_alloc(FUNC(paddle_irqreset_callback)); | |
264 | m_joy_pulse_timer[port] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(coleco_state::paddle_pulse_callback),this)); | |
265 | m_joy_d7_timer[port] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(coleco_state::paddle_d7reset_callback),this)); | |
266 | m_joy_irq_timer[port] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(coleco_state::paddle_irqreset_callback),this)); | |
270 | 267 | |
271 | 268 | m_joy_irq_state[port] = 0; |
272 | 269 | m_joy_d7_state[port] = 0; |
r18113 | r18114 | |
---|---|---|
325 | 325 | INTERRUPTS |
326 | 326 | ***************************************************************************/ |
327 | 327 | |
328 | ||
328 | TIMER_CALLBACK_MEMBER(samcoupe_state::irq_off) | |
329 | 329 | { |
330 | samcoupe_state *state = machine.driver_data<samcoupe_state>(); | |
331 | 330 | /* adjust STATUS register */ |
332 | | |
331 | m_status |= param; | |
333 | 332 | |
334 | 333 | /* clear interrupt */ |
335 | if ((state->m_status & 0x1f) == 0x1f) | |
336 | machine.device("maincpu")->execute().set_input_line(0, CLEAR_LINE); | |
334 | if ((m_status & 0x1f) == 0x1f) | |
335 | machine().device("maincpu")->execute().set_input_line(0, CLEAR_LINE); | |
337 | 336 | |
338 | 337 | } |
339 | 338 | |
r18113 | r18114 | |
343 | 342 | |
344 | 343 | /* assert irq and a timer to set it off again */ |
345 | 344 | device->execute().set_input_line(0, ASSERT_LINE); |
346 | device->machine().scheduler().timer_set(attotime::from_usec(20), FUNC(irq_off), src); | |
345 | device->machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(samcoupe_state::irq_off),state), src); | |
347 | 346 | |
348 | 347 | /* adjust STATUS register */ |
349 | 348 | state->m_status &= ~src; |
r18113 | r18114 | |
---|---|---|
479 | 479 | // TIMER_CALLBACK( st_mouse_tick ) |
480 | 480 | //------------------------------------------------- |
481 | 481 | |
482 | ||
482 | TIMER_CALLBACK_MEMBER(st_state::st_mouse_tick) | |
483 | 483 | { |
484 | st_state *state = machine.driver_data<st_state>(); | |
485 | 484 | |
486 | | |
485 | mouse_tick(); | |
487 | 486 | } |
488 | 487 | |
489 | 488 | |
r18113 | r18114 | |
776 | 775 | // TIMER_CALLBACK( atariste_dmasound_tick ) |
777 | 776 | //------------------------------------------------- |
778 | 777 | |
779 | ||
778 | TIMER_CALLBACK_MEMBER(ste_state::atariste_dmasound_tick) | |
780 | 779 | { |
781 | ste_state *state = machine.driver_data<ste_state>(); | |
782 | 780 | |
783 | | |
781 | dmasound_tick(); | |
784 | 782 | } |
785 | 783 | |
786 | 784 | |
r18113 | r18114 | |
1027 | 1025 | // TIMER_CALLBACK( atariste_microwire_tick ) |
1028 | 1026 | //------------------------------------------------- |
1029 | 1027 | |
1030 | ||
1028 | TIMER_CALLBACK_MEMBER(ste_state::atariste_microwire_tick) | |
1031 | 1029 | { |
1032 | ste_state *state = machine.driver_data<ste_state>(); | |
1033 | 1030 | |
1034 | | |
1031 | microwire_tick(); | |
1035 | 1032 | } |
1036 | 1033 | |
1037 | 1034 | |
r18113 | r18114 | |
2208 | 2205 | m_maincpu->set_irq_acknowledge_callback(atarist_int_ack); |
2209 | 2206 | |
2210 | 2207 | // allocate timers |
2211 | m_mouse_timer = machine().scheduler().timer_alloc(FUNC(st_mouse_tick)); | |
2208 | m_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_state::st_mouse_tick),this)); | |
2212 | 2209 | m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(500)); |
2213 | 2210 | |
2214 | 2211 | // register for state saving |
r18113 | r18114 | |
2265 | 2262 | m_maincpu->set_irq_acknowledge_callback(atarist_int_ack); |
2266 | 2263 | |
2267 | 2264 | /* allocate timers */ |
2268 | m_dmasound_timer = machine().scheduler().timer_alloc(FUNC(atariste_dmasound_tick)); | |
2269 | m_microwire_timer = machine().scheduler().timer_alloc(FUNC(atariste_microwire_tick)); | |
2265 | m_dmasound_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ste_state::atariste_dmasound_tick),this)); | |
2266 | m_microwire_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ste_state::atariste_microwire_tick),this)); | |
2270 | 2267 | |
2271 | 2268 | /* register for state saving */ |
2272 | 2269 | state_save(); |
r18113 | r18114 | |
---|---|---|
340 | 340 | */ |
341 | 341 | |
342 | 342 | |
343 | static TIMER_CALLBACK(reader_callback); | |
344 | static TIMER_CALLBACK(puncher_callback); | |
345 | static TIMER_CALLBACK(prt_callback); | |
346 | static TIMER_CALLBACK(dis_callback); | |
347 | 343 | |
348 | 344 | |
349 | 345 | |
r18113 | r18114 | |
352 | 348 | |
353 | 349 | |
354 | 350 | |
351 | ||
352 | ||
353 | ||
354 | ||
355 | 355 | /* crt display timer */ |
356 | 356 | |
357 | 357 | |
r18113 | r18114 | |
383 | 383 | |
384 | 384 | void tx0_state::machine_start() |
385 | 385 | { |
386 | m_tape_reader.timer = machine().scheduler().timer_alloc(FUNC(reader_callback)); | |
387 | m_tape_puncher.timer = machine().scheduler().timer_alloc(FUNC(puncher_callback)); | |
388 | m_typewriter.prt_timer = machine().scheduler().timer_alloc(FUNC(prt_callback)); | |
389 | m_dis_timer = machine().scheduler().timer_alloc(FUNC(dis_callback)); | |
386 | m_tape_reader.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx0_state::reader_callback),this)); | |
387 | m_tape_puncher.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx0_state::puncher_callback),this)); | |
388 | m_typewriter.prt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx0_state::prt_callback),this)); | |
389 | m_dis_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx0_state::dis_callback),this)); | |
390 | 390 | |
391 | 391 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(tx0_machine_stop),&machine())); |
392 | 392 | } |
r18113 | r18114 | |
631 | 631 | /* |
632 | 632 | timer callback to simulate reader IO |
633 | 633 | */ |
634 | ||
634 | TIMER_CALLBACK_MEMBER(tx0_state::reader_callback) | |
635 | 635 | { |
636 | tx0_state *state = machine.driver_data<tx0_state>(); | |
637 | 636 | int not_ready; |
638 | 637 | UINT8 data; |
639 | 638 | int ac; |
640 | 639 | |
641 | if ( | |
640 | if (m_tape_reader.rc) | |
642 | 641 | { |
643 | not_ready = tape_read( | |
642 | not_ready = tape_read(this, & data); | |
644 | 643 | if (not_ready) |
645 | 644 | { |
646 | | |
645 | m_tape_reader.motor_on = 0; /* let us stop the motor */ | |
647 | 646 | } |
648 | 647 | else |
649 | 648 | { |
650 | 649 | if (data & 0100) |
651 | 650 | { |
652 | 651 | /* read current AC */ |
653 | ac = machine.device("maincpu")->state().state_int(TX0_AC); | |
652 | ac = machine().device("maincpu")->state().state_int(TX0_AC); | |
654 | 653 | /* cycle right */ |
655 | 654 | ac = (ac >> 1) | ((ac & 1) << 17); |
656 | 655 | /* shuffle and insert data into AC */ |
657 | 656 | ac = (ac /*& 0333333*/) | ((data & 001) << 17) | ((data & 002) << 13) | ((data & 004) << 9) | ((data & 010) << 5) | ((data & 020) << 1) | ((data & 040) >> 3); |
658 | 657 | /* write modified AC */ |
659 | machine.device("maincpu")->state().set_state_int(TX0_AC, ac); | |
658 | machine().device("maincpu")->state().set_state_int(TX0_AC, ac); | |
660 | 659 | |
661 | | |
660 | m_tape_reader.rc = (m_tape_reader.rc+1) & 3; | |
662 | 661 | |
663 | if ( | |
662 | if (m_tape_reader.rc == 0) | |
664 | 663 | { /* IO complete */ |
665 | state->m_tape_reader.rcl = 0; | |
666 | machine.device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
664 | m_tape_reader.rcl = 0; | |
665 | machine().device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
667 | 666 | } |
668 | 667 | } |
669 | 668 | } |
670 | 669 | } |
671 | 670 | |
672 | if ( | |
671 | if (m_tape_reader.motor_on && m_tape_reader.rcl) | |
673 | 672 | /* delay is approximately 1/400s */ |
674 | | |
673 | m_tape_reader.timer->adjust(attotime::from_usec(2500)); | |
675 | 674 | else |
676 | | |
675 | m_tape_reader.timer->enable(0); | |
677 | 676 | } |
678 | 677 | |
679 | 678 | /* |
r18113 | r18114 | |
697 | 696 | state->m_tape_puncher.fd = NULL; |
698 | 697 | } |
699 | 698 | |
700 | ||
699 | TIMER_CALLBACK_MEMBER(tx0_state::puncher_callback) | |
701 | 700 | { |
702 | machine.device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
701 | machine().device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
703 | 702 | } |
704 | 703 | |
705 | 704 | /* |
r18113 | r18114 | |
792 | 791 | /* |
793 | 792 | timer callback to generate typewriter completion pulse |
794 | 793 | */ |
795 | ||
794 | TIMER_CALLBACK_MEMBER(tx0_state::prt_callback) | |
796 | 795 | { |
797 | machine.device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
796 | machine().device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
798 | 797 | } |
799 | 798 | |
800 | 799 | /* |
r18113 | r18114 | |
819 | 818 | /* |
820 | 819 | timer callback to generate crt completion pulse |
821 | 820 | */ |
822 | ||
821 | TIMER_CALLBACK_MEMBER(tx0_state::dis_callback) | |
823 | 822 | { |
824 | machine.device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
823 | machine().device("maincpu")->state().set_state_int(TX0_IO_COMPLETE, (UINT64)0); | |
825 | 824 | } |
826 | 825 | |
827 | 826 | /* |
r18113 | r18114 | |
---|---|---|
546 | 546 | |
547 | 547 | /* Driver Initialization */ |
548 | 548 | |
549 | ||
549 | TIMER_CALLBACK_MEMBER(studio2_state::setup_beep) | |
550 | 550 | { |
551 | device_t *speaker = machine.device(BEEPER_TAG); | |
551 | device_t *speaker = machine().device(BEEPER_TAG); | |
552 | 552 | beep_set_state(speaker, 0); |
553 | 553 | beep_set_frequency(speaker, 300); |
554 | 554 | } |
555 | 555 | |
556 | 556 | DRIVER_INIT_MEMBER(studio2_state,studio2) |
557 | 557 | { |
558 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep)); | |
558 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(studio2_state::setup_beep),this)); | |
559 | 559 | } |
560 | 560 | |
561 | 561 | /* Game Drivers */ |
r18113 | r18114 | |
---|---|---|
162 | 162 | machine.device("maincpu")->execute().set_input_line(0, CLEAR_LINE); |
163 | 163 | } |
164 | 164 | |
165 | ||
165 | TIMER_CALLBACK_MEMBER(pcw_state::pcw_timer_pulse) | |
166 | 166 | { |
167 | pcw_state *state = machine.driver_data<pcw_state>(); | |
168 | state->m_timer_irq_flag = 0; | |
169 | pcw_update_irqs(machine); | |
167 | m_timer_irq_flag = 0; | |
168 | pcw_update_irqs(machine()); | |
170 | 169 | } |
171 | 170 | |
172 | 171 | /* callback for 1/300ths of a second interrupt */ |
r18113 | r18114 | |
177 | 176 | |
178 | 177 | state->m_timer_irq_flag = 1; |
179 | 178 | pcw_update_irqs(timer.machine()); |
180 | timer.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(pcw_timer_pulse)); | |
179 | timer.machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(pcw_state::pcw_timer_pulse),state)); | |
181 | 180 | } |
182 | 181 | |
183 | 182 | /* fdc interrupt callback. set/clear fdc int */ |
r18113 | r18114 | |
731 | 730 | * T0: Paper sensor (?) |
732 | 731 | * T1: Print head location (1 if not at left margin) |
733 | 732 | */ |
734 | ||
733 | TIMER_CALLBACK_MEMBER(pcw_state::pcw_stepper_callback) | |
735 | 734 | { |
736 | pcw_state *state = machine.driver_data<pcw_state>(); | |
737 | 735 | |
738 | //popmessage("PRN: P2 bits %s %s %s\nSerial: %02x\nHeadpos: %i",state->m_printer_p2 & 0x40 ? " " : "6",state->m_printer_p2 & 0x20 ? " " : "5",state->m_printer_p2 & 0x10 ? " " : "4",state->m_printer_shift_output,state->m_printer_headpos); | |
739 | if((state->m_printer_p2 & 0x10) == 0) // print head motor active | |
736 | //popmessage("PRN: P2 bits %s %s %s\nSerial: %02x\nHeadpos: %i",m_printer_p2 & 0x40 ? " " : "6",m_printer_p2 & 0x20 ? " " : "5",m_printer_p2 & 0x10 ? " " : "4",m_printer_shift_output,m_printer_headpos); | |
737 | if((m_printer_p2 & 0x10) == 0) // print head motor active | |
740 | 738 | { |
741 | UINT8 stepper_state = (state->m_printer_shift_output >> 4) & 0x0f; | |
742 | if(stepper_state == full_step_table[(state->m_head_motor_state + 1) & 0x03]) | |
739 | UINT8 stepper_state = (m_printer_shift_output >> 4) & 0x0f; | |
740 | if(stepper_state == full_step_table[(m_head_motor_state + 1) & 0x03]) | |
743 | 741 | { |
744 | state->m_printer_headpos += 2; | |
745 | state->m_head_motor_state++; | |
746 | logerror("Printer head moved forward by 2 to %i\n",state->m_printer_headpos); | |
742 | m_printer_headpos += 2; | |
743 | m_head_motor_state++; | |
744 | logerror("Printer head moved forward by 2 to %i\n",m_printer_headpos); | |
747 | 745 | } |
748 | if(stepper_state == half_step_table[( | |
746 | if(stepper_state == half_step_table[(m_head_motor_state + 1) & 0x03]) | |
749 | 747 | { |
750 | state->m_printer_headpos += 1; | |
751 | state->m_head_motor_state++; | |
752 | logerror("Printer head moved forward by 1 to %i\n",state->m_printer_headpos); | |
748 | m_printer_headpos += 1; | |
749 | m_head_motor_state++; | |
750 | logerror("Printer head moved forward by 1 to %i\n",m_printer_headpos); | |
753 | 751 | } |
754 | if(stepper_state == full_step_table[( | |
752 | if(stepper_state == full_step_table[(m_head_motor_state - 1) & 0x03]) | |
755 | 753 | { |
756 | state->m_printer_headpos -= 2; | |
757 | state->m_head_motor_state--; | |
758 | logerror("Printer head moved back by 2 to %i\n",state->m_printer_headpos); | |
754 | m_printer_headpos -= 2; | |
755 | m_head_motor_state--; | |
756 | logerror("Printer head moved back by 2 to %i\n",m_printer_headpos); | |
759 | 757 | } |
760 | if(stepper_state == half_step_table[( | |
758 | if(stepper_state == half_step_table[(m_head_motor_state - 1) & 0x03]) | |
761 | 759 | { |
762 | state->m_printer_headpos -= 1; | |
763 | state->m_head_motor_state--; | |
764 | logerror("Printer head moved back by 1 to %i\n",state->m_printer_headpos); | |
760 | m_printer_headpos -= 1; | |
761 | m_head_motor_state--; | |
762 | logerror("Printer head moved back by 1 to %i\n",m_printer_headpos); | |
765 | 763 | } |
766 | if(state->m_printer_headpos < 0) | |
767 | state->m_printer_headpos = 0; | |
768 | if(state->m_printer_headpos > PCW_PRINTER_WIDTH) | |
769 | state->m_printer_headpos = PCW_PRINTER_WIDTH; | |
770 | state->m_head_motor_state &= 0x03; | |
771 | state->m_printer_p2 |= 0x10; | |
764 | if(m_printer_headpos < 0) | |
765 | m_printer_headpos = 0; | |
766 | if(m_printer_headpos > PCW_PRINTER_WIDTH) | |
767 | m_printer_headpos = PCW_PRINTER_WIDTH; | |
768 | m_head_motor_state &= 0x03; | |
769 | m_printer_p2 |= 0x10; | |
772 | 770 | } |
773 | if(( | |
771 | if((m_printer_p2 & 0x20) == 0) // line feed motor active | |
774 | 772 | { |
775 | UINT8 stepper_state = state->m_printer_shift_output & 0x0f; | |
776 | if(stepper_state == full_step_table[(state->m_linefeed_motor_state + 1) & 0x03]) | |
773 | UINT8 stepper_state = m_printer_shift_output & 0x0f; | |
774 | if(stepper_state == full_step_table[(m_linefeed_motor_state + 1) & 0x03]) | |
777 | 775 | { |
778 | state->m_paper_feed++; | |
779 | if(state->m_paper_feed > PCW_PRINTER_HEIGHT*2) | |
780 | state->m_paper_feed = 0; | |
781 | state->m_linefeed_motor_state++; | |
776 | m_paper_feed++; | |
777 | if(m_paper_feed > PCW_PRINTER_HEIGHT*2) | |
778 | m_paper_feed = 0; | |
779 | m_linefeed_motor_state++; | |
782 | 780 | } |
783 | if(stepper_state == half_step_table[( | |
781 | if(stepper_state == half_step_table[(m_linefeed_motor_state + 1) & 0x03]) | |
784 | 782 | { |
785 | state->m_paper_feed++; | |
786 | if(state->m_paper_feed > PCW_PRINTER_HEIGHT*2) | |
787 | state->m_paper_feed = 0; | |
788 | state->m_linefeed_motor_state++; | |
783 | m_paper_feed++; | |
784 | if(m_paper_feed > PCW_PRINTER_HEIGHT*2) | |
785 | m_paper_feed = 0; | |
786 | m_linefeed_motor_state++; | |
789 | 787 | } |
790 | state->m_linefeed_motor_state &= 0x03; | |
791 | state->m_printer_p2 |= 0x20; | |
788 | m_linefeed_motor_state &= 0x03; | |
789 | m_printer_p2 |= 0x20; | |
792 | 790 | } |
793 | 791 | } |
794 | 792 | |
795 | ||
793 | TIMER_CALLBACK_MEMBER(pcw_state::pcw_pins_callback) | |
796 | 794 | { |
797 | pcw_state *state = machine.driver_data<pcw_state>(); | |
798 | 795 | |
799 | pcw_printer_fire_pins(machine,state->m_printer_pins); | |
800 | state->m_printer_p2 |= 0x40; | |
796 | pcw_printer_fire_pins(machine(),m_printer_pins); | |
797 | m_printer_p2 |= 0x40; | |
801 | 798 | } |
802 | 799 | |
803 | 800 | READ8_MEMBER(pcw_state::mcu_printer_p1_r) |
r18113 | r18114 | |
1034 | 1031 | ADDRESS_MAP_END |
1035 | 1032 | |
1036 | 1033 | |
1037 | ||
1034 | TIMER_CALLBACK_MEMBER(pcw_state::setup_beep) | |
1038 | 1035 | { |
1039 | device_t *speaker = machine.device(BEEPER_TAG); | |
1036 | device_t *speaker = machine().device(BEEPER_TAG); | |
1040 | 1037 | beep_set_state(speaker, 0); |
1041 | 1038 | beep_set_frequency(speaker, 3750); |
1042 | 1039 | } |
r18113 | r18114 | |
1096 | 1093 | m_roller_ram_offset = 0; |
1097 | 1094 | |
1098 | 1095 | /* timer interrupt */ |
1099 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep)); | |
1096 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(pcw_state::setup_beep),this)); | |
1100 | 1097 | |
1101 | m_prn_stepper = machine().scheduler().timer_alloc(FUNC(pcw_stepper_callback)); | |
1102 | m_prn_pins = machine().scheduler().timer_alloc(FUNC(pcw_pins_callback)); | |
1098 | m_prn_stepper = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pcw_state::pcw_stepper_callback),this)); | |
1099 | m_prn_pins = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pcw_state::pcw_pins_callback),this)); | |
1103 | 1100 | } |
1104 | 1101 | |
1105 | 1102 |
r18113 | r18114 | |
---|---|---|
903 | 903 | |
904 | 904 | /* Driver Initialization */ |
905 | 905 | |
906 | ||
906 | TIMER_CALLBACK_MEMBER(sb2m600_state::setup_beep) | |
907 | 907 | { |
908 | device_t *speaker = machine.device(BEEPER_TAG); | |
908 | device_t *speaker = machine().device(BEEPER_TAG); | |
909 | 909 | beep_set_state(speaker, 0); |
910 | 910 | beep_set_frequency(speaker, 300); |
911 | 911 | } |
912 | 912 | |
913 | 913 | DRIVER_INIT_MEMBER(c1p_state,c1p) |
914 | 914 | { |
915 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep)); | |
915 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(sb2m600_state::setup_beep),this)); | |
916 | 916 | } |
917 | 917 | |
918 | 918 |
r18113 | r18114 | |
---|---|---|
900 | 900 | |
901 | 901 | /* Driver Initialization */ |
902 | 902 | |
903 | ||
903 | TIMER_CALLBACK_MEMBER(tmc1800_state::setup_beep) | |
904 | 904 | { |
905 | device_t *speaker = machine.device(BEEPER_TAG); | |
905 | device_t *speaker = machine().device(BEEPER_TAG); | |
906 | 906 | beep_set_state(speaker, 0); |
907 | 907 | beep_set_frequency( speaker, 0 ); |
908 | 908 | } |
909 | 909 | |
910 | 910 | DRIVER_INIT_MEMBER(tmc1800_state,tmc1800) |
911 | 911 | { |
912 | machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep)); | |
912 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(tmc1800_state::setup_beep),this)); | |
913 | 913 | } |
914 | 914 | |
915 | 915 | /* System Drivers */ |
r18113 | r18114 | |
---|---|---|
1305 | 1305 | } |
1306 | 1306 | } |
1307 | 1307 | |
1308 | ||
1308 | TIMER_CALLBACK_MEMBER(towns_state::towns_cd_status_ready) | |
1309 | 1309 | { |
1310 | towns_state* state = machine.driver_data<towns_state>(); | |
1311 | state->m_towns_cd.status |= 0x02; // status read request | |
1312 | state->m_towns_cd.status |= 0x01; // ready | |
1313 | state->m_towns_cd.cmd_status_ptr = 0; | |
1314 | towns_cdrom_set_irq((running_machine&)machine,TOWNS_CD_IRQ_MPU,1); | |
1310 | m_towns_cd.status |= 0x02; // status read request | |
1311 | m_towns_cd.status |= 0x01; // ready | |
1312 | m_towns_cd.cmd_status_ptr = 0; | |
1313 | towns_cdrom_set_irq((running_machine&)machine(),TOWNS_CD_IRQ_MPU,1); | |
1315 | 1314 | } |
1316 | 1315 | |
1317 | 1316 | static void towns_cd_set_status(running_machine &machine, UINT8 st0, UINT8 st1, UINT8 st2, UINT8 st3) |
r18113 | r18114 | |
1322 | 1321 | state->m_towns_cd.cmd_status[2] = st2; |
1323 | 1322 | state->m_towns_cd.cmd_status[3] = st3; |
1324 | 1323 | // wait a bit |
1325 | machine.scheduler().timer_set(attotime::from_msec(1), FUNC(towns_cd_status_ready), 0, &machine); | |
1324 | machine.scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(towns_state::towns_cd_status_ready),state), 0, &machine); | |
1326 | 1325 | } |
1327 | 1326 | |
1328 | 1327 | static UINT8 towns_cd_get_track(running_machine &machine) |
r18113 | r18114 | |
1341 | 1340 | return track; |
1342 | 1341 | } |
1343 | 1342 | |
1344 | ||
1343 | TIMER_CALLBACK_MEMBER(towns_state::towns_cdrom_read_byte) | |
1345 | 1344 | { |
1346 | 1345 | device_t* device = (device_t* )ptr; |
1347 | towns_state* state = machine.driver_data<towns_state>(); | |
1348 | 1346 | int masked; |
1349 | 1347 | // TODO: support software transfers, for now DMA is assumed. |
1350 | 1348 | |
1351 | if( | |
1349 | if(m_towns_cd.buffer_ptr < 0) // transfer has ended | |
1352 | 1350 | return; |
1353 | 1351 | |
1354 | 1352 | masked = upd71071_dmarq(device,param,3); // CD-ROM controller uses DMA1 channel 3 |
1355 | // logerror("DMARQ: param=%i ret=%i bufferptr=%i\n",param,masked, | |
1353 | // logerror("DMARQ: param=%i ret=%i bufferptr=%i\n",param,masked,m_towns_cd.buffer_ptr); | |
1356 | 1354 | if(param != 0) |
1357 | 1355 | { |
1358 | | |
1356 | m_towns_cd.read_timer->adjust(attotime::from_hz(300000)); | |
1359 | 1357 | } |
1360 | 1358 | else |
1361 | 1359 | { |
1362 | 1360 | if(masked != 0) // check if the DMA channel is masked |
1363 | 1361 | { |
1364 | | |
1362 | m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); | |
1365 | 1363 | return; |
1366 | 1364 | } |
1367 | if(state->m_towns_cd.buffer_ptr < 2048) | |
1368 | state->m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); | |
1365 | if(m_towns_cd.buffer_ptr < 2048) | |
1366 | m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); | |
1369 | 1367 | else |
1370 | 1368 | { // end of transfer |
1371 | state->m_towns_cd.status &= ~0x10; // no longer transferring by DMA | |
1372 | state->m_towns_cd.status &= ~0x20; // no longer transferring by software | |
1373 | logerror("DMA1: end of transfer (LBA=%08x)\n",state->m_towns_cd.lba_current); | |
1374 | if(state->m_towns_cd.lba_current >= state->m_towns_cd.lba_last) | |
1369 | m_towns_cd.status &= ~0x10; // no longer transferring by DMA | |
1370 | m_towns_cd.status &= ~0x20; // no longer transferring by software | |
1371 | logerror("DMA1: end of transfer (LBA=%08x)\n",m_towns_cd.lba_current); | |
1372 | if(m_towns_cd.lba_current >= m_towns_cd.lba_last) | |
1375 | 1373 | { |
1376 | | |
1374 | m_towns_cd.extra_status = 0; | |
1377 | 1375 | towns_cd_set_status(device->machine(),0x06,0x00,0x00,0x00); |
1378 | 1376 | towns_cdrom_set_irq(device->machine(),TOWNS_CD_IRQ_DMA,1); |
1379 | state->m_towns_cd.buffer_ptr = -1; | |
1380 | state->m_towns_cd.status |= 0x01; // ready | |
1377 | m_towns_cd.buffer_ptr = -1; | |
1378 | m_towns_cd.status |= 0x01; // ready | |
1381 | 1379 | } |
1382 | 1380 | else |
1383 | 1381 | { |
1384 | | |
1382 | m_towns_cd.extra_status = 0; | |
1385 | 1383 | towns_cd_set_status(device->machine(),0x22,0x00,0x00,0x00); |
1386 | 1384 | towns_cdrom_set_irq(device->machine(),TOWNS_CD_IRQ_DMA,1); |
1387 | cdrom_read_data(state->m_cdrom->get_cdrom_file(),++state->m_towns_cd.lba_current,state->m_towns_cd.buffer,CD_TRACK_MODE1); | |
1388 | state->m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); | |
1389 | state->m_towns_cd.buffer_ptr = -1; | |
1385 | cdrom_read_data(m_cdrom->get_cdrom_file(),++m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1); | |
1386 | m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); | |
1387 | m_towns_cd.buffer_ptr = -1; | |
1390 | 1388 | } |
1391 | 1389 | } |
1392 | 1390 | } |
r18113 | r18114 | |
1482 | 1480 | } |
1483 | 1481 | } |
1484 | 1482 | |
1485 | ||
1483 | TIMER_CALLBACK_MEMBER(towns_state::towns_delay_cdda) | |
1486 | 1484 | { |
1487 | 1485 | towns_cdrom_play_cdda((cdrom_image_device*)ptr); |
1488 | 1486 | } |
r18113 | r18114 | |
1526 | 1524 | break; |
1527 | 1525 | case 0x04: // Play Audio Track |
1528 | 1526 | logerror("CD: Command 0x04: PLAY CD-DA\n"); |
1529 | device->machine().scheduler().timer_set(attotime::from_msec(1), FUNC(towns_delay_cdda), 0, device); | |
1527 | device->machine().scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(towns_state::towns_delay_cdda),state), 0, device); | |
1530 | 1528 | break; |
1531 | 1529 | case 0x05: // Read TOC |
1532 | 1530 | logerror("CD: Command 0x05: READ TOC\n"); |
r18113 | r18114 | |
2456 | 2454 | m_towns_intervaltimer2 = timer_alloc(TIMER_INTERVAL2); |
2457 | 2455 | |
2458 | 2456 | // CD-ROM init |
2459 | m_towns_cd.read_timer = machine().scheduler().timer_alloc(FUNC(towns_cdrom_read_byte), (void*)machine().device("dma_1")); | |
2457 | m_towns_cd.read_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(towns_state::towns_cdrom_read_byte),this), (void*)machine().device("dma_1")); | |
2460 | 2458 | |
2461 | 2459 | machine().device("maincpu")->execute().set_irq_acknowledge_callback(towns_irq_callback); |
2462 | 2460 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_ram(0x100000,machine().device<ram_device>(RAM_TAG)->size()-1,0xffffffff,0,NULL); |
r18113 | r18114 | |
---|---|---|
2432 | 2432 | } |
2433 | 2433 | } |
2434 | 2434 | |
2435 | TIMER_CALLBACK(x1_rtc_increment) | |
2435 | TIMER_CALLBACK_MEMBER(x1_state::x1_rtc_increment) | |
2436 | 2436 | { |
2437 | x1_state *state = machine.driver_data<x1_state>(); | |
2438 | 2437 | static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; |
2439 | 2438 | |
2440 | | |
2439 | m_rtc.sec++; | |
2441 | 2440 | |
2442 | if((state->m_rtc.sec & 0x0f) >= 0x0a) { state->m_rtc.sec+=0x10; state->m_rtc.sec&=0xf0; } | |
2443 | if((state->m_rtc.sec & 0xf0) >= 0x60) { state->m_rtc.min++; state->m_rtc.sec = 0; } | |
2444 | if((state->m_rtc.min & 0x0f) >= 0x0a) { state->m_rtc.min+=0x10; state->m_rtc.min&=0xf0; } | |
2445 | if((state->m_rtc.min & 0xf0) >= 0x60) { state->m_rtc.hour++; state->m_rtc.min = 0; } | |
2446 | if((state->m_rtc.hour & 0x0f) >= 0x0a) { state->m_rtc.hour+=0x10; state->m_rtc.hour&=0xf0; } | |
2447 | if((state->m_rtc.hour & 0xff) >= 0x24) { state->m_rtc.day++; state->m_rtc.wday++; state->m_rtc.hour = 0; } | |
2448 | if((state->m_rtc.wday & 0x0f) >= 0x07) { state->m_rtc.wday = 0; } | |
2449 | if((state->m_rtc.day & 0x0f) >= 0x0a) { state->m_rtc.day+=0x10; state->m_rtc.day&=0xf0; } | |
2441 | if((m_rtc.sec & 0x0f) >= 0x0a) { m_rtc.sec+=0x10; m_rtc.sec&=0xf0; } | |
2442 | if((m_rtc.sec & 0xf0) >= 0x60) { m_rtc.min++; m_rtc.sec = 0; } | |
2443 | if((m_rtc.min & 0x0f) >= 0x0a) { m_rtc.min+=0x10; m_rtc.min&=0xf0; } | |
2444 | if((m_rtc.min & 0xf0) >= 0x60) { m_rtc.hour++; m_rtc.min = 0; } | |
2445 | if((m_rtc.hour & 0x0f) >= 0x0a) { m_rtc.hour+=0x10; m_rtc.hour&=0xf0; } | |
2446 | if((m_rtc.hour & 0xff) >= 0x24) { m_rtc.day++; m_rtc.wday++; m_rtc.hour = 0; } | |
2447 | if((m_rtc.wday & 0x0f) >= 0x07) { m_rtc.wday = 0; } | |
2448 | if((m_rtc.day & 0x0f) >= 0x0a) { m_rtc.day+=0x10; m_rtc.day&=0xf0; } | |
2450 | 2449 | /* FIXME: very crude leap year support (i.e. it treats the RTC to be with a 2000-2099 timeline), dunno how the real x1 supports this, |
2451 | 2450 | maybe it just have a 1980-1999 timeline since year 0x00 shows as a XX on display */ |
2452 | if((( | |
2451 | if(((m_rtc.year % 4) == 0) && m_rtc.month == 2) | |
2453 | 2452 | { |
2454 | if((state->m_rtc.day & 0xff) >= dpm[state->m_rtc.month-1]+1+1) | |
2455 | { state->m_rtc.month++; state->m_rtc.day = 0x01; } | |
2453 | if((m_rtc.day & 0xff) >= dpm[m_rtc.month-1]+1+1) | |
2454 | { m_rtc.month++; m_rtc.day = 0x01; } | |
2456 | 2455 | } |
2457 | else if((state->m_rtc.day & 0xff) >= dpm[state->m_rtc.month-1]+1){ state->m_rtc.month++; state->m_rtc.day = 0x01; } | |
2458 | if(state->m_rtc.month > 12) { state->m_rtc.year++; state->m_rtc.month = 0x01; } | |
2459 | if((state->m_rtc.year & 0x0f) >= 0x0a) { state->m_rtc.year+=0x10; state->m_rtc.year&=0xf0; } | |
2460 | if((state->m_rtc.year & 0xf0) >= 0xa0) { state->m_rtc.year = 0; } //roll over | |
2456 | else if((m_rtc.day & 0xff) >= dpm[m_rtc.month-1]+1){ m_rtc.month++; m_rtc.day = 0x01; } | |
2457 | if(m_rtc.month > 12) { m_rtc.year++; m_rtc.month = 0x01; } | |
2458 | if((m_rtc.year & 0x0f) >= 0x0a) { m_rtc.year+=0x10; m_rtc.year&=0xf0; } | |
2459 | if((m_rtc.year & 0xf0) >= 0xa0) { m_rtc.year = 0; } //roll over | |
2461 | 2460 | } |
2462 | 2461 | |
2463 | 2462 | MACHINE_RESET_MEMBER(x1_state,x1) |
r18113 | r18114 | |
2530 | 2529 | m_rtc.min = ((systime.local_time.minute / 10)<<4) | ((systime.local_time.minute % 10) & 0xf); |
2531 | 2530 | m_rtc.sec = ((systime.local_time.second / 10)<<4) | ((systime.local_time.second % 10) & 0xf); |
2532 | 2531 | |
2533 | m_rtc_timer = machine().scheduler().timer_alloc(FUNC(x1_rtc_increment)); | |
2532 | m_rtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x1_state::x1_rtc_increment),this)); | |
2534 | 2533 | } |
2535 | 2534 | } |
2536 | 2535 |
r18113 | r18114 | |
---|---|---|
177 | 177 | state->m_mfp.current_irq = -1; // No current interrupt |
178 | 178 | |
179 | 179 | #if 0 |
180 | mfp_timer[0] = machine.scheduler().timer_alloc(FUNC(mfp_timer_a_callback)); | |
181 | mfp_timer[1] = machine.scheduler().timer_alloc(FUNC(mfp_timer_b_callback)); | |
182 | mfp_timer[2] = machine.scheduler().timer_alloc(FUNC(mfp_timer_c_callback)); | |
183 | mfp_timer[3] = machine.scheduler().timer_alloc(FUNC(mfp_timer_d_callback)); | |
184 | mfp_irq = machine.scheduler().timer_alloc(FUNC(mfp_update_irq)); | |
180 | mfp_timer[0] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::mfp_timer_a_callback),this)); | |
181 | mfp_timer[1] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::mfp_timer_b_callback),this)); | |
182 | mfp_timer[2] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::mfp_timer_c_callback),this)); | |
183 | mfp_timer[3] = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::mfp_timer_d_callback),this)); | |
184 | mfp_irq = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::mfp_update_irq),this)); | |
185 | 185 | mfp_irq->adjust(attotime::zero, 0, attotime::from_usec(32)); |
186 | 186 | #endif |
187 | 187 | } |
188 | 188 | |
189 | 189 | #ifdef UNUSED_FUNCTION |
190 | TIMER_CALLBACK(mfp_update_irq) | |
190 | TIMER_CALLBACK_MEMBER(x68k_state::mfp_update_irq) | |
191 | 191 | { |
192 | x68k_state *state = machine.driver_data<x68k_state>(); | |
193 | 192 | int x; |
194 | 193 | |
195 | if(( | |
194 | if((m_ioc.irqstatus & 0xc0) != 0) | |
196 | 195 | return; |
197 | 196 | |
198 | 197 | // check for pending IRQs, in priority order |
199 | if( | |
198 | if(m_mfp.ipra != 0) | |
200 | 199 | { |
201 | 200 | for(x=7;x>=0;x--) |
202 | 201 | { |
203 | if(( | |
202 | if((m_mfp.ipra & (1 << x)) && (m_mfp.imra & (1 << x))) | |
204 | 203 | { |
205 | state->m_current_irq_line = state->m_mfp.irqline; | |
206 | state->m_mfp.current_irq = x + 8; | |
204 | m_current_irq_line = m_mfp.irqline; | |
205 | m_mfp.current_irq = x + 8; | |
207 | 206 | // assert IRQ line |
208 | // if( | |
207 | // if(m_mfp.iera & (1 << x)) | |
209 | 208 | { |
210 | state->m_current_vector[6] = (state->m_mfp.vr & 0xf0) | (x+8); | |
211 | machine.device("maincpu")->execute().set_input_line_and_vector(state->m_mfp.irqline,ASSERT_LINE,(state->m_mfp.vr & 0xf0) | (x + 8)); | |
212 | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(state->m_mfp.vr & 0xf0) | (x+8),state->m_mfp.irqline); | |
209 | m_current_vector[6] = (m_mfp.vr & 0xf0) | (x+8); | |
210 | machine().device("maincpu")->execute().set_input_line_and_vector(m_mfp.irqline,ASSERT_LINE,(m_mfp.vr & 0xf0) | (x + 8)); | |
211 | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(m_mfp.vr & 0xf0) | (x+8),m_mfp.irqline); | |
213 | 212 | return; // one at a time only |
214 | 213 | } |
215 | 214 | } |
216 | 215 | } |
217 | 216 | } |
218 | if( | |
217 | if(m_mfp.iprb != 0) | |
219 | 218 | { |
220 | 219 | for(x=7;x>=0;x--) |
221 | 220 | { |
222 | if(( | |
221 | if((m_mfp.iprb & (1 << x)) && (m_mfp.imrb & (1 << x))) | |
223 | 222 | { |
224 | state->m_current_irq_line = state->m_mfp.irqline; | |
225 | state->m_mfp.current_irq = x; | |
223 | m_current_irq_line = m_mfp.irqline; | |
224 | m_mfp.current_irq = x; | |
226 | 225 | // assert IRQ line |
227 | // if( | |
226 | // if(m_mfp.ierb & (1 << x)) | |
228 | 227 | { |
229 | state->m_current_vector[6] = (state->m_mfp.vr & 0xf0) | x; | |
230 | machine.device("maincpu")->execute().set_input_line_and_vector(state->m_mfp.irqline,ASSERT_LINE,(state->m_mfp.vr & 0xf0) | x); | |
231 | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(state->m_mfp.vr & 0xf0) | x,state->m_mfp.irqline); | |
228 | m_current_vector[6] = (m_mfp.vr & 0xf0) | x; | |
229 | machine().device("maincpu")->execute().set_input_line_and_vector(m_mfp.irqline,ASSERT_LINE,(m_mfp.vr & 0xf0) | x); | |
230 | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(m_mfp.vr & 0xf0) | x,m_mfp.irqline); | |
232 | 231 | return; // one at a time only |
233 | 232 | } |
234 | 233 | } |
r18113 | r18114 | |
262 | 261 | |
263 | 262 | } |
264 | 263 | |
265 | TIMER_CALLBACK(mfp_timer_a_callback) | |
264 | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_a_callback) | |
266 | 265 | { |
267 | x68k_state *state = machine.driver_data<x68k_state>(); | |
268 | state->m_mfp.timer[0].counter--; | |
269 | if(state->m_mfp.timer[0].counter == 0) | |
266 | m_mfp.timer[0].counter--; | |
267 | if(m_mfp.timer[0].counter == 0) | |
270 | 268 | { |
271 | | |
269 | m_mfp.timer[0].counter = m_mfp.tadr; | |
272 | 270 | mfp_trigger_irq(MFP_IRQ_TIMERA); |
273 | 271 | } |
274 | 272 | } |
275 | 273 | |
276 | TIMER_CALLBACK(mfp_timer_b_callback) | |
274 | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_b_callback) | |
277 | 275 | { |
278 | x68k_state *state = machine.driver_data<x68k_state>(); | |
279 | state->m_mfp.timer[1].counter--; | |
280 | if(state->m_mfp.timer[1].counter == 0) | |
276 | m_mfp.timer[1].counter--; | |
277 | if(m_mfp.timer[1].counter == 0) | |
281 | 278 | { |
282 | | |
279 | m_mfp.timer[1].counter = m_mfp.tbdr; | |
283 | 280 | mfp_trigger_irq(MFP_IRQ_TIMERB); |
284 | 281 | } |
285 | 282 | } |
286 | 283 | |
287 | TIMER_CALLBACK(mfp_timer_c_callback) | |
284 | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_c_callback) | |
288 | 285 | { |
289 | x68k_state *state = machine.driver_data<x68k_state>(); | |
290 | state->m_mfp.timer[2].counter--; | |
291 | if(state->m_mfp.timer[2].counter == 0) | |
286 | m_mfp.timer[2].counter--; | |
287 | if(m_mfp.timer[2].counter == 0) | |
292 | 288 | { |
293 | | |
289 | m_mfp.timer[2].counter = m_mfp.tcdr; | |
294 | 290 | mfp_trigger_irq(MFP_IRQ_TIMERC); |
295 | 291 | } |
296 | 292 | } |
297 | 293 | |
298 | TIMER_CALLBACK(mfp_timer_d_callback) | |
294 | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_d_callback) | |
299 | 295 | { |
300 | x68k_state *state = machine.driver_data<x68k_state>(); | |
301 | state->m_mfp.timer[3].counter--; | |
302 | if(state->m_mfp.timer[3].counter == 0) | |
296 | m_mfp.timer[3].counter--; | |
297 | if(m_mfp.timer[3].counter == 0) | |
303 | 298 | { |
304 | | |
299 | m_mfp.timer[3].counter = m_mfp.tddr; | |
305 | 300 | mfp_trigger_irq(MFP_IRQ_TIMERD); |
306 | 301 | } |
307 | 302 | } |
r18113 | r18114 | |
322 | 317 | #endif |
323 | 318 | |
324 | 319 | // LED timer callback |
325 | ||
320 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_led_callback) | |
326 | 321 | { |
327 | x68k_state *state = machine.driver_data<x68k_state>(); | |
328 | 322 | int drive; |
329 | if(state->m_led_state == 0) | |
330 | state->m_led_state = 1; | |
323 | if(m_led_state == 0) | |
324 | m_led_state = 1; | |
331 | 325 | else |
332 | state->m_led_state = 0; | |
333 | if(state->m_led_state == 1) | |
326 | m_led_state = 0; | |
327 | if(m_led_state == 1) | |
334 | 328 | { |
335 | 329 | for(drive=0;drive<4;drive++) |
336 | output_set_indexed_value("ctrl_drv",drive, | |
330 | output_set_indexed_value("ctrl_drv",drive,m_fdc.led_ctrl[drive] ? 0 : 1); | |
337 | 331 | } |
338 | 332 | else |
339 | 333 | { |
r18113 | r18114 | |
470 | 464 | } |
471 | 465 | } |
472 | 466 | |
473 | ||
467 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_keyboard_poll) | |
474 | 468 | { |
475 | x68k_state *state = machine.driver_data<x68k_state>(); | |
476 | 469 | int x; |
477 | 470 | static const char *const keynames[] = { "key1", "key2", "key3", "key4" }; |
478 | 471 | |
479 | 472 | for(x=0;x<0x80;x++) |
480 | 473 | { |
481 | 474 | // adjust delay/repeat timers |
482 | if( | |
475 | if(m_keyboard.keytime[x] > 0) | |
483 | 476 | { |
484 | | |
477 | m_keyboard.keytime[x] -= 5; | |
485 | 478 | } |
486 | if(!(machine.root_device().ioport(keynames[x / 32])->read() & (1 << (x % 32)))) | |
479 | if(!(machine().root_device().ioport(keynames[x / 32])->read() & (1 << (x % 32)))) | |
487 | 480 | { |
488 | if( | |
481 | if(m_keyboard.keyon[x] != 0) | |
489 | 482 | { |
490 | x68k_keyboard_push_scancode(machine,0x80 + x); | |
491 | state->m_keyboard.keytime[x] = 0; | |
492 | state->m_keyboard.keyon[x] = 0; | |
493 | state->m_keyboard.last_pressed = 0; | |
483 | x68k_keyboard_push_scancode(machine(),0x80 + x); | |
484 | m_keyboard.keytime[x] = 0; | |
485 | m_keyboard.keyon[x] = 0; | |
486 | m_keyboard.last_pressed = 0; | |
494 | 487 | logerror("KB: Released key 0x%02x\n",x); |
495 | 488 | } |
496 | 489 | } |
497 | 490 | // check to see if a key is being held |
498 | if( | |
491 | if(m_keyboard.keyon[x] != 0 && m_keyboard.keytime[x] == 0 && m_keyboard.last_pressed == x) | |
499 | 492 | { |
500 | if(machine.root_device().ioport(keynames[ | |
493 | if(machine().root_device().ioport(keynames[m_keyboard.last_pressed / 32])->read() & (1 << (m_keyboard.last_pressed % 32))) | |
501 | 494 | { |
502 | x68k_keyboard_push_scancode(machine,state->m_keyboard.last_pressed); | |
503 | state->m_keyboard.keytime[state->m_keyboard.last_pressed] = (state->m_keyboard.repeat^2)*5+30; | |
504 | logerror("KB: Holding key 0x%02x\n",state->m_keyboard.last_pressed); | |
495 | x68k_keyboard_push_scancode(machine(),m_keyboard.last_pressed); | |
496 | m_keyboard.keytime[m_keyboard.last_pressed] = (m_keyboard.repeat^2)*5+30; | |
497 | logerror("KB: Holding key 0x%02x\n",m_keyboard.last_pressed); | |
505 | 498 | } |
506 | 499 | } |
507 | if((machine.root_device().ioport(keynames[x / 32])->read() & (1 << (x % 32)))) | |
500 | if((machine().root_device().ioport(keynames[x / 32])->read() & (1 << (x % 32)))) | |
508 | 501 | { |
509 | if( | |
502 | if(m_keyboard.keyon[x] == 0) | |
510 | 503 | { |
511 | x68k_keyboard_push_scancode(machine,x); | |
512 | state->m_keyboard.keytime[x] = state->m_keyboard.delay * 100 + 200; | |
513 | state->m_keyboard.keyon[x] = 1; | |
514 | state->m_keyboard.last_pressed = x; | |
504 | x68k_keyboard_push_scancode(machine(),x); | |
505 | m_keyboard.keytime[x] = m_keyboard.delay * 100 + 200; | |
506 | m_keyboard.keyon[x] = 1; | |
507 | m_keyboard.last_pressed = x; | |
515 | 508 | logerror("KB: Pushed key 0x%02x\n",x); |
516 | 509 | } |
517 | 510 | } |
r18113 | r18114 | |
634 | 627 | state->m_scc_prev = scc->get_reg_b(5) & 0x02; |
635 | 628 | } |
636 | 629 | |
637 | ||
630 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_scc_ack) | |
638 | 631 | { |
639 | x68k_state *state = machine.driver_data<x68k_state>(); | |
640 | scc8530_t *scc = machine.device<scc8530_t>("scc"); | |
641 | if(state->m_mouse.bufferempty != 0) // nothing to do if the mouse data buffer is empty | |
632 | scc8530_t *scc = machine().device<scc8530_t>("scc"); | |
633 | if(m_mouse.bufferempty != 0) // nothing to do if the mouse data buffer is empty | |
642 | 634 | return; |
643 | 635 | |
644 | // if(( | |
636 | // if((m_ioc.irqstatus & 0xc0) != 0) | |
645 | 637 | // return; |
646 | 638 | |
647 | 639 | // hard-code the IRQ vector for now, until the SCC code is more complete |
r18113 | r18114 | |
651 | 643 | { |
652 | 644 | if(scc->get_reg_b(5) & 0x02) // RTS signal |
653 | 645 | { |
654 | state->m_mouse.irqactive = 1; | |
655 | state->m_current_vector[5] = 0x54; | |
656 | state->m_current_irq_line = 5; | |
657 | machine.device("maincpu")->execute().set_input_line_and_vector(5,ASSERT_LINE,0x54); | |
646 | m_mouse.irqactive = 1; | |
647 | m_current_vector[5] = 0x54; | |
648 | m_current_irq_line = 5; | |
649 | machine().device("maincpu")->execute().set_input_line_and_vector(5,ASSERT_LINE,0x54); | |
658 | 650 | } |
659 | 651 | } |
660 | 652 | } |
r18113 | r18114 | |
725 | 717 | } |
726 | 718 | |
727 | 719 | // Megadrive 6 button gamepad |
728 | ||
720 | TIMER_CALLBACK_MEMBER(x68k_state::md_6button_port1_timeout) | |
729 | 721 | { |
730 | x68k_state *state = machine.driver_data<x68k_state>(); | |
731 | state->m_mdctrl.seq1 = 0; | |
722 | m_mdctrl.seq1 = 0; | |
732 | 723 | } |
733 | 724 | |
734 | ||
725 | TIMER_CALLBACK_MEMBER(x68k_state::md_6button_port2_timeout) | |
735 | 726 | { |
736 | x68k_state *state = machine.driver_data<x68k_state>(); | |
737 | state->m_mdctrl.seq2 = 0; | |
727 | m_mdctrl.seq2 = 0; | |
738 | 728 | } |
739 | 729 | |
740 | 730 | static void md_6button_init(running_machine &machine) |
741 | 731 | { |
742 | 732 | x68k_state *state = machine.driver_data<x68k_state>(); |
743 | state->m_mdctrl.io_timeout1 = machine.scheduler().timer_alloc(FUNC(md_6button_port1_timeout)); | |
744 | state->m_mdctrl.io_timeout2 = machine.scheduler().timer_alloc(FUNC(md_6button_port2_timeout)); | |
733 | state->m_mdctrl.io_timeout1 = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::md_6button_port1_timeout),state)); | |
734 | state->m_mdctrl.io_timeout2 = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::md_6button_port2_timeout),state)); | |
745 | 735 | } |
746 | 736 | |
747 | 737 | static UINT8 md_6button_r(device_t* device, int port) |
r18113 | r18114 | |
1689 | 1679 | logerror("SYS: Enhanced Supervisor area set (from %iMB): 0x%02x\n",(offset + 1) * 2,data & 0xff); |
1690 | 1680 | } |
1691 | 1681 | |
1692 | ||
1682 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_bus_error) | |
1693 | 1683 | { |
1694 | 1684 | int val = param; |
1695 | 1685 | int v; |
1696 | UINT8 *ram = machine.device<ram_device>(RAM_TAG)->pointer(); | |
1686 | UINT8 *ram = machine().device<ram_device>(RAM_TAG)->pointer(); | |
1697 | 1687 | |
1698 | if(strcmp(machine.system().name,"x68030") == 0) | |
1688 | if(strcmp(machine().system().name,"x68030") == 0) | |
1699 | 1689 | v = 0x0b; |
1700 | 1690 | else |
1701 | 1691 | v = 0x09; |
1702 | 1692 | if(ram[v] != 0x02) // normal vector for bus errors points to 02FF0540 |
1703 | 1693 | { |
1704 | machine.device("maincpu")->execute().set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); | |
1705 | machine.device("maincpu")->execute().set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); | |
1694 | machine().device("maincpu")->execute().set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); | |
1695 | machine().device("maincpu")->execute().set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); | |
1706 | 1696 | popmessage("Bus error: Unused RAM access [%08x]", val); |
1707 | 1697 | } |
1708 | 1698 | } |
r18113 | r18114 | |
1720 | 1710 | offset *= 2; |
1721 | 1711 | if(ACCESSING_BITS_0_7) |
1722 | 1712 | offset++; |
1723 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), FUNC(x68k_bus_error), 0xbffffc+offset); | |
1713 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), 0xbffffc+offset); | |
1724 | 1714 | } |
1725 | 1715 | return 0xff; |
1726 | 1716 | } |
r18113 | r18114 | |
1738 | 1728 | offset *= 2; |
1739 | 1729 | if(ACCESSING_BITS_0_7) |
1740 | 1730 | offset++; |
1741 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), FUNC(x68k_bus_error), 0xbffffc+offset); | |
1731 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), 0xbffffc+offset); | |
1742 | 1732 | } |
1743 | 1733 | } |
1744 | 1734 | |
r18113 | r18114 | |
1755 | 1745 | offset *= 2; |
1756 | 1746 | if(ACCESSING_BITS_0_7) |
1757 | 1747 | offset++; |
1758 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), FUNC(x68k_bus_error), offset); | |
1748 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), offset); | |
1759 | 1749 | } |
1760 | 1750 | return 0xff; |
1761 | 1751 | } |
r18113 | r18114 | |
1773 | 1763 | offset *= 2; |
1774 | 1764 | if(ACCESSING_BITS_0_7) |
1775 | 1765 | offset++; |
1776 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), FUNC(x68k_bus_error), offset); | |
1766 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), offset); | |
1777 | 1767 | } |
1778 | 1768 | } |
1779 | 1769 | |
r18113 | r18114 | |
1788 | 1778 | offset *= 2; |
1789 | 1779 | if(ACCESSING_BITS_0_7) |
1790 | 1780 | offset++; |
1791 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(16), FUNC(x68k_bus_error), 0xeafa00+offset); | |
1781 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(16), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), 0xeafa00+offset); | |
1792 | 1782 | // machine.device("maincpu")->execute().set_input_line_and_vector(2,ASSERT_LINE,state->m_current_vector[2]); |
1793 | 1783 | } |
1794 | 1784 | return 0xffff; |
r18113 | r18114 | |
1805 | 1795 | offset *= 2; |
1806 | 1796 | if(ACCESSING_BITS_0_7) |
1807 | 1797 | offset++; |
1808 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(16), FUNC(x68k_bus_error), 0xeafa00+offset); | |
1798 | space.machine().scheduler().timer_set(space.machine().device<cpu_device>("maincpu")->cycles_to_attotime(16), timer_expired_delegate(FUNC(x68k_state::x68k_bus_error),state), 0xeafa00+offset); | |
1809 | 1799 | // machine.device("maincpu")->execute().set_input_line_and_vector(2,ASSERT_LINE,state->m_current_vector[2]); |
1810 | 1800 | } |
1811 | 1801 | } |
r18113 | r18114 | |
2482 | 2472 | state->m_fdc.disk_inserted[floppy_get_drive(&image.device())] = 0; |
2483 | 2473 | } |
2484 | 2474 | |
2485 | ||
2475 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_net_irq) | |
2486 | 2476 | { |
2487 | x68k_state *state = machine.driver_data<x68k_state>(); | |
2488 | 2477 | |
2489 | state->m_current_vector[2] = 0xf9; | |
2490 | state->m_current_irq_line = 2; | |
2491 | machine.device("maincpu")->execute().set_input_line_and_vector(2,ASSERT_LINE,state->m_current_vector[2]); | |
2478 | m_current_vector[2] = 0xf9; | |
2479 | m_current_irq_line = 2; | |
2480 | machine().device("maincpu")->execute().set_input_line_and_vector(2,ASSERT_LINE,m_current_vector[2]); | |
2492 | 2481 | } |
2493 | 2482 | |
2494 | 2483 | static void x68k_irq2_line(device_t* device,int state) |
r18113 | r18114 | |
2708 | 2697 | // init keyboard |
2709 | 2698 | m_keyboard.delay = 500; // 3*100+200 |
2710 | 2699 | m_keyboard.repeat = 110; // 4^2*5+30 |
2711 | m_kb_timer = machine().scheduler().timer_alloc(FUNC(x68k_keyboard_poll)); | |
2712 | m_scanline_timer = machine().scheduler().timer_alloc(FUNC(x68k_hsync)); | |
2713 | m_raster_irq = machine().scheduler().timer_alloc(FUNC(x68k_crtc_raster_irq)); | |
2714 | m_vblank_irq = machine().scheduler().timer_alloc(FUNC(x68k_crtc_vblank_irq)); | |
2715 | m_mouse_timer = machine().scheduler().timer_alloc(FUNC(x68k_scc_ack)); | |
2716 | m_led_timer = machine().scheduler().timer_alloc(FUNC(x68k_led_callback)); | |
2717 | m_net_timer = machine().scheduler().timer_alloc(FUNC(x68k_net_irq)); | |
2700 | m_kb_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_keyboard_poll),this)); | |
2701 | m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_hsync),this)); | |
2702 | m_raster_irq = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_crtc_raster_irq),this)); | |
2703 | m_vblank_irq = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_crtc_vblank_irq),this)); | |
2704 | m_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_scc_ack),this)); | |
2705 | m_led_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_led_callback),this)); | |
2706 | m_net_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(x68k_state::x68k_net_irq),this)); | |
2718 | 2707 | |
2719 | 2708 | // Initialise timers for 6-button MD controllers |
2720 | 2709 | md_6button_init(machine()); |
Previous | 199869 Revisions | Next |