Modular Pinball Machine Controller
|
00001 #ifndef PINKIT_H 00002 #define PINKIT_H 00003 00014 #include "pinkit_defs.h" 00015 #include "types.h" 00016 00017 //define PK_SOUND 00018 //define AUXGI_MODE 00019 00020 #if defined(PK_SOUND) 00021 #warning pinkit.h: pk_sound mode in pk_common 00022 #endif 00023 00024 /* These should be in pinkit_defs.h file */ 00025 #define COIL0 LATAbits.LATA5 00026 #define COIL1 LATAbits.LATA4 00027 #define COIL2 LATAbits.LATA3 00028 #define COIL3 LATAbits.LATA2 00029 #define COIL4 coil_dummy 00030 #define COIL5 coil_dummy 00031 #define COIL6 coil_dummy 00032 #define COIL7 coil_dummy 00033 00034 #define LAMP0 LATAbits.LATA0 00035 #define LAMP1 LATAbits.LATA1 00036 #define LAMP2 LATBbits.LATB6 00037 #define LAMP3 LATBbits.LATB7 00038 #define LAMP4 LATCbits.LATC4 00039 #define LAMP5 LATCbits.LATC5 00040 #define LAMP6 LATCbits.LATC6 00041 #define LAMP7 LATCbits.LATC7 00042 00043 #define SW0 PORTCbits.RC0 00044 #define SW1 PORTCbits.RC1 00045 #define SW2 PORTCbits.RC2 00046 #define SW3 PORTCbits.RC3 00047 #define SW4 PORTCbits.RC4 00048 #define SW5 PORTCbits.RC5 00049 #define SW6 PORTCbits.RC6 00050 #define SW7 PORTCbits.RC7 00051 00052 #define ID0 PORTBbits.RB5 00053 #define ID1 PORTBbits.RB4 00054 #define ID2 PORTBbits.RB1 00055 #define ID3 PORTBbits.RB0 00056 00057 00058 //define BLINK_RATE(n) (UINT16) (2000L >> (n)) 00059 #define ERROR_FLAG(n) reg[15] |= ((BYTE)(1UL << (n))) 00060 #define TEST_DELAY 200 00061 00062 00063 /* Note that space is reserved for 16 devices to avoid having out-of-range checks on the */ 00064 /* incoming messages. Targeting a device that doesn't exist will be a no-op. */ 00065 #if defined (PK_SOUND) 00066 #define MAX_LAMPS 0 00067 #define MAX_SWITCHES 1 00068 #define MAX_COILS 0 00069 #define MAX_DIGITS 1 00070 #define MAX_REGS 16 00071 #else 00072 #if !defined (MAX_LAMPS) 00073 #define MAX_LAMPS 16 00074 #endif 00075 #define MAX_SWITCHES 16 00076 #define MAX_COILS 16 00077 #define MAX_DIGITS 7 00078 #define MAX_REGS 16 00079 #endif 00080 00091 #if !defined(MAX_PLAYER) 00092 #define MAX_PLAYER 1 00093 #endif 00094 00095 #if !defined(COIL_PULSE) 00096 #define COIL_PULSE 40 00097 #endif 00098 00099 #if !defined(MAX_CREDITS) 00100 #define MAX_CREDITS 29 00101 #endif 00102 00103 #if !defined(PK_SOUND) 00104 #if !defined(MAX_ATTRACT) 00105 #define MAX_ATTRACT 64 00106 #endif 00107 #endif 00108 #define BALL_WDT 200 /* 20 seconds */ 00109 00118 typedef union PK_MSG_ID_T { 00119 unsigned long id; 00120 struct { 00121 BYTE BYTE_0; 00122 BYTE BYTE_1; 00123 BYTE BYTE_2; 00124 BYTE BYTE_3; 00125 } u; 00126 } PK_MSG_ID; 00127 00134 struct LAMP { 00135 BYTE state; 00136 BYTE group; 00137 union { 00138 UINT16 patt_all; 00139 struct { BYTE patt_lo; 00140 BYTE patt_hi; 00141 }; 00142 } pattern; 00143 UINT16 timer; 00144 BYTE blink; 00145 }; 00146 extern BYTE cmd_patt[2]; 00147 00148 #define SW_LEVEL 0x7F 00149 #define SW_EDGE_SLOWEST 0x3F 00150 #define SW_EDGE_SLOW 0x1F 00151 #define SW_EDGE_MED 0x07 00152 #define SW_EDGE 0x03 00153 #define SW_EDGE_FAST 0x01 00154 00157 struct SW { 00158 BYTE state; 00159 BYTE type; 00160 BYTE score; 00161 BYTE coil; 00162 BYTE cmd[2]; 00163 }; 00164 00168 struct COIL { 00169 BYTE state; 00170 BYTE timer; 00171 BYTE max; 00172 }; 00173 00178 struct PK_CMD_FUNC { 00179 BYTE ttype; 00180 union { 00181 BYTE cmd[2]; 00182 void (*func)(void); 00183 } fc; 00184 }; 00185 00186 struct EVENT { 00187 BYTE next; 00188 struct PK_CMD_FUNC u; 00189 }; 00190 00194 struct PK_QCMD { 00195 BYTE cmd1; 00196 BYTE cmd2; 00197 }; 00198 00199 #ifdef CPU_MODE 00200 #define ATTRACT_OFF 0 00201 #define ATTRACT_SWEEP_LEFT 1 00202 #define ATTRACT_SWEEP_RIGHT 2 00203 #define ATTRACT_CHASE 3 00204 #define ATTRACT_SWEEP_UP 4 00205 #define ATTRACT_SWEEP_DOWN 5 00206 #define ATTRACT_FADE_ON 6 00207 #define ATTRACT_FADE_OFF 7 00208 #define ATTRACT_TWINKLE 8 00209 #define ATTRACT_RANDOM 9 00210 #define ATTRACT_RESET 10 00211 #define MAX_ATTRACT_MODE 9 00212 00213 extern struct { 00214 BYTE lampID; 00215 BYTE x; 00216 BYTE y; 00217 } attract[64]; 00218 extern BYTE attract_rate; 00219 extern BYTE attract_enable = 0xFF; 00220 #endif 00221 00233 typedef enum { 00234 MS_RESET = 0, 00235 MS_GAME_OVER, 00236 MS_NEW_GAME, 00237 MS_NEW_BALL, 00238 MS_LAUNCH_BALL, 00239 MS_PLAY_BALL, 00241 MS_COLLECT_BONUS, 00242 MS_END_BALL, 00243 MS_CUSTOM1, 00244 MS_CUSTOM2, 00245 MS_MATCH1, 00246 MS_MATCH2, 00247 MS_END_GAME, 00248 MS_ABORT_GAME, 00249 MS_TILT, 00250 MS_SLAM, 00251 MS_SLAM_HOLD, 00252 MS_ATTRACT, MS_ATTRACT_OFF, 00253 MS_NV_UPDATE, 00254 MS_DIAG, MS_DIAG_ADJUST1, MS_DIAG_ADJUST2, MS_DIAG_LAMP, MS_DIAG_COIL, MS_DIAG_SWITCH, MS_DIAG_PINCAN, 00255 MS_CLOCK } MACHINE_STATE; 00256 00257 //define ID_PANIC 0x110 /* Lower IDs have higher priority in CAN protocol */ 00258 //define ID_DIAG 0x120 00259 //define ID_COIL 0x140 00260 //define ID_SW 0x150 00261 //define ID_LAMP 0x160 00262 //define ID_SCORE 0x180 00263 //define ID_SOUND 0x190 00264 //define ID_LOWPRI 0x1E0 00265 00266 #define MSG_REG_READ 0x00 00267 #define MSG_REG_WRITE 0x10 00268 #define MSG_2 0x20 00269 #define MSG_VOLUME 0x30 00270 #define MSG_COIL 0x40 00271 #define MSG_SW 0x50 00272 #define MSG_LAMP 0x60 00273 #define MSG_LGROUP 0x70 00274 #define MSG_SCORE 0x80 00275 #define MSG_SOUND 0x90 00276 #define MSG_PLAY 0x90 00277 #define MSG_ASSIGN 0xA0 00278 #define MSG_BLINK 0xB0 00279 #define MSG_CTL 0xC0 00280 #define MSG_D 0xD0 00281 #define MSG_XOP 0xE0 00282 #define MSG_USER 0xF0 00283 00284 #define MSG_COIL_OFF (MSG_COIL | 0x00) 00285 #define MSG_COIL_ON (MSG_COIL | 0x0F) 00286 #define MSG_COIL_PULSE (MSG_COIL | 0x03) 00287 00288 #define MSG_SW_OFF (MSG_SW | 0x00) 00289 #define MSG_SW_ON (MSG_SW | 0x01) 00290 #define MSG_SW_EDGE (MSG_SW | SW_EDGE) 00291 #define MSG_SW_QUERY (MSG_SW | 0x04) 00292 00293 #define MSG_LAMP_OFF (MSG_LAMP | 0x00) 00294 #define MSG_LAMP_ON (MSG_LAMP | 0x0F) 00295 00296 #define MSG_LGROUP_OFF (MSG_LGROUP | 0x00) 00297 #define MSG_LGROUP_ON (MSG_LGROUP | 0x01) 00298 #define MSG_LGROUP_RESET (MSG_LGROUP | 0x03) 00299 #define MSG_LGROUP_TOGGLE (MSG_LGROUP | 0x04) 00300 #define MSG_LAMP_FLASH 0x77 00301 00302 #define MSG_SCORE_RESET (MSG_SCORE | 0x00) 00303 #define MSG_SET_PLAYER (MSG_SCORE | 0x01) 00304 #define MSG_SCORE_SET (MSG_SCORE | 0x02) 00305 #define MSG_SCORE_ADD (MSG_SCORE | 0x08) 00306 00307 #define TRACK1 0x00 00308 #define TRACK2 0x01 00309 #define TRACK3 0x02 00310 #define TRACK_ALL 0x03 00311 #define VOL_MASTER 0x03 00312 00313 #define CHANNEL_RIGHT 0x04 00314 #define CHANNEL_LEFT 0x08 00315 #define CHANNEL_BOTH 0x0C 00316 00317 #define MSG_VOLUME_MASTER (MSG_VOLUME | VOL_MASTER | CHANNEL_BOTH) 00318 #define MSG_VOLUME_MASTER_RIGHT (MSG_VOLUME | VOL_MASTER | CHANNEL_RIGHT) 00319 #define MSG_VOLUME_MASTER_LEFT (MSG_VOLUME | VOL_MASTER | CHANNEL_LEFT) 00320 #define MSG_VOLUME_TRACK1 (MSG_VOLUME | TRACK1 | CHANNEL_BOTH) 00321 #define MSG_VOLUME_TRACK2 (MSG_VOLUME | TRACK2 | CHANNEL_BOTH) 00322 #define MSG_VOLUME_TRACK3 (MSG_VOLUME | TRACK3 | CHANNEL_BOTH) 00323 #define MSG_SET_SOUND_BANK (MSG_VOLUME | 0x00); 00324 00325 #define MSG_PLAY_STOP (MSG_PLAY | 0x00) 00326 #define MSG_PLAY_ONCE (MSG_PLAY | 0x04) 00327 #define MSG_PLAY_NEXT (MSG_PLAY | 0x08) 00328 #define MSG_PLAY_REPEAT (MSG_PLAY | 0x0C) 00329 00330 #define MSG_PLAY_TRACK1 (MSG_PLAY_ONCE | TRACK1) 00331 #define MSG_PLAY_TRACK2 (MSG_PLAY_ONCE | TRACK2) 00332 #define MSG_PLAY_TRACK3 (MSG_PLAY_ONCE | TRACK3) 00333 00334 #define MSG_NOP (MSG_CTL | 0x04) 00335 #define MSG_TIMER_SYNC (MSG_CTL | 0x05) 00336 #define MSG_SET_MODE (MSG_CTL | 0x06) 00337 #define MSG_RESET_MODE (MSG_CTL | 0x07) 00338 #define MSG_NEW_GAME (MSG_CTL | 0x0A) 00339 #define MSG_GAME_OVER (MSG_CTL | 0x0B) 00340 #define MSG_NEW_BALL (MSG_CTL | 0x0E) 00341 #define MSG_TILT (MSG_CTL | 0x0F) 00342 00343 #define COIL0_ON COIL0 = 0; 00344 #define COIL1_ON COIL1 = 0; 00345 #define COIL2_ON COIL2 = 0; 00346 #define COIL3_ON COIL3 = 0; 00347 #define COIL4_ON COIL4 = 0; 00348 #define COIL5_ON COIL5 = 0; 00349 #define COIL6_ON COIL6 = 0; 00350 #define COIL7_ON COIL7 = 0; 00351 00352 #define COIL0_OFF COIL0 = 1; 00353 #define COIL1_OFF COIL1 = 1; 00354 #define COIL2_OFF COIL2 = 1; 00355 #define COIL3_OFF COIL3 = 1; 00356 #define COIL4_OFF COIL4 = 1; 00357 #define COIL5_OFF COIL5 = 1; 00358 #define COIL6_OFF COIL6 = 1; 00359 #define COIL7_OFF COIL7 = 1; 00360 00361 #define ROW0_ON COIL0 = 1; 00362 #define ROW1_ON COIL1 = 1; 00363 #define ROW2_ON COIL2 = 1; 00364 #define ROW3_ON COIL3 = 1; 00365 00366 #define ROW0_OFF COIL0 = 0; 00367 #define ROW1_OFF COIL1 = 0; 00368 #define ROW2_OFF COIL2 = 0; 00369 #define ROW3_OFF COIL3 = 0; 00370 00371 #define LAMP0_ON LAMP0 = 1; 00372 #define LAMP1_ON LAMP1 = 1; 00373 #define LAMP2_ON LAMP2 = 1; 00374 #define LAMP3_ON LAMP3 = 1; 00375 #define LAMP4_ON LAMP4 = 1; 00376 #define LAMP5_ON LAMP5 = 1; 00377 #define LAMP6_ON LAMP6 = 1; 00378 #define LAMP7_ON LAMP7 = 1; 00379 00380 #define LAMP0_OFF LAMP0 = 0; 00381 #define LAMP1_OFF LAMP1 = 0; 00382 #define LAMP2_OFF LAMP2 = 0; 00383 #define LAMP3_OFF LAMP3 = 0; 00384 #define LAMP4_OFF LAMP4 = 0; 00385 #define LAMP5_OFF LAMP5 = 0; 00386 #define LAMP6_OFF LAMP6 = 0; 00387 #define LAMP7_OFF LAMP7 = 0; 00388 00389 #define ROW0_ON COIL0 = 1; 00390 #define ROW1_ON COIL1 = 1; 00391 #define ROW2_ON COIL2 = 1; 00392 #define ROW3_ON COIL3 = 1; 00393 00394 #define ROW0_OFF COIL0 = 0; 00395 #define ROW1_OFF COIL1 = 0; 00396 #define ROW2_OFF COIL2 = 0; 00397 #define ROW3_OFF COIL3 = 0; 00398 00399 #define CMD_ON 0x01 00400 #define CMD_OFF 0x00 00401 #define CMD_PULSE_STRONG 0x05 00402 #define CMD_PULSE 0x03 00403 #define CMD_PULSE_WEAK 0x02 00404 00405 #define PK_MODE_MODE1 0x01 00406 #define PK_MODE_MODE2 0x02 00407 #define PK_MODE_MODE3 0x04 00408 #define PK_MODE_MODE4 0x08 00409 #define PK_MODE_DIAG 0x40 00410 #define PK_MODE_REVERSE 0x80 00411 00412 00413 00414 #define POLY 0xF1A7 00415 00416 #if defined(PK_SOUND) 00417 #define MAX_EVENTS 1 00418 #define MAX_EVENTS_MASK 0x01; 00419 #define WHEELSIZE 1 00420 #else 00421 #define MAX_EVENTS 32 00422 #define MAX_EVENTS_MASK 0x1F; 00423 #define MAX_SCHED 32 00424 #define WHEELSIZE 64 00425 #define WHEELSIZE_MASK 0x3F 00426 #endif 00427 00428 extern BYTE wheel[WHEELSIZE]; 00429 extern struct EVENT eventq[MAX_SCHED]; 00430 00431 /* PinKit Controller Variables */ 00432 #if MAX_LAMPS > 0 00433 extern struct LAMP lamp[MAX_LAMPS]; 00434 #endif 00435 00436 extern struct SW sw[MAX_SWITCHES]; 00437 #if MAX_COILS > 0 00438 extern struct COIL coil[MAX_COILS]; 00439 #endif 00440 00441 /* Predefine the COIL_PULSE multiplication to avoid multiply operation */ 00442 extern BYTE PULSE_LOOKUP[]; 00443 extern UINT16 BLINK_RATE[]; 00444 00445 /* Score Reel (SR) State */ 00446 #define SR_ENABLE 0 00447 #define SR_SYNC 1 00448 #define SR_UNKNOWN 2 00449 #define SR_DISABLE 3 00450 00451 extern BYTE player; 00452 extern BYTE score[MAX_PLAYER][MAX_DIGITS]; /* 8 digits for each player */ 00453 extern BYTE reel[MAX_DIGITS]; /* current score reel position */ 00454 extern BYTE reg[16]; 00455 00456 extern BYTE num_digits; 00457 BYTE score_reset(void); 00458 void zero_scores(BYTE n); 00459 00469 void set_scores(BYTE n); 00470 00481 void add_score(BYTE player, BYTE value); 00482 00483 00484 #define SEND_PINCAN_MSG(id, data) while(!ECANSendMessage(id, data, 2, ECAN_TX_STD_FRAME)) 00485 00486 /* Low priority message, 1 try only */ 00487 #define SEND_PINCAN_MSG_LP(id, data) ECANSendMessage(id, data, 2, ECAN_TX_STD_FRAME) 00488 00489 00501 UINT16 rand_lfsr(UINT16 min, UINT16 max, BYTE mask); 00502 BYTE rand8(BYTE min, BYTE max); 00503 00530 int choice16(UINT16 *list, BYTE min, BYTE max); 00531 00537 void pinkit_init(void); 00538 00563 BYTE ensched_cmd(BYTE time, BYTE cmd1, BYTE cmd2); 00564 BYTE ensched_fn(BYTE time, void (*func)(void)); 00565 /* returns the next entry from the requested time slot */ 00566 00584 BYTE desched(BYTE time); 00585 00586 00596 BYTE enqueue(BYTE cmd1, BYTE cmd2); 00597 00604 BYTE dequeue(BYTE *cmd1, BYTE *cmd2); 00605 void requeue(void); 00606 00607 00608 /* coil_on: Drive the PIN to turn coil n ON */ 00609 void coil_on(BYTE n); 00610 00611 /* coil_off: Drive the PIN to turn coil n OFF */ 00612 void coil_off(BYTE n); 00613 00614 /* lamp_on: Drive the PIN to turn lamp n ON */ 00615 void lamp_on(BYTE n); 00616 00617 /* lamp_off: Drive the PIN to turn lamp n ON */ 00618 void lamp_off(BYTE n); 00619 00620 void local_coil_pulse(BYTE n, BYTE dur); 00621 00622 #if MAX_LAMPS > 0 00623 void lamp_group_assign(BYTE lnum, BYTE group); 00624 void lamp_group_on(BYTE group); 00625 void lamp_group_off(BYTE group); 00626 void lamp_group_reset(BYTE group); 00627 void lamp_group_toggle(BYTE group); 00628 void set_lamp(BYTE lnum, BYTE state, BYTE pwm, BYTE blink); 00629 #endif 00630 00631 #endif /*PINKIT_H*/