diff --git a/src/mess/drivers/vk100.c b/src/mess/drivers/vk100.c index d6316e29fa1..af3c629a7e9 100644 --- a/src/mess/drivers/vk100.c +++ b/src/mess/drivers/vk100.c @@ -9,10 +9,30 @@ Todo: * fix vector generator hardware enough to pass the startup self test the tests are described on page 6-5 thru 6-8 of the tech reference - * hook up the direction and sync prom to the sync counter + * hook up the bresenham DU/DVM/ERR stuff, currently only simple directional vectors work + * hook up the vector and sync proms to the sync counter + * figure out how the erase prom actually works at a hardware level + * redump the vector prom, the first two bytes look bad * figure out the correct meaning of systat b register - needed for communications selftest * hook up smc com5016t baud generator to i8251 rx and tx clocks - begun + Notes: + The directions for the DIR value are arranged, starting from the * + as the vector origin: + 3 2 1 + \ | / + \|/ + 4--*--0 + /|\ + / | \ + 5 6 7 + + The X and Y counters are techincally 12 bits long each, though + only the low 9 and 10 bits respectively are used for ram addressing. + The MSB bit of each counter does have a special purpose with + regards to the RAS/ERASE prom though, perhaps to detect an + underflow 000->FFF + Tony DiCenzo, now the director of standards and architecture at Oracle, was on the team that developed the VK100 see http://startup.nmnaturalhistory.org/visitorstories/view.php?ii=79 Robert "Bob" C. Quinn was definitely lead engineer on the VT125 and may have been lead engineer on the VK100 as well @@ -39,8 +59,8 @@ PCB Layout VK100 LOGICBOARD |-------| |---------| |---------| |-| |-| |-| |-| -|---|-20 mA-|----|---EIA---|--|HARD-COPY|----|B|-|G|-|R|--|-|----------| -| BW DSW(8) | +|---|-20 mA-|----|---EIA---|--|HARD-COPY|----|B|-|G|-|R|--|-|--DSW(8)--| +| BW | | POWER | | PR2 | | HD46505SP 4116 4116 4116 4116 | @@ -121,6 +141,9 @@ state machine and sees if the GO bit ever finishes and goes back to 0 #undef SYSTAT_A_VERBOSE #undef SYSTAT_B_VERBOSE +// debug state dump for the vector generator +#undef DEBUG_VG_STATE + #include "emu.h" #include "cpu/i8085/i8085.h" #include "sound/beep.h" @@ -161,6 +184,11 @@ public: UINT8* m_trans; UINT8* m_pattern; UINT8* m_dir; + UINT8* m_sync; + UINT8* m_vector; + UINT8* m_ras_erase; + UINT8 m_dir_a6; // latched a6 of dir rom + UINT8 m_cout; // carry out from vgERR adder UINT8 m_vsync; // vsync pin of crtc UINT16 m_vgX; UINT16 m_vgY; @@ -197,7 +225,7 @@ public: DECLARE_READ8_MEMBER(SYSTAT_A); DECLARE_READ8_MEMBER(SYSTAT_B); DECLARE_DRIVER_INIT(vk100); - virtual void machine_reset(); + virtual void machine_start(); virtual void video_start(); TIMER_CALLBACK_MEMBER(execute_vg); DECLARE_WRITE_LINE_MEMBER(crtc_vsync); @@ -262,36 +290,6 @@ void vk100_state::vram_write(UINT8 data) m_vram[(EA<<1)] = (block&0xFF00)>>8; // '' } -TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) -{ - UINT8 thisNyb = vram_read(); // read in the nybble - // pattern rom addressing is a complex mess. see the pattern rom def later in this file. - UINT8 newNyb = m_pattern[((m_vgPAT&m_vgPAT_Mask)?0x200:0)|((VG_WOPS&7)<<6)|((m_vgX&3)<<4)|thisNyb]; // calculate new nybble based on pattern rom - // finally write the block back to ram depending on the VG_MODE (sort of a hack until we get the vector and synd and dir roms all hooked up) - switch (m_VG_MODE) - { - case 0: // move; adjusts the x and y but doesn't write anything. do nothing - break; - case 1: // dot: only write the LAST pixel in the chain? TODO: some fallthrough magic here? - if ((m_vgDownCount) == 0x00) - { - vram_write(newNyb); // write out the modified nybble - } - break; - case 2: // vec: draw the vector - vram_write(newNyb); // write out the modified nybble - break; - case 3: // er: erase: special case here: wipe the entire screen (except for color/attrib?) and then set done. - for (int i = 0; i < 0x8000; i++) - { - if (!(i&1)) // avoid stomping attribute - m_vram[i] = m_vram[i]&0xF0; - else // (i&1) - m_vram[i] = 0; - } - m_vgGO = 0; // done - break; - } /* this is the "DIRECTION ROM" == mb6309 (256x8, 82s135) * see figure 5-24 on page 5-39 * It tells the direction and enable for counting on the X and Y counters @@ -306,8 +304,8 @@ TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) * |\-------- feedback bit from d5 strobed by V CLK [verified via tracing] * \--------- GND; the second half of the prom is blank (0x00) * data bits: 76543210 - * |||||||\-- ENA X (enables change on X counter) - * ||||||\--- ENA Y (enables change on Y counter) + * |||||||\-- ENA Y (enables change on Y counter) + * ||||||\--- ENA X (enables change on X counter) * |||||\---- Y DIRECTION (high is count down, low is count up) * ||||\----- X DIRECTION (high is count down, low is count up) * |||\------ PIXEL WRT @@ -316,40 +314,55 @@ TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) * \--------- UNUSED, always 0 * The VT125 prom @ E41 is literally identical to this, the same exact part: 23-059B1 */ - //UINT8 direction_rom = m_dir[]; - // HACK: we need the proper direction rom dump for this! - switch(VG_DIR&0x7) +TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) +{ + m_cout = 1; // hack for now + UINT8 dirbyte = m_dir[(m_dir_a6<<6)|((m_vgY&1)<<5)|(m_cout<<4)|VG_DIR]; +#ifdef DEBUG_VG_STATE + static const char *const vg_functions[] = { "Move", "Dot", "Vector", "Erase" }; + fprintf(stderr, "VGMODE: %s; DIR: A:%02x; D:%02x; X: %03X; Y: %03X; DownCount: %02X\n", vg_functions[m_VG_MODE], ((m_dir_a6<<6)|((m_vgY&1)<<5)|(m_cout<<4)|VG_DIR), dirbyte, m_vgX, m_vgY, m_vgDownCount); +#endif + m_dir_a6 = m_vgGO?((dirbyte&0x20)>>5):1; + if (dirbyte&2) // ena_x is active { - case 0: - m_vgX++; + if (dirbyte&0x80) m_vgX--; + else m_vgX++; + } + if (dirbyte&1) // ena_y is active + { + if (dirbyte&0x40) m_vgY--; + else m_vgY++; + } + if (dirbyte&0x10) m_vgDownCount--; // decrement the down counter + UINT8 thisNyb = vram_read(); // read in the nybble + // pattern rom addressing is a complex mess. see the pattern rom def later in this file. + UINT8 newNyb = m_pattern[((m_vgPAT&m_vgPAT_Mask)?0x200:0)|((VG_WOPS&7)<<6)|((m_vgX&3)<<4)|thisNyb]; // calculate new nybble based on pattern rom + // finally write the block back to ram depending on the VG_MODE (sort of a hack until we get the vector and synd and dir roms all hooked up) + // but only do it if the direction rom said so! + switch (m_VG_MODE) + { + case 0: // move; adjusts the x and y but doesn't write anything. do nothing break; - case 7: - m_vgX++; - m_vgY++; + case 1: // dot: only write the LAST pixel in the chain? TODO: some fallthrough magic here? + if ((m_vgDownCount) == 0x00) + { + if (dirbyte&0x10) vram_write(newNyb); // write out the modified nybble + } break; - case 6: - m_vgY++; + case 2: // vec: draw the vector + if (dirbyte&0x10) vram_write(newNyb); // write out the modified nybble break; - case 5: - m_vgX--; - m_vgY++; - break; - case 4: - m_vgX--; - break; - case 3: - m_vgX--; - m_vgY--; - break; - case 2: - m_vgY--; - break; - case 1: - m_vgX++; - m_vgY--; + case 3: // er: erase: special case here: wipe the entire screen (except for color/attrib?) and then set done. + for (int i = 0; i < 0x8000; i++) + { + if (!(i&1)) // avoid stomping attribute + m_vram[i] = m_vram[i]&0xF0; + else // (i&1) + m_vram[i] = 0; + } + m_vgGO = 0; // done break; } - m_vgDownCount--; // decrement the down counter if ((m_vgDownCount) == 0x00) m_vgGO = 0; // check if the down counter hit terminal count (0), if so we're done. if (((++m_vgPMUL_Count)&0xF)==0) // if pattern multiplier counter overflowed { @@ -850,7 +863,7 @@ static INPUT_PORTS_START( vk100 ) INPUT_PORTS_END -void vk100_state::machine_reset() +void vk100_state::machine_start() { beep_set_frequency( m_speaker, 116 ); //116 hz (page 172 of TM), but duty cycle is wrong here! output_set_value("online_led",1); @@ -861,6 +874,8 @@ void vk100_state::machine_reset() output_set_value("l1_led", 1); output_set_value("l2_led", 1); m_vsync = 0; + m_dir_a6 = 1; + m_cout = 0; m_vgX = 0; m_vgY = 0; m_vgERR = 0; @@ -926,6 +941,9 @@ void vk100_state::video_start() m_trans = memregion("trans")->base(); m_pattern = memregion("pattern")->base(); m_dir = memregion("dir")->base(); + m_sync = memregion("sync")->base(); + m_vector = memregion("vector")->base(); + m_ras_erase = memregion("ras_erase")->base(); } static MC6845_UPDATE_ROW( vk100_update_row ) @@ -1081,8 +1099,8 @@ ROM_START( vk100 ) * |\-------- feedback bit from d5 strobed by V CLK [verified via tracing] * \--------- GND; the second half of the prom is blank (0x00) * data bits: 76543210 - * |||||||\-- ENA X (enables change on X counter) - * ||||||\--- ENA Y (enables change on Y counter) + * |||||||\-- ENA Y (enables change on X counter) [works with code] + * ||||||\--- ENA X (enables change on Y counter) [works with code] * |||||\---- Y DIRECTION (high is count down, low is count up) * ||||\----- X DIRECTION (high is count down, low is count up) * |||\------ PIXEL WRT @@ -1093,7 +1111,7 @@ ROM_START( vk100 ) */ ROM_LOAD( "wb8141_059b1.tbp18s22.pr5.ic108", 0x0000, 0x0100, CRC(4b63857a) SHA1(3217247d983521f0b0499b5c4ef6b5de9844c465)) // label verified from andy's board - ROM_REGION( 0x400, "proms", ROMREGION_ERASEFF ) + ROM_REGION( 0x100, "ras_erase", ROMREGION_ERASEFF ) /* this is the "RAS/ERASE ROM" involved with driving the RAS lines and erasing VRAM dram (256*4, 82s129) * control bits: * /CE1 ----- /WRITE aka WRITE L (pin 6 of vector rom after being latched by its ls273) [verified via tracing and vt125 schematic] @@ -1133,6 +1151,8 @@ ROM_START( vk100 ) * */ ROM_LOAD( "wb8151_573a2.mmi6301.pr3.ic44", 0x0000, 0x0100, CRC(75885a9f) SHA1(c721dad6a69c291dd86dad102ed3a8ddd620ecc4)) // label verified from nigwil's and andy's board + + ROM_REGION( 0x100, "vector", ROMREGION_ERASEFF ) // WARNING: it is possible that the first two bytes of this prom are bad! /* this is the "VECTOR ROM" (256*8, 82s135) which runs the vector generator state machine * the vector rom bits are complex and are unfortunately poorly documented @@ -1169,7 +1189,9 @@ ROM_START( vk100 ) * * The VT125 prom E71 and its latch E70 is mostly equivalent to the vector prom, but the address order is different */ - ROM_LOAD( "wb8146_058b1.mmi6309.pr1.ic99", 0x0100, 0x0100, CRC(71b01864) SHA1(e552f5b0bc3f443299282b1da7e9dbfec60e12bf)) // label verified from nigwil's and andy's board + ROM_LOAD( "wb8146_058b1.mmi6309.pr1.ic99", 0x0000, 0x0100, CRC(71b01864) SHA1(e552f5b0bc3f443299282b1da7e9dbfec60e12bf)) // label verified from nigwil's and andy's board + + ROM_REGION( 0x20, "sync", ROMREGION_ERASEFF ) /* this is the "SYNC ROM" == mb6331 (32x8, 82s123) * It generates the ram RAS/CAS and a few other signals, see figure 5-20 on page 5-32 * The exact pins for each signal are not documented. @@ -1194,7 +1216,7 @@ ROM_START( vk100 ) * \--------- SYNC (latches the EXECUTE signal from an EXEC * write to activate the GO signal and enable the Vector rom) [verified via tracing] * The VT125 proms E64/E66 and their respective latches E65 and E83 are mostly equivalent to the sync rom */ - ROM_LOAD( "wb8014_297a1.74s288.pr6.ic89", 0x0200, 0x0020, CRC(e2f7c566) SHA1(a4c3dc5d07667141ad799168a862cb3c489b4934)) // label verified from nigwil's and andy's board + ROM_LOAD( "wb8014_297a1.74s288.pr6.ic89", 0x0000, 0x0020, CRC(e2f7c566) SHA1(a4c3dc5d07667141ad799168a862cb3c489b4934)) // label verified from nigwil's and andy's board ROM_END /* Driver */