23
23
berzerk_state(const machine_config &mconfig, device_type type, const char *tag)
24
: driver_device(mconfig, type, tag) { }
24
: driver_device(mconfig, type, tag) ,
25
m_videoram(*this, "videoram"),
26
m_colorram(*this, "colorram"){ }
27
size_t m_videoram_size;
28
required_shared_ptr<UINT8> m_videoram;
29
required_shared_ptr<UINT8> m_colorram;
29
30
UINT8 m_magicram_control;
30
31
UINT8 m_last_shift_data;
37
38
int m_p1_direction;
38
39
int m_p2_counter_74ls161;
39
40
int m_p2_direction;
41
DECLARE_READ8_MEMBER(led_on_r);
42
DECLARE_WRITE8_MEMBER(led_on_w);
43
DECLARE_READ8_MEMBER(led_off_r);
44
DECLARE_WRITE8_MEMBER(led_off_w);
45
DECLARE_WRITE8_MEMBER(irq_enable_w);
46
DECLARE_WRITE8_MEMBER(nmi_enable_w);
47
DECLARE_WRITE8_MEMBER(nmi_disable_w);
48
DECLARE_READ8_MEMBER(nmi_enable_r);
49
DECLARE_READ8_MEMBER(nmi_disable_r);
50
DECLARE_WRITE8_MEMBER(magicram_w);
51
DECLARE_WRITE8_MEMBER(magicram_control_w);
52
DECLARE_READ8_MEMBER(intercept_v256_r);
53
DECLARE_WRITE8_MEMBER(berzerk_audio_w);
54
DECLARE_READ8_MEMBER(berzerk_audio_r);
55
DECLARE_READ8_MEMBER(moonwarp_p1_r);
56
DECLARE_READ8_MEMBER(moonwarp_p2_r);
71
88
*************************************/
73
static READ8_HANDLER( led_on_r )
75
set_led_status(space->machine(), 0, 1);
81
static WRITE8_HANDLER( led_on_w )
83
set_led_status(space->machine(), 0, 1);
87
static READ8_HANDLER( led_off_r )
89
set_led_status(space->machine(), 0, 0);
95
static WRITE8_HANDLER( led_off_w )
97
set_led_status(space->machine(), 0, 0);
90
READ8_MEMBER(berzerk_state::led_on_r)
92
set_led_status(machine(), 0, 1);
98
WRITE8_MEMBER(berzerk_state::led_on_w)
100
set_led_status(machine(), 0, 1);
104
READ8_MEMBER(berzerk_state::led_off_r)
106
set_led_status(machine(), 0, 0);
112
WRITE8_MEMBER(berzerk_state::led_off_w)
114
set_led_status(machine(), 0, 0);
213
229
*************************************/
215
static WRITE8_HANDLER( nmi_enable_w )
217
berzerk_state *state = space->machine().driver_data<berzerk_state>();
218
state->m_nmi_enabled = 1;
222
static WRITE8_HANDLER( nmi_disable_w )
224
berzerk_state *state = space->machine().driver_data<berzerk_state>();
225
state->m_nmi_enabled = 0;
229
static READ8_HANDLER( nmi_enable_r )
231
berzerk_state *state = space->machine().driver_data<berzerk_state>();
232
state->m_nmi_enabled = 1;
231
WRITE8_MEMBER(berzerk_state::nmi_enable_w)
237
WRITE8_MEMBER(berzerk_state::nmi_disable_w)
243
READ8_MEMBER(berzerk_state::nmi_enable_r)
238
static READ8_HANDLER( nmi_disable_r )
251
READ8_MEMBER(berzerk_state::nmi_disable_r)
240
berzerk_state *state = space->machine().driver_data<berzerk_state>();
241
state->m_nmi_enabled = 0;
350
static WRITE8_HANDLER( magicram_w )
362
WRITE8_MEMBER(berzerk_state::magicram_w)
352
berzerk_state *state = space->machine().driver_data<berzerk_state>();
353
364
UINT8 alu_output;
355
UINT8 current_video_data = state->m_videoram[offset];
366
UINT8 current_video_data = m_videoram[offset];
357
368
/* shift data towards LSB. MSB bits are filled by data from last_shift_data.
358
369
The shifter consists of 5 74153 devices @ 7A, 8A, 9A, 10A and 11A,
359
370
followed by 4 more 153's at 11B, 10B, 9B and 8B, which optionally
360
371
reverse the order of the resulting bits */
361
UINT8 shift_flop_output = (((UINT16)state->m_last_shift_data << 8) | data) >> (state->m_magicram_control & 0x07);
372
UINT8 shift_flop_output = (((UINT16)m_last_shift_data << 8) | data) >> (m_magicram_control & 0x07);
363
if (state->m_magicram_control & 0x08)
374
if (m_magicram_control & 0x08)
364
375
shift_flop_output = BITSWAP8(shift_flop_output, 0, 1, 2, 3, 4, 5, 6, 7);
366
377
/* collision detection - AND gate output goes to the K pin of the flip-flop,
367
378
while J is LO, therefore, it only resets, never sets */
368
379
if (shift_flop_output & current_video_data)
369
state->m_intercept = 0;
371
382
/* perform ALU step */
372
383
TTL74181_write(LS181_12C, TTL74181_INPUT_A0, 4, shift_flop_output & 0x0f);
373
384
TTL74181_write(LS181_10C, TTL74181_INPUT_A0, 4, shift_flop_output >> 4);
374
385
TTL74181_write(LS181_12C, TTL74181_INPUT_B0, 4, current_video_data & 0x0f);
375
386
TTL74181_write(LS181_10C, TTL74181_INPUT_B0, 4, current_video_data >> 4);
376
TTL74181_write(LS181_12C, TTL74181_INPUT_S0, 4, state->m_magicram_control >> 4);
377
TTL74181_write(LS181_10C, TTL74181_INPUT_S0, 4, state->m_magicram_control >> 4);
387
TTL74181_write(LS181_12C, TTL74181_INPUT_S0, 4, m_magicram_control >> 4);
388
TTL74181_write(LS181_10C, TTL74181_INPUT_S0, 4, m_magicram_control >> 4);
379
390
alu_output = (TTL74181_read(LS181_10C, TTL74181_OUTPUT_F0, 4) << 4) |
380
391
(TTL74181_read(LS181_12C, TTL74181_OUTPUT_F0, 4) << 0);
382
state->m_videoram[offset] = alu_output ^ 0xff;
393
m_videoram[offset] = alu_output ^ 0xff;
384
395
/* save data for next time */
385
state->m_last_shift_data = data & 0x7f;
396
m_last_shift_data = data & 0x7f;
389
static WRITE8_HANDLER( magicram_control_w )
400
WRITE8_MEMBER(berzerk_state::magicram_control_w)
391
berzerk_state *state = space->machine().driver_data<berzerk_state>();
392
402
/* save the control byte, clear the shift data latch,
393
403
and set the intercept flip-flop */
394
state->m_magicram_control = data;
395
state->m_last_shift_data = 0;
396
state->m_intercept = 1;
404
m_magicram_control = data;
405
m_last_shift_data = 0;
400
static READ8_HANDLER( intercept_v256_r )
410
READ8_MEMBER(berzerk_state::intercept_v256_r)
402
berzerk_state *state = space->machine().driver_data<berzerk_state>();
406
vpos_to_vsync_chain_counter(space->machine().primary_screen->vpos(), &counter, &v256);
415
vpos_to_vsync_chain_counter(machine().primary_screen->vpos(), &counter, &v256);
408
return (!state->m_intercept << 7) | v256;
417
return (!m_intercept << 7) | v256;
538
547
/* offset 6 writes to the sfxcontrol latch */
540
exidy_sfxctrl_w(space->machine().device("exidy"), data >> 6, data);
549
exidy_sfxctrl_w(machine().device("exidy"), data >> 6, data);
543
552
/* everything else writes to the 6840 */
545
exidy_sh6840_w(space->machine().device("exidy"), offset, data);
554
exidy_sh6840_w(machine().device("exidy"), offset, data);
552
static READ8_HANDLER( berzerk_audio_r )
561
READ8_MEMBER(berzerk_state::berzerk_audio_r)
554
device_t *device = space->machine().device("speech");
563
device_t *device = machine().device("speech");
557
566
/* offset 4 reads from the S14001A */
585
595
*************************************/
587
static ADDRESS_MAP_START( berzerk_map, AS_PROGRAM, 8 )
597
static ADDRESS_MAP_START( berzerk_map, AS_PROGRAM, 8, berzerk_state )
588
598
AM_RANGE(0x0000, 0x07ff) AM_ROM
589
599
AM_RANGE(0x0800, 0x0bff) AM_MIRROR(0x0400) AM_RAM AM_SHARE("nvram")
590
600
AM_RANGE(0x1000, 0x3fff) AM_ROM
591
AM_RANGE(0x4000, 0x5fff) AM_RAM AM_BASE_MEMBER(berzerk_state, m_videoram) AM_SIZE_MEMBER(berzerk_state, m_videoram_size) AM_SHARE("share1")
592
AM_RANGE(0x6000, 0x7fff) AM_RAM_WRITE(magicram_w) AM_SHARE("share1")
593
AM_RANGE(0x8000, 0x87ff) AM_MIRROR(0x3800) AM_RAM AM_BASE_MEMBER(berzerk_state, m_colorram)
601
AM_RANGE(0x4000, 0x5fff) AM_RAM AM_SHARE("videoram")
602
AM_RANGE(0x6000, 0x7fff) AM_RAM_WRITE(magicram_w) AM_SHARE("videoram")
603
AM_RANGE(0x8000, 0x87ff) AM_MIRROR(0x3800) AM_RAM AM_SHARE("colorram")
594
604
AM_RANGE(0xc000, 0xffff) AM_NOP
598
static ADDRESS_MAP_START( frenzy_map, AS_PROGRAM, 8 )
608
static ADDRESS_MAP_START( frenzy_map, AS_PROGRAM, 8, berzerk_state )
599
609
AM_RANGE(0x0000, 0x3fff) AM_ROM
600
AM_RANGE(0x4000, 0x5fff) AM_RAM AM_BASE_MEMBER(berzerk_state, m_videoram) AM_SIZE_MEMBER(berzerk_state, m_videoram_size) AM_SHARE("share1")
601
AM_RANGE(0x6000, 0x7fff) AM_RAM_WRITE(magicram_w) AM_SHARE("share1")
602
AM_RANGE(0x8000, 0x87ff) AM_MIRROR(0x3800) AM_RAM AM_BASE_MEMBER(berzerk_state, m_colorram)
610
AM_RANGE(0x4000, 0x5fff) AM_RAM AM_SHARE("videoram")
611
AM_RANGE(0x6000, 0x7fff) AM_RAM_WRITE(magicram_w) AM_SHARE("videoram")
612
AM_RANGE(0x8000, 0x87ff) AM_MIRROR(0x3800) AM_RAM AM_SHARE("colorram")
603
613
AM_RANGE(0xc000, 0xcfff) AM_ROM
604
614
AM_RANGE(0xf800, 0xfbff) AM_MIRROR(0x0400) AM_RAM AM_SHARE("nvram")
885
895
PORT_DIPSETTING( 0xff, "255" )
888
static READ8_HANDLER( moonwarp_p1_r )
898
READ8_MEMBER(berzerk_state::moonwarp_p1_r)
890
berzerk_state *state = space->machine().driver_data<berzerk_state>();
891
900
// This seems to be the same type of dial as the later 'moon war 2' set uses
892
901
// see http://www.cityofberwyn.com/schematics/stern/MoonWar_opto.tiff for schematic
893
902
// I.e. a 74ls161 counts from 0 to 15 which is the absolute number of bars passed on the quadrature
894
903
// one difference is it lacks the strobe input (does it?), which if not active causes
895
904
// the dial input to go open bus. This is used in moon war 2 to switch between player 1
896
905
// and player 2 dials, which share a single port. moonwarp uses separate ports for the dials.
897
signed char dialread = input_port_read(space->machine(),"P1_DIAL");
906
signed char dialread = ioport("P1_DIAL")->read();
899
UINT8 buttons = (input_port_read(space->machine(),"P1")&0xe0);
900
if (dialread < 0) state->m_p1_direction = 0;
901
else if (dialread > 0) state->m_p1_direction = 0x10;
902
state->m_p1_counter_74ls161 += abs(dialread);
903
state->m_p1_counter_74ls161 &= 0xf;
904
ret = state->m_p1_counter_74ls161 | state->m_p1_direction | buttons;
905
//fprintf(stderr, "dialread1: %02x, p1_counter_74ls161: %02x, spinner ret is %02x\n", dialread, state->m_p1_counter_74ls161, ret);
908
UINT8 buttons = (ioport("P1")->read()&0xe0);
909
if (dialread < 0) m_p1_direction = 0;
910
else if (dialread > 0) m_p1_direction = 0x10;
911
m_p1_counter_74ls161 += abs(dialread);
912
m_p1_counter_74ls161 &= 0xf;
913
ret = m_p1_counter_74ls161 | m_p1_direction | buttons;
914
//fprintf(stderr, "dialread1: %02x, p1_counter_74ls161: %02x, spinner ret is %02x\n", dialread, m_p1_counter_74ls161, ret);
909
static READ8_HANDLER( moonwarp_p2_r )
918
READ8_MEMBER(berzerk_state::moonwarp_p2_r)
911
berzerk_state *state = space->machine().driver_data<berzerk_state>();
912
920
// same as above, but for player 2 in cocktail mode
913
signed char dialread = input_port_read(space->machine(),"P2_DIAL");
921
signed char dialread = ioport("P2_DIAL")->read();
915
UINT8 buttons = (input_port_read(space->machine(),"P2")&0xe0);
916
if (dialread < 0) state->m_p2_direction = 0;
917
else if (dialread > 0) state->m_p2_direction = 0x10;
918
state->m_p2_counter_74ls161 += abs(dialread);
919
state->m_p2_counter_74ls161 &= 0xf;
920
ret = state->m_p2_counter_74ls161 | state->m_p2_direction | buttons;
921
//fprintf(stderr, "dialread2: %02x, p2_counter_74ls161: %02x, spinner ret is %02x\n", dialread, state->m_p2_counter_74ls161, ret);
923
UINT8 buttons = (ioport("P2")->read()&0xe0);
924
if (dialread < 0) m_p2_direction = 0;
925
else if (dialread > 0) m_p2_direction = 0x10;
926
m_p2_counter_74ls161 += abs(dialread);
927
m_p2_counter_74ls161 &= 0xf;
928
ret = m_p2_counter_74ls161 | m_p2_direction | buttons;
929
//fprintf(stderr, "dialread2: %02x, p2_counter_74ls161: %02x, spinner ret is %02x\n", dialread, m_p2_counter_74ls161, ret);
1228
1236
static DRIVER_INIT( moonwarp )
1230
1238
address_space *io = machine.device("maincpu")->memory().space(AS_IO);
1231
io->install_legacy_read_handler (0x48, 0x48, FUNC(moonwarp_p1_r));
1232
io->install_legacy_read_handler (0x4a, 0x4a, FUNC(moonwarp_p2_r));
1239
berzerk_state *state = machine.driver_data<berzerk_state>();
1240
io->install_read_handler (0x48, 0x48, read8_delegate(FUNC(berzerk_state::moonwarp_p1_r), state));
1241
io->install_read_handler (0x4a, 0x4a, read8_delegate(FUNC(berzerk_state::moonwarp_p2_r), state));
1235
1244
/*************************************