summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/segag80v.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/segag80v.cpp')
-rw-r--r--src/mame/video/segag80v.cpp316
1 files changed, 156 insertions, 160 deletions
diff --git a/src/mame/video/segag80v.cpp b/src/mame/video/segag80v.cpp
index 110930e5973..bc126f72fe4 100644
--- a/src/mame/video/segag80v.cpp
+++ b/src/mame/video/segag80v.cpp
@@ -9,13 +9,17 @@
#include "emu.h"
#include "includes/segag80v.h"
-#define VECTOR_CLOCK 15468480 /* master clock */
-#define U34_CLOCK (VECTOR_CLOCK/3) /* clock for interrupt chain */
-#define VCL_CLOCK (U34_CLOCK/2) /* clock for vector generator */
-#define U51_CLOCK (VCL_CLOCK/16) /* clock for phase generator */
-#define IRQ_CLOCK (U34_CLOCK/0x1f788) /* 40Hz interrupt */
+#define VECTOR_CLOCK 15468480 // master clock
+#define U34_CLOCK (VECTOR_CLOCK/3) // clock for interrupt chain
+#define VCL_CLOCK (U34_CLOCK/2) // clock for vector generator
+#define U51_CLOCK (VCL_CLOCK/16) // clock for phase generator
+#define IRQ_CLOCK (U34_CLOCK/0x1f788) // 40Hz interrupt
+static constexpr attoseconds_t VCL_ATTOS = HZ_TO_ATTOSECONDS(VCL_CLOCK);
+static constexpr attoseconds_t U51_ATTOS = HZ_TO_ATTOSECONDS(U51_CLOCK);
+static constexpr attoseconds_t IRQ_ATTOS = HZ_TO_ATTOSECONDS(IRQ_CLOCK);
+
/*
@@ -73,247 +77,239 @@
A1-A8 = sum of VEC angle and SYM angle (low 8 bits)
A9 = sum of bit 8 of VEC angle and SYM angle, plus 1 for phase 13
-
*/
-inline bool segag80v_state::adjust_xy(int rawx, int rawy, int *outx, int *outy)
+
+inline bool segag80v_state::adjust_xy(int rawx, int rawy, int &outx, int &outy)
{
bool clipped = false;
- /* first apply the XOR at 0x200 */
- *outx = (rawx & 0x7ff) ^ 0x200;
- *outy = (rawy & 0x7ff) ^ 0x200;
+ // first apply the XOR at 0x200
+ outx = (rawx & 0x7ff) ^ 0x200;
+ outy = (rawy & 0x7ff) ^ 0x200;
- /* apply clipping logic to X */
- if ((*outx & 0x600) == 0x200)
- *outx = 0x000, clipped = true;
- else if ((*outx & 0x600) == 0x400)
- *outx = 0x3ff, clipped = true;
+ // apply clipping logic to X
+ if ((outx & 0x600) == 0x200)
+ outx = 0x000, clipped = true;
+ else if ((outx & 0x600) == 0x400)
+ outx = 0x3ff, clipped = true;
else
- *outx &= 0x3ff;
+ outx &= 0x3ff;
- /* apply clipping logic to Y */
- if ((*outy & 0x600) == 0x200)
- *outy = 0x000, clipped = true;
- else if ((*outy & 0x600) == 0x400)
- *outy = 0x3ff, clipped = true;
+ // apply clipping logic to Y
+ if ((outy & 0x600) == 0x200)
+ outy = 0x000, clipped = true;
+ else if ((outy & 0x600) == 0x400)
+ outy = 0x3ff, clipped = true;
else
- *outy &= 0x3ff;
+ outy &= 0x3ff;
- /* convert into .16 values */
- *outx = (*outx - (m_min_x - 512)) << 16;
- *outy = (*outy - (m_min_y - 512)) << 16;
+ // convert into .16 values
+ outx = (outx - (m_min_x - 512)) << 16;
+ outy = (outy - (m_min_y - 512)) << 16;
return clipped;
}
void segag80v_state::sega_generate_vector_list()
{
- uint8_t *sintable = memregion("proms")->base();
- double total_time = 1.0 / (double)IRQ_CLOCK;
- uint16_t symaddr = 0;
- uint8_t *vectorram = m_vectorram;
+ attoseconds_t time_remaining = IRQ_ATTOS;
+ u8 *sintable = memregion("proms")->base();
+ u8 *vectorram = m_vectorram;
+ u16 symaddr = 0;
m_vector->clear_list();
- /* Loop until we run out of time. */
- while (total_time > 0)
+ // Loop until we run out of time.
+ while (time_remaining > 0)
{
- uint16_t curx, cury, xaccum, yaccum;
- uint16_t vecaddr, symangle;
- uint8_t scale, draw;
-
- /* The "draw" flag is clocked at the end of phase 0. */
- draw = vectorram[symaddr++ & 0xfff];
+ // The "draw" flag is clocked at the end of phase 0.
+ u8 draw = vectorram[symaddr++ & 0xfff];
- /* The low byte of the X coordinate is latched into the */
- /* up/down counters at U15/U16 during phase 1. */
- curx = vectorram[symaddr++ & 0xfff];
+ // The low byte of the X coordinate is latched into the
+ // up/down counters at U15/U16 during phase 1.
+ u16 curx = vectorram[symaddr++ & 0xfff];
- /* The low 3 bits of the high byte of the X coordinate are */
- /* latched into the up/down counter at U17 during phase 2. */
- /* Bit 2 of the input is latched as both bit 2 and 3. */
+ // The low 3 bits of the high byte of the X coordinate are
+ // latched into the up/down counter at U17 during phase 2.
+ // Bit 2 of the input is latched as both bit 2 and 3.
curx |= (vectorram[symaddr++ & 0xfff] & 7) << 8;
curx |= (curx << 1) & 0x800;
- /* The low byte of the Y coordinate is latched into the */
- /* up/down counters at U18/U19 during phase 3. */
- cury = vectorram[symaddr++ & 0xfff];
+ // The low byte of the Y coordinate is latched into the
+ // up/down counters at U18/U19 during phase 3.
+ u16 cury = vectorram[symaddr++ & 0xfff];
- /* The low 3 bits of the high byte of the X coordinate are */
- /* latched into the up/down counter at U17 during phase 4. */
- /* Bit 2 of the input is latched as both bit 2 and 3. */
+ // The low 3 bits of the high byte of the X coordinate are
+ // latched into the up/down counter at U17 during phase 4.
+ // Bit 2 of the input is latched as both bit 2 and 3.
cury |= (vectorram[symaddr++ & 0xfff] & 7) << 8;
cury |= (cury << 1) & 0x800;
- /* The low byte of the vector address is latched into the */
- /* counters at U10/U11 during phase 5. */
- vecaddr = vectorram[symaddr++ & 0xfff];
+ // The low byte of the vector address is latched into the
+ // counters at U10/U11 during phase 5.
+ u16 vecaddr = vectorram[symaddr++ & 0xfff];
- /* The low 4 bits of the high byte of the vector address is */
- /* latched into the counter at U12 during phase 6. */
+ // The low 4 bits of the high byte of the vector address is
+ // latched into the counter at U12 during phase 6.
vecaddr |= (vectorram[symaddr++ & 0xfff] & 0xf) << 8;
- /* The low byte of the symbol angle is latched into the tri- */
- /* state flip flop at U55 at the end of phase 7. */
- symangle = vectorram[symaddr++ & 0xfff];
+ // The low byte of the symbol angle is latched into the tri-
+ // state flip flop at U55 at the end of phase 7.
+ u16 symangle = vectorram[symaddr++ & 0xfff];
- /* The low 2 bits of the high byte of the symbol angle are */
- /* latched into flip flops at U26 at the end of phase 8. */
+ // The low 2 bits of the high byte of the symbol angle are
+ // latched into flip flops at U26 at the end of phase 8.
symangle |= (vectorram[symaddr++ & 0xfff] & 3) << 8;
- /* The scale is latched in phase 9 as the X input to the */
- /* 25LS14 multiplier at U8. */
- scale = vectorram[symaddr++ & 0xfff];
+ // The scale is latched in phase 9 as the X input to the
+ // 25LS14 multiplier at U8.
+ u8 scale = vectorram[symaddr++ & 0xfff];
- /* Account for the 10 phases so far. */
- total_time -= 10.0 / (double)U51_CLOCK;
+ // Account for the 10 phases so far.
+ time_remaining -= 10 * U51_ATTOS;
- /* Skip the rest if we're not drawing this symbol. */
+ // Skip the rest if we're not drawing this symbol.
if (draw & 1)
{
- int adjx, adjy, clipped;
-
- /* Add a starting point to the vector list. */
- clipped = adjust_xy(curx, cury, &adjx, &adjy);
+ // Add a starting point to the vector list.
+ int adjx, adjy;
+ bool clipped = adjust_xy(curx, cury, adjx, adjy);
if (!clipped)
m_vector->add_point(adjx, adjy, 0, 0);
- /* Loop until we run out of time. */
- while (total_time > 0)
+ // Loop until we run out of time.
+ while (time_remaining > 0)
{
- uint16_t vecangle, length, deltax, deltay;
- uint8_t attrib, intensity;
- uint32_t color;
-
- /* The 'attribute' byte is latched at the end of phase 10 into */
- /* the tri-state flip flop at U2. The low bit controls whether */
- /* or not the beam is enabled. Bits 1-6 control the RGB color */
- /* (2 bits per component). In addition, bit 7 of this value is */
- /* latched into U52, which controls the pre-load value for the */
- /* phase generator. If bit 7 is high, then the phase generator */
- /* will reset back to 0 and draw a new symbol; if bit 7 is low */
- /* the phase generator will reset back to 10 and draw another */
- /* vector. */
- attrib = vectorram[vecaddr++ & 0xfff];
-
- /* The length of the vector is loaded into the shift registers */
- /* at U6/U7 during phase 11. During phase 12, the 25LS14 */
- /* multiplier at U8 is used to multiply the length by the */
- /* scale that was loaded during phase 9. The length is clocked */
- /* bit by bit out of U6/U7 and the result is clocked into the */
- /* other side. After the multiply, the 9 MSBs are loaded into */
- /* the counter chain at U15/16/17 and are used to count how */
- /* long to draw the vector. */
- length = (vectorram[vecaddr++ & 0xfff] * scale) >> 7;
-
- /* The vector angle low byte is latched at the end of phase 12 */
- /* into the tri-state flip flop at U56. */
- vecangle = vectorram[vecaddr++ & 0xfff];
-
- /* The vector angle high byte is preset on the CD bus during */
- /* phases 13 and 14, and is used as inputs to the adder at */
- /* U46. */
+ // The 'attribute' byte is latched at the end of phase 10 into
+ // the tri-state flip flop at U2. The low bit controls whether
+ // or not the beam is enabled. Bits 1-6 control the RGB color
+ // (2 bits per component). In addition, bit 7 of this value is
+ // latched into U52, which controls the pre-load value for the
+ // phase generator. If bit 7 is high, then the phase generator
+ // will reset back to 0 and draw a new symbol; if bit 7 is low
+ // the phase generator will reset back to 10 and draw another
+ // vector.
+ u8 attrib = vectorram[vecaddr++ & 0xfff];
+
+ // The length of the vector is loaded into the shift registers
+ // at U6/U7 during phase 11. During phase 12, the 25LS14
+ // multiplier at U8 is used to multiply the length by the
+ // scale that was loaded during phase 9. The length is clocked
+ // bit by bit out of U6/U7 and the result is clocked into the
+ // other side. After the multiply, the 9 MSBs are loaded into
+ // the counter chain at U15/16/17 and are used to count how
+ // long to draw the vector.
+ u16 length = (vectorram[vecaddr++ & 0xfff] * scale) >> 7;
+
+ // The vector angle low byte is latched at the end of phase 12
+ // into the tri-state flip flop at U56.
+ u16 vecangle = vectorram[vecaddr++ & 0xfff];
+
+ // The vector angle high byte is preset on the CD bus during
+ // phases 13 and 14, and is used as inputs to the adder at
+ // U46.
vecangle |= (vectorram[vecaddr++ & 0xfff] & 3) << 8;
- /* The X increment value is looked up first (phase 13). The */
- /* sum of the latched symbol angle and the vector angle is */
- /* used as input to the PROM at U39. A0 is tied to ground. */
- /* A1-A9 map to bits 0-8 of the summed angles. The output from */
- /* the PROM is latched into U48. */
- deltax = sintable[((vecangle + symangle) & 0x1ff) << 1];
-
- /* The Y increment value is looked up second (phase 14). The */
- /* angle sum is used once again as the input to the PROM, but */
- /* this time an additional 0x100 is effectively added to it */
- /* before it is used; this separates sin from cos. The output */
- /* from the PROM is latched into U49. */
- deltay = sintable[((vecangle + symangle + 0x100) & 0x1ff) << 1];
-
- /* Account for the 4 phases for data fetching. */
- total_time -= 4.0 / (double)U51_CLOCK;
-
- /* Compute color/intensity values from the attributes */
- color = vector_device::color222((attrib >> 1) & 0x3f);
+ // The X increment value is looked up first (phase 13). The
+ // sum of the latched symbol angle and the vector angle is
+ // used as input to the PROM at U39. A0 is tied to ground.
+ // A1-A9 map to bits 0-8 of the summed angles. The output from
+ // the PROM is latched into U48.
+ u16 deltax = sintable[((vecangle + symangle) & 0x1ff) << 1];
+
+ // The Y increment value is looked up second (phase 14). The
+ // angle sum is used once again as the input to the PROM, but
+ // this time an additional 0x100 is effectively added to it
+ // before it is used; this separates sin from cos. The output
+ // from the PROM is latched into U49.
+ u16 deltay = sintable[((vecangle + symangle + 0x100) & 0x1ff) << 1];
+
+ // Account for the 4 phases for data fetching.
+ time_remaining -= 4 * U51_ATTOS;
+
+ // Compute color/intensity values from the attributes
+ u32 color = vector_device::color222((attrib >> 1) & 0x3f);
+ u8 intensity = 0;
if ((attrib & 1) && color)
intensity = 0xff;
- else
- intensity = 0;
- /* Loop over the length of the vector. */
- clipped = adjust_xy(curx, cury, &adjx, &adjy);
- xaccum = yaccum = 0;
- while (length-- != 0 && total_time > 0)
+ // Loop over the length of the vector.
+ clipped = adjust_xy(curx, cury, adjx, adjy);
+ u16 xaccum = 0;
+ u16 yaccum = 0;
+ while (length-- != 0 && time_remaining > 0)
{
- int newclip;
-
- /* The adders at U44/U45 are used as X accumulators. The value */
- /* from U48 is repeatedly added to itself here. The carry out */
- /* of bit 8 clocks the up/down counters at U15/U16/U17. Bit 7 */
- /* of the input value from U48 is used as a carry in to round */
- /* small values downward and larger values upward. */
+ // The adders at U44/U45 are used as X accumulators. The value
+ // from U48 is repeatedly added to itself here. The carry out
+ // of bit 8 clocks the up/down counters at U15/U16/U17. Bit 7
+ // of the input value from U48 is used as a carry in to round
+ // small values downward and larger values upward.
xaccum += deltax + (deltax >> 7);
- /* Bit 9 of the summed angles controls the direction the up/ */
- /* down counters at U15/U16/U17. */
+ // Bit 9 of the summed angles controls the direction the up/
+ // down counters at U15/U16/U17.
if (((vecangle + symangle) & 0x200) == 0)
curx += xaccum >> 8;
else
curx -= xaccum >> 8;
xaccum &= 0xff;
- /* The adders at U46/U47 are used as Y accumulators. The value */
- /* from U49 is repeatedly added to itself here. The carry out */
- /* of bit 8 clocks the up/down counters at U18/U19/U20. Bit 7 */
- /* of the input value from U49 is used as a carry in to round */
- /* small values downward and larger values upward. */
+ // The adders at U46/U47 are used as Y accumulators. The value
+ // from U49 is repeatedly added to itself here. The carry out
+ // of bit 8 clocks the up/down counters at U18/U19/U20. Bit 7
+ // of the input value from U49 is used as a carry in to round
+ // small values downward and larger values upward.
yaccum += deltay + (deltay >> 7);
- /* Bit 9 of the summed angles controls the direction the up/ */
- /* down counters at U18/U19/U20. */
+ // Bit 9 of the summed angles controls the direction the up/
+ // down counters at U18/U19/U20.
if (((vecangle + symangle + 0x100) & 0x200) == 0)
cury += yaccum >> 8;
else
cury -= yaccum >> 8;
yaccum &= 0xff;
- /* Apply the clipping from the DAC circuit. If the values clip */
- /* the beam is turned off, but the computations continue right */
- /* on going. */
- newclip = adjust_xy(curx, cury, &adjx, &adjy);
+ // Apply the clipping from the DAC circuit. If the values clip
+ // the beam is turned off, but the computations continue right
+ // on going.
+ bool newclip = adjust_xy(curx, cury, adjx, adjy);
if (newclip != clipped)
{
- /* if we're just becoming unclipped, add an empty point */
+ // if we're just becoming unclipped, add an empty point
if (!newclip)
m_vector->add_point(adjx, adjy, 0, 0);
- /* otherwise, add a colored point */
+ // otherwise, add a colored point
else
m_vector->add_point(adjx, adjy, color, intensity);
}
clipped = newclip;
- /* account for vector drawing time */
- total_time -= 1.0 / (double)VCL_CLOCK;
+ // account for vector drawing time
+ time_remaining -= VCL_ATTOS;
}
- /* We're done; if we are not clipped, add a final point. */
+ // We're done; if we are not clipped, add a final point.
if (!clipped)
m_vector->add_point(adjx, adjy, color, intensity);
- /* if the high bit of the attribute is set, we break out of */
- /* this loop and fetch another symbol */
+ // if the high bit of the attribute is set, we break out of
+ // this loop and fetch another symbol
if (attrib & 0x80)
break;
}
}
- /* if the high bit of the draw flag is set, we break out of this loop */
- /* and stop the rendering altogether for this frame. */
+ // if the high bit of the draw flag is set, we break out of this loop
+ // and stop the rendering altogether for this frame.
if (draw & 0x80)
break;
}
+
+ // set the drawing end time for this frame
+ m_draw_end_time = machine().scheduler().time() + attotime(0, IRQ_ATTOS - time_remaining);
}
@@ -328,12 +324,12 @@ void segag80v_state::video_start()
if (!m_vectorram.bytes())
throw emu_fatalerror("segag80v_state::video_start: !vectorram.bytes()");
- m_min_x =m_screen->visible_area().min_x;
- m_min_y =m_screen->visible_area().min_y;
+ m_min_x = m_screen->visible_area().min_x;
+ m_min_y = m_screen->visible_area().min_y;
}
-uint32_t segag80v_state::screen_update_segag80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+u32 segag80v_state::screen_update_segag80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
sega_generate_vector_list();
m_vector->screen_update(screen, bitmap, cliprect);