diff options
Diffstat (limited to 'src/mame/video/segag80v.cpp')
-rw-r--r-- | src/mame/video/segag80v.cpp | 316 |
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); |