/* Before any switch data can be accessed on a WPC-S * or WPC95 machine, we need to poll the PIC and see * if the unlock code must be sent to it. On pre- * security games, this function is a no-op. */ void pic_rtt (void) { #if (MACHINE_PIC == 1) U8 unlocked; /* Until initialization is complete, the PIC is not ready to receive unlock commands. */ if (sys_init_complete == 0) return; /* Read the status to see if the matrix is still unlocked. */ wpc_write_pic (WPC_PIC_COUNTER); null_function (); null_function (); null_function (); unlocked = wpc_read_pic (); if (!unlocked) { /* We need to unlock it again. */ extern U8 pic_unlock_code[3]; extern bool pic_unlock_ready; if (!pic_unlock_ready) return; /* The unlock sequence is four bytes long, but we can't write everything without some delay between bytes. The 'null_function' calls are there just to delay for a few tens of cycles. */ wpc_write_pic (WPC_PIC_UNLOCK); null_function (); null_function (); wpc_write_pic (pic_unlock_code[0]); null_function (); null_function (); wpc_write_pic (pic_unlock_code[1]); null_function (); null_function (); wpc_write_pic (pic_unlock_code[2]); null_function (); null_function (); } #endif /* MACHINE_PIC */ }
char * k_var_name(DESCRIPTOR * descr) { struct PROGRAM * pgm; OBJECT_HEADER * obj_header; long int sym_tab_offset; short int d_no; /* Descriptor number within program */ DESCRIPTOR * d; DESCRIPTOR * cd; short int cd_no; ARRAY_HEADER * ahdr; ARRAY_CHUNK * achnk; short int c_no = -1; /* Common block variable index */ ARRAY_HEADER * chdr; /* Common block header... */ ARRAY_CHUNK * cchnk; /* ...and chunk */ long int cols; long int element = -1; static char name[80+1]; /* Extracted variable name */ u_char * p; u_char * q; short int i; short int j; short int n; u_char c; u_char * xcbase; if (descr == NULL) return NULL; /* Track back through any recursives to report variable error as belonging to parent program. */ xcbase = c_base; pgm = &process.program; while(pgm->flags & HDR_RECURSIVE) { pgm = pgm->prev; xcbase = pgm->saved_c_base; } obj_header = (OBJECT_HEADER *)xcbase; if ((sym_tab_offset = obj_header->sym_tab_offset) == 0) return NULL; /* Follow ADDR chain to base descriptor, stopping if we find an ADDR that represents a subroutine argument. */ while(descr->type == ADDR) { if (descr->flags & DF_ARG) break; descr = descr->data.d_addr; } /* Check decriptor is in variable area */ d_no = descr - pgm->vars; if ((d_no >= 0) && (d_no < pgm->no_vars)) goto found; null_function(); /* Just to stop the compiler optimiser */ /* No, is it a common variable or an array element? */ for(d_no = 0, d = pgm->vars; d_no < pgm->no_vars; d_no++, d++) { switch(d->type) { case ARRAY: element = 0; ahdr = d->data.ahdr_addr; cols = ahdr->cols; for(i = 0; i < ahdr->num_chunks; i++) { achnk = ahdr->chunk[i]; if ((descr >= achnk->descr) && (descr < (achnk->descr + achnk->num_descr))) { element += descr - achnk->descr; goto found; } element += achnk->num_descr; } break; case COMMON: c_no = 0; chdr = d->data.ahdr_addr; for(j = 0; j < chdr->num_chunks; j++) { cchnk = chdr->chunk[j]; if ((descr >= cchnk->descr) && (descr < (cchnk->descr + cchnk->num_descr))) { /* Variable is a simple common block entry */ c_no += descr - cchnk->descr - 1; /* -1 to skip block name */ goto found; } /* Check for arrays in this common chunk */ for(cd_no = 0, cd = cchnk->descr; cd_no < cchnk->num_descr; cd_no++, cd++) { if (cd->type == ARRAY) { element = 0; ahdr = cd->data.ahdr_addr; cols = ahdr->cols; for(i = 0; i < ahdr->num_chunks; i++) { achnk = ahdr->chunk[i]; if ((descr >= achnk->descr) && (descr < (achnk->descr + achnk->num_descr))) { c_no += cd - cchnk->descr - 1; /* -1 to skip block name */ element += descr - achnk->descr; goto found; } element += achnk->num_descr; } } } c_no += cchnk->num_descr; /* 0450 */ } c_no = -1; /* Didn' find it - make sure we don't treat as common */ break; } } return NULL; found: /* Identify the variable at offset d_no */ p = xcbase + sym_tab_offset; for(i = 0; (i < d_no) && ((q = (u_char *)strchr((char *)p, VALUE_MARK)) != NULL); i++) { p = q + 1; } if (i == d_no) /* Found start of symbol */ { q = (u_char *)name; if (c_no >= 0) /* Common block reference */ { *(q++) = '/'; } for (i = 0; i < 80; i++) { if ((p == NULL) || IsMark(*p) || (*p == '\0')) break; *(q++) = *(p++); } if (c_no >= 0) /* Add common block variable name */ { *(q++) = '/'; p = xcbase + sym_tab_offset; while((p = (u_char *)strchr((char *)p, (char)FIELD_MARK)) != NULL) { p++; /* Skip field mark */ /* Extract common block number */ n = 0; while(IsDigit(*p)) n = (n * 10) + (*(p++) - '0'); if (n == d_no) /* Found this common */ { p++; /* Skip VM before first name */ /* Step through to required variable name */ for (j = 0; (j < c_no) && (p != NULL); j++) { while((((char)(c = *(p++))) != SUBVALUE_MARK) && (c != '\0')) {} if (c == '\0') p = NULL; } /* Copy variable name */ if (p != NULL) { while((!IsMark(*p)) && (*p != '\0')) *(q++) = *(p++); break; } } } } switch(element) { case -1: /* Not an array */ *q = '\0'; break; case 0: /* Zero element */ sprintf((char *)q, (cols == 0)?"(0)":"(0,0)"); break; default: /* Some other element */ if (cols == 0) sprintf((char *)q, "(%ld)", element); else sprintf((char *)q, "(%ld,%ld)", ((element - 1) / cols) + 1, ((element - 1) % cols) + 1); break; } } return name; }