trunk/src/mess/drivers/vk100.c
| r21619 | r21620 | |
| 9 | 9 | Todo: |
| 10 | 10 | * fix vector generator hardware enough to pass the startup self test |
| 11 | 11 | the tests are described on page 6-5 thru 6-8 of the tech reference |
| 12 | | * hook up the direction and sync prom to the sync counter |
| 12 | * hook up the bresenham DU/DVM/ERR stuff, currently only simple directional vectors work |
| 13 | * hook up the vector and sync proms to the sync counter |
| 14 | * figure out how the erase prom actually works at a hardware level |
| 15 | * redump the vector prom, the first two bytes look bad |
| 13 | 16 | * figure out the correct meaning of systat b register - needed for communications selftest |
| 14 | 17 | * hook up smc com5016t baud generator to i8251 rx and tx clocks - begun |
| 15 | 18 | |
| 19 | Notes: |
| 20 | The directions for the DIR value are arranged, starting from the * |
| 21 | as the vector origin: |
| 22 | 3 2 1 |
| 23 | \ | / |
| 24 | \|/ |
| 25 | 4--*--0 |
| 26 | /|\ |
| 27 | / | \ |
| 28 | 5 6 7 |
| 29 | |
| 30 | The X and Y counters are techincally 12 bits long each, though |
| 31 | only the low 9 and 10 bits respectively are used for ram addressing. |
| 32 | The MSB bit of each counter does have a special purpose with |
| 33 | regards to the RAS/ERASE prom though, perhaps to detect an |
| 34 | underflow 000->FFF |
| 35 | |
| 16 | 36 | Tony DiCenzo, now the director of standards and architecture at Oracle, was on the team that developed the VK100 |
| 17 | 37 | see http://startup.nmnaturalhistory.org/visitorstories/view.php?ii=79 |
| 18 | 38 | Robert "Bob" C. Quinn was definitely lead engineer on the VT125 and may have been lead engineer on the VK100 as well |
| r21619 | r21620 | |
| 39 | 59 | |
| 40 | 60 | VK100 LOGICBOARD |
| 41 | 61 | |-------| |---------| |---------| |-| |-| |-| |-| |
| 42 | | |---|-20 mA-|----|---EIA---|--|HARD-COPY|----|B|-|G|-|R|--|-|----------| |
| 43 | | | BW DSW(8) | |
| 62 | |---|-20 mA-|----|---EIA---|--|HARD-COPY|----|B|-|G|-|R|--|-|--DSW(8)--| |
| 63 | | BW | |
| 44 | 64 | | POWER | |
| 45 | 65 | | PR2 | |
| 46 | 66 | | HD46505SP 4116 4116 4116 4116 | |
| r21619 | r21620 | |
| 121 | 141 | #undef SYSTAT_A_VERBOSE |
| 122 | 142 | #undef SYSTAT_B_VERBOSE |
| 123 | 143 | |
| 144 | // debug state dump for the vector generator |
| 145 | #undef DEBUG_VG_STATE |
| 146 | |
| 124 | 147 | #include "emu.h" |
| 125 | 148 | #include "cpu/i8085/i8085.h" |
| 126 | 149 | #include "sound/beep.h" |
| r21619 | r21620 | |
| 161 | 184 | UINT8* m_trans; |
| 162 | 185 | UINT8* m_pattern; |
| 163 | 186 | UINT8* m_dir; |
| 187 | UINT8* m_sync; |
| 188 | UINT8* m_vector; |
| 189 | UINT8* m_ras_erase; |
| 190 | UINT8 m_dir_a6; // latched a6 of dir rom |
| 191 | UINT8 m_cout; // carry out from vgERR adder |
| 164 | 192 | UINT8 m_vsync; // vsync pin of crtc |
| 165 | 193 | UINT16 m_vgX; |
| 166 | 194 | UINT16 m_vgY; |
| r21619 | r21620 | |
| 197 | 225 | DECLARE_READ8_MEMBER(SYSTAT_A); |
| 198 | 226 | DECLARE_READ8_MEMBER(SYSTAT_B); |
| 199 | 227 | DECLARE_DRIVER_INIT(vk100); |
| 200 | | virtual void machine_reset(); |
| 228 | virtual void machine_start(); |
| 201 | 229 | virtual void video_start(); |
| 202 | 230 | TIMER_CALLBACK_MEMBER(execute_vg); |
| 203 | 231 | DECLARE_WRITE_LINE_MEMBER(crtc_vsync); |
| r21619 | r21620 | |
| 262 | 290 | m_vram[(EA<<1)] = (block&0xFF00)>>8; // '' |
| 263 | 291 | } |
| 264 | 292 | |
| 293 | /* this is the "DIRECTION ROM" == mb6309 (256x8, 82s135) |
| 294 | * see figure 5-24 on page 5-39 |
| 295 | * It tells the direction and enable for counting on the X and Y counters |
| 296 | * and also handles the non-math related parts of the bresenham line algorithm |
| 297 | * control bits: |
| 298 | * /CE1 ----- DCOUNT 0 H [verified via tracing] |
| 299 | * /CE2 ----- ENA ERROR L [verified via tracing] |
| 300 | * addr bits: 76543210 |
| 301 | * ||||\\\\-- DIR (vgDIR register low 4 bits) |
| 302 | * |||\------ C OUT aka ERROR CARRY (strobed in by STROBE L from the error counter's adder) [verified via tracing] |
| 303 | * ||\------- Y0 (the otherwise unused lsb of the Y register, used for bresenham) [verified via tracing] |
| 304 | * |\-------- feedback bit from d5 strobed by V CLK [verified via tracing] |
| 305 | * \--------- GND; the second half of the prom is blank (0x00) |
| 306 | * data bits: 76543210 |
| 307 | * |||||||\-- ENA Y (enables change on Y counter) |
| 308 | * ||||||\--- ENA X (enables change on X counter) |
| 309 | * |||||\---- Y DIRECTION (high is count down, low is count up) |
| 310 | * ||||\----- X DIRECTION (high is count down, low is count up) |
| 311 | * |||\------ PIXEL WRT |
| 312 | * ||\------- feedback bit to a6, this bit is held in PRESET/1 condition by GO being inactive, and if the vector prom is disabled it is pulled to 1 [verified via tracing and schematics] |
| 313 | * |\-------- UNUSED, always 0 |
| 314 | * \--------- UNUSED, always 0 |
| 315 | * The VT125 prom @ E41 is literally identical to this, the same exact part: 23-059B1 |
| 316 | */ |
| 265 | 317 | TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) |
| 266 | 318 | { |
| 319 | m_cout = 1; // hack for now |
| 320 | UINT8 dirbyte = m_dir[(m_dir_a6<<6)|((m_vgY&1)<<5)|(m_cout<<4)|VG_DIR]; |
| 321 | #ifdef DEBUG_VG_STATE |
| 322 | static const char *const vg_functions[] = { "Move", "Dot", "Vector", "Erase" }; |
| 323 | 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); |
| 324 | #endif |
| 325 | m_dir_a6 = m_vgGO?((dirbyte&0x20)>>5):1; |
| 326 | if (dirbyte&2) // ena_x is active |
| 327 | { |
| 328 | if (dirbyte&0x80) m_vgX--; |
| 329 | else m_vgX++; |
| 330 | } |
| 331 | if (dirbyte&1) // ena_y is active |
| 332 | { |
| 333 | if (dirbyte&0x40) m_vgY--; |
| 334 | else m_vgY++; |
| 335 | } |
| 336 | if (dirbyte&0x10) m_vgDownCount--; // decrement the down counter |
| 267 | 337 | UINT8 thisNyb = vram_read(); // read in the nybble |
| 268 | 338 | // pattern rom addressing is a complex mess. see the pattern rom def later in this file. |
| 269 | 339 | 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 |
| 270 | 340 | // 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) |
| 341 | // but only do it if the direction rom said so! |
| 271 | 342 | switch (m_VG_MODE) |
| 272 | 343 | { |
| 273 | 344 | case 0: // move; adjusts the x and y but doesn't write anything. do nothing |
| r21619 | r21620 | |
| 275 | 346 | case 1: // dot: only write the LAST pixel in the chain? TODO: some fallthrough magic here? |
| 276 | 347 | if ((m_vgDownCount) == 0x00) |
| 277 | 348 | { |
| 278 | | vram_write(newNyb); // write out the modified nybble |
| 349 | if (dirbyte&0x10) vram_write(newNyb); // write out the modified nybble |
| 279 | 350 | } |
| 280 | 351 | break; |
| 281 | 352 | case 2: // vec: draw the vector |
| 282 | | vram_write(newNyb); // write out the modified nybble |
| 353 | if (dirbyte&0x10) vram_write(newNyb); // write out the modified nybble |
| 283 | 354 | break; |
| 284 | 355 | case 3: // er: erase: special case here: wipe the entire screen (except for color/attrib?) and then set done. |
| 285 | 356 | for (int i = 0; i < 0x8000; i++) |
| r21619 | r21620 | |
| 292 | 363 | m_vgGO = 0; // done |
| 293 | 364 | break; |
| 294 | 365 | } |
| 295 | | /* this is the "DIRECTION ROM" == mb6309 (256x8, 82s135) |
| 296 | | * see figure 5-24 on page 5-39 |
| 297 | | * It tells the direction and enable for counting on the X and Y counters |
| 298 | | * and also handles the non-math related parts of the bresenham line algorithm |
| 299 | | * control bits: |
| 300 | | * /CE1 ----- DCOUNT 0 H [verified via tracing] |
| 301 | | * /CE2 ----- ENA ERROR L [verified via tracing] |
| 302 | | * addr bits: 76543210 |
| 303 | | * ||||\\\\-- DIR (vgDIR register low 4 bits) |
| 304 | | * |||\------ C OUT aka ERROR CARRY (strobed in by STROBE L from the error counter's adder) [verified via tracing] |
| 305 | | * ||\------- Y0 (the otherwise unused lsb of the Y register, used for bresenham) [verified via tracing] |
| 306 | | * |\-------- feedback bit from d5 strobed by V CLK [verified via tracing] |
| 307 | | * \--------- GND; the second half of the prom is blank (0x00) |
| 308 | | * data bits: 76543210 |
| 309 | | * |||||||\-- ENA X (enables change on X counter) |
| 310 | | * ||||||\--- ENA Y (enables change on Y counter) |
| 311 | | * |||||\---- Y DIRECTION (high is count down, low is count up) |
| 312 | | * ||||\----- X DIRECTION (high is count down, low is count up) |
| 313 | | * |||\------ PIXEL WRT |
| 314 | | * ||\------- feedback bit to a6, this bit is held in PRESET/1 condition by GO being inactive, and if the vector prom is disabled it is pulled to 1 [verified via tracing and schematics] |
| 315 | | * |\-------- UNUSED, always 0 |
| 316 | | * \--------- UNUSED, always 0 |
| 317 | | * The VT125 prom @ E41 is literally identical to this, the same exact part: 23-059B1 |
| 318 | | */ |
| 319 | | //UINT8 direction_rom = m_dir[]; |
| 320 | | // HACK: we need the proper direction rom dump for this! |
| 321 | | switch(VG_DIR&0x7) |
| 322 | | { |
| 323 | | case 0: |
| 324 | | m_vgX++; |
| 325 | | break; |
| 326 | | case 7: |
| 327 | | m_vgX++; |
| 328 | | m_vgY++; |
| 329 | | break; |
| 330 | | case 6: |
| 331 | | m_vgY++; |
| 332 | | break; |
| 333 | | case 5: |
| 334 | | m_vgX--; |
| 335 | | m_vgY++; |
| 336 | | break; |
| 337 | | case 4: |
| 338 | | m_vgX--; |
| 339 | | break; |
| 340 | | case 3: |
| 341 | | m_vgX--; |
| 342 | | m_vgY--; |
| 343 | | break; |
| 344 | | case 2: |
| 345 | | m_vgY--; |
| 346 | | break; |
| 347 | | case 1: |
| 348 | | m_vgX++; |
| 349 | | m_vgY--; |
| 350 | | break; |
| 351 | | } |
| 352 | | m_vgDownCount--; // decrement the down counter |
| 353 | 366 | if ((m_vgDownCount) == 0x00) m_vgGO = 0; // check if the down counter hit terminal count (0), if so we're done. |
| 354 | 367 | if (((++m_vgPMUL_Count)&0xF)==0) // if pattern multiplier counter overflowed |
| 355 | 368 | { |
| r21619 | r21620 | |
| 850 | 863 | INPUT_PORTS_END |
| 851 | 864 | |
| 852 | 865 | |
| 853 | | void vk100_state::machine_reset() |
| 866 | void vk100_state::machine_start() |
| 854 | 867 | { |
| 855 | 868 | beep_set_frequency( m_speaker, 116 ); //116 hz (page 172 of TM), but duty cycle is wrong here! |
| 856 | 869 | output_set_value("online_led",1); |
| r21619 | r21620 | |
| 861 | 874 | output_set_value("l1_led", 1); |
| 862 | 875 | output_set_value("l2_led", 1); |
| 863 | 876 | m_vsync = 0; |
| 877 | m_dir_a6 = 1; |
| 878 | m_cout = 0; |
| 864 | 879 | m_vgX = 0; |
| 865 | 880 | m_vgY = 0; |
| 866 | 881 | m_vgERR = 0; |
| r21619 | r21620 | |
| 926 | 941 | m_trans = memregion("trans")->base(); |
| 927 | 942 | m_pattern = memregion("pattern")->base(); |
| 928 | 943 | m_dir = memregion("dir")->base(); |
| 944 | m_sync = memregion("sync")->base(); |
| 945 | m_vector = memregion("vector")->base(); |
| 946 | m_ras_erase = memregion("ras_erase")->base(); |
| 929 | 947 | } |
| 930 | 948 | |
| 931 | 949 | static MC6845_UPDATE_ROW( vk100_update_row ) |
| r21619 | r21620 | |
| 1081 | 1099 | * |\-------- feedback bit from d5 strobed by V CLK [verified via tracing] |
| 1082 | 1100 | * \--------- GND; the second half of the prom is blank (0x00) |
| 1083 | 1101 | * data bits: 76543210 |
| 1084 | | * |||||||\-- ENA X (enables change on X counter) |
| 1085 | | * ||||||\--- ENA Y (enables change on Y counter) |
| 1102 | * |||||||\-- ENA Y (enables change on X counter) [works with code] |
| 1103 | * ||||||\--- ENA X (enables change on Y counter) [works with code] |
| 1086 | 1104 | * |||||\---- Y DIRECTION (high is count down, low is count up) |
| 1087 | 1105 | * ||||\----- X DIRECTION (high is count down, low is count up) |
| 1088 | 1106 | * |||\------ PIXEL WRT |
| r21619 | r21620 | |
| 1093 | 1111 | */ |
| 1094 | 1112 | ROM_LOAD( "wb8141_059b1.tbp18s22.pr5.ic108", 0x0000, 0x0100, CRC(4b63857a) SHA1(3217247d983521f0b0499b5c4ef6b5de9844c465)) // label verified from andy's board |
| 1095 | 1113 | |
| 1096 | | ROM_REGION( 0x400, "proms", ROMREGION_ERASEFF ) |
| 1114 | ROM_REGION( 0x100, "ras_erase", ROMREGION_ERASEFF ) |
| 1097 | 1115 | /* this is the "RAS/ERASE ROM" involved with driving the RAS lines and erasing VRAM dram (256*4, 82s129) |
| 1098 | 1116 | * control bits: |
| 1099 | 1117 | * /CE1 ----- /WRITE aka WRITE L (pin 6 of vector rom after being latched by its ls273) [verified via tracing and vt125 schematic] |
| r21619 | r21620 | |
| 1133 | 1151 | * |
| 1134 | 1152 | */ |
| 1135 | 1153 | ROM_LOAD( "wb8151_573a2.mmi6301.pr3.ic44", 0x0000, 0x0100, CRC(75885a9f) SHA1(c721dad6a69c291dd86dad102ed3a8ddd620ecc4)) // label verified from nigwil's and andy's board |
| 1154 | |
| 1155 | ROM_REGION( 0x100, "vector", ROMREGION_ERASEFF ) |
| 1136 | 1156 | // WARNING: it is possible that the first two bytes of this prom are bad! |
| 1137 | 1157 | /* this is the "VECTOR ROM" (256*8, 82s135) which runs the vector generator state machine |
| 1138 | 1158 | * the vector rom bits are complex and are unfortunately poorly documented |
| r21619 | r21620 | |
| 1169 | 1189 | * |
| 1170 | 1190 | * The VT125 prom E71 and its latch E70 is mostly equivalent to the vector prom, but the address order is different |
| 1171 | 1191 | */ |
| 1172 | | ROM_LOAD( "wb8146_058b1.mmi6309.pr1.ic99", 0x0100, 0x0100, CRC(71b01864) SHA1(e552f5b0bc3f443299282b1da7e9dbfec60e12bf)) // label verified from nigwil's and andy's board |
| 1192 | ROM_LOAD( "wb8146_058b1.mmi6309.pr1.ic99", 0x0000, 0x0100, CRC(71b01864) SHA1(e552f5b0bc3f443299282b1da7e9dbfec60e12bf)) // label verified from nigwil's and andy's board |
| 1193 | |
| 1194 | ROM_REGION( 0x20, "sync", ROMREGION_ERASEFF ) |
| 1173 | 1195 | /* this is the "SYNC ROM" == mb6331 (32x8, 82s123) |
| 1174 | 1196 | * It generates the ram RAS/CAS and a few other signals, see figure 5-20 on page 5-32 |
| 1175 | 1197 | * The exact pins for each signal are not documented. |
| r21619 | r21620 | |
| 1194 | 1216 | * \--------- SYNC (latches the EXECUTE signal from an EXEC * write to activate the GO signal and enable the Vector rom) [verified via tracing] |
| 1195 | 1217 | * The VT125 proms E64/E66 and their respective latches E65 and E83 are mostly equivalent to the sync rom |
| 1196 | 1218 | */ |
| 1197 | | ROM_LOAD( "wb8014_297a1.74s288.pr6.ic89", 0x0200, 0x0020, CRC(e2f7c566) SHA1(a4c3dc5d07667141ad799168a862cb3c489b4934)) // label verified from nigwil's and andy's board |
| 1219 | ROM_LOAD( "wb8014_297a1.74s288.pr6.ic89", 0x0000, 0x0020, CRC(e2f7c566) SHA1(a4c3dc5d07667141ad799168a862cb3c489b4934)) // label verified from nigwil's and andy's board |
| 1198 | 1220 | ROM_END |
| 1199 | 1221 | |
| 1200 | 1222 | /* Driver */ |