1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
// license:???
// copyright-holders:Michael Strutts, Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni,Lee Taylor, Valerio Verrando, Marco Cassili, Zsolt Vasvari
/***************************************************************************
Midway 8080-based black and white hardware
****************************************************************************/
#include "emu.h"
#include "includes/mw8080bw.h"
/*************************************
*
* Interrupt generation
*
*************************************/
UINT8 mw8080bw_state::vpos_to_vysnc_chain_counter( int vpos )
{
/* convert from a vertical position to the actual values on the vertical sync counters */
UINT8 counter;
int vblank = (vpos >= MW8080BW_VBSTART);
if (vblank)
counter = vpos - MW8080BW_VBSTART + MW8080BW_VCOUNTER_START_VBLANK;
else
counter = vpos + MW8080BW_VCOUNTER_START_NO_VBLANK;
return counter;
}
int mw8080bw_state::vysnc_chain_counter_to_vpos( UINT8 counter, int vblank )
{
/* convert from the vertical sync counters to an actual vertical position */
int vpos;
if (vblank)
vpos = counter - MW8080BW_VCOUNTER_START_VBLANK + MW8080BW_VBSTART;
else
vpos = counter - MW8080BW_VCOUNTER_START_NO_VBLANK;
return vpos;
}
TIMER_CALLBACK_MEMBER(mw8080bw_state::mw8080bw_interrupt_callback)
{
UINT8 next_counter;
int next_vpos;
int next_vblank;
/* compute vector and set the interrupt line */
int vpos = m_screen->vpos();
UINT8 counter = vpos_to_vysnc_chain_counter(vpos);
UINT8 vector = 0xc7 | ((counter & 0x40) >> 2) | ((~counter & 0x40) >> 3);
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, vector);
/* set up for next interrupt */
if (counter == MW8080BW_INT_TRIGGER_COUNT_1)
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_2;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_2;
}
else
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_1;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_1;
}
next_vpos = vysnc_chain_counter_to_vpos(next_counter, next_vblank);
m_interrupt_timer->adjust(m_screen->time_until_pos(next_vpos));
}
void mw8080bw_state::mw8080bw_create_interrupt_timer( )
{
m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mw8080bw_state::mw8080bw_interrupt_callback),this));
}
void mw8080bw_state::mw8080bw_start_interrupt_timer( )
{
int vpos = vysnc_chain_counter_to_vpos(MW8080BW_INT_TRIGGER_COUNT_1, MW8080BW_INT_TRIGGER_VBLANK_1);
m_interrupt_timer->adjust(m_screen->time_until_pos(vpos));
}
/*************************************
*
* Machine setup
*
*************************************/
MACHINE_START_MEMBER(mw8080bw_state,mw8080bw)
{
mw8080bw_create_interrupt_timer();
}
/*************************************
*
* Machine reset
*
*************************************/
MACHINE_RESET_MEMBER(mw8080bw_state,mw8080bw)
{
mw8080bw_start_interrupt_timer();
}
|