int main(void) { trit a; puts("[Not]"); forall(a) printf("%c | %c\n", t_s(a), t_s(t_not(a))); show_op(t_and, "And"); show_op(t_or, "Or"); show_op(t_eq, "Equiv"); show_op(t_imply, "Imply"); return 0; }
//------------------------------------------------------------------------ int notmain ( void ) { unsigned int ra; unsigned int rb; unsigned int rc; unsigned int rd; unsigned int re; uart_send(0x0D); uart_send(0x0A); uart_send(0x0A); rd=0x0432; re=0x0137; for(ra=0;ra<4;ra++) { for(rb=0;rb<4;rb++) { rc=atest(ra<<30,rb<<30); show_op(ra); show_op(rb); if(rc&1) uart_send(0x31); else uart_send(0x30); if(rd&0x8000) uart_send(0x31); else uart_send(0x30); rd<<=1; uart_send(0x20); if(rc&2) uart_send(0x31); else uart_send(0x30); if(re&0x8000) uart_send(0x31); else uart_send(0x30); re<<=1; uart_send(0x0D); uart_send(0x0A); } } uart_send(0x0D); uart_send(0x0A); uart_send(0x0A); rd=0x2340; re=0x8CEF; for(ra=0;ra<4;ra++) { for(rb=0;rb<4;rb++) { rc=stest(ra<<30,rb<<30); show_op(ra); show_op(rb); if(rc&1) uart_send(0x31); else uart_send(0x30); if(rd&0x8000) uart_send(0x31); else uart_send(0x30); rd<<=1; uart_send(0x20); if(rc&2) uart_send(0x31); else uart_send(0x30); if(re&0x8000) uart_send(0x31); else uart_send(0x30); re<<=1; rc=ra-rb; if(rc&4) uart_send(0x30); else uart_send(0x31); uart_send(0x0D); uart_send(0x0A); } } uart_send(0x0D); uart_send(0x0A); uart_send(0x0A); return(0); }
/* process changes to resource file (or just list it) */ static opdef *rscproc(osfildef *fp, osfildef *fpout, opdef *oplist) { char buf[128]; ulong siz; char datebuf[27]; ulong endpos; uchar nambuf[40]; uint rsiz; opdef *op; int copyrsc; ulong startpos; uint endpos_ofs; ulong first_xfcn = 0; ulong extcnt_pos = 0; int found_user_rsc = FALSE; int showed_heading = FALSE; int found_htmlres = FALSE; char *file_type; /* * if we're reading an existing file, check it header; otherwise, * write out a brand new file header */ if (fp != 0) { /* * the input file exists -- check file and version headers, and * get flags and timestamp */ if (osfrb(fp, buf, (int)(sizeof(FIOFILHDR) + sizeof(FIOVSNHDR) + 2))) listexit(fp, "error reading file header"); /* check the file type */ if (memcmp(buf, FIOFILHDR, sizeof(FIOFILHDR)) == 0) file_type = "game"; else if (memcmp(buf, FIOFILHDRRSC, sizeof(FIOFILHDRRSC)) == 0) file_type = "resource"; else listexit(fp, "invalid resource file header"); /* check the version header */ if (memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR, sizeof(FIOVSNHDR)) && memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR2, sizeof(FIOVSNHDR2)) && memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR3, sizeof(FIOVSNHDR3))) listexit(fp, "incompatible resource file version"); /* get the timestamp */ if (osfrb(fp, datebuf, (size_t)26)) listexit(fp, "error reading file"); datebuf[26] = '\0'; } else { struct tm *tblock; time_t timer; /* construct a new file header */ memcpy(buf, FIOFILHDRRSC, sizeof(FIOFILHDRRSC)); memcpy(buf + sizeof(FIOFILHDR), FIOVSNHDR, sizeof(FIOVSNHDR)); /* clear the flags */ oswp2(buf + sizeof(FIOFILHDR) + sizeof(FIOVSNHDR), 0); /* construct the timestamp */ timer = time(0); tblock = localtime(&timer); strcpy(datebuf, asctime(tblock)); } if (fpout) { if (osfwb(fpout, buf, (int)(sizeof(FIOFILHDR) + sizeof(FIOVSNHDR) + 2)) || osfwb(fpout, datebuf, (size_t)26)) listexit(fp, "error writing header"); } /* if listing, show file creation timestamp */ if (fpout == 0) rscptf("\n" "File type: TADS %s file\n" "Date compiled: %s\n", file_type, datebuf); /* * Process the input file, if there is one */ for ( ; fp != 0 ; ) { /* assume this resource will be copied to the output */ copyrsc = TRUE; startpos = osfpos(fp); if (osfrb(fp, buf, 1) || osfrb(fp, buf + 1, (int)(buf[0] + 4))) listexit(fp, "error reading file"); memcpy(nambuf, buf + 1, (size_t)buf[0]); nambuf[buf[0]] = '\0'; endpos_ofs = 1 + buf[0]; endpos = osrp4(buf + endpos_ofs); siz = endpos - startpos; /* see what kind of resource we have, and do the right thing */ if (!strcmp((char *)nambuf, "$EOF")) { /* end of file marker - quit here */ break; } else if (!strcmp((char *)nambuf, "HTMLRES")) { /* if we've already found an HTMLRES list, it's an error */ if (found_htmlres) { rscptf("error: multiple HTMLRES maps found in file\n" " -- redundant entries have been deleted.\n"); copyrsc = FALSE; } else { /* go process it */ oplist = prochtmlres(fp, fpout, oplist, ©rsc, &showed_heading, TRUE); } /* note that we've found a resource */ found_user_rsc = TRUE; found_htmlres = TRUE; } else if (!strcmp((char *)nambuf, "EXTCNT")) { /* place to write start of XFCN's? */ if (siz >= 17 && fpout) extcnt_pos = osfpos(fpout); } else if (!strcmp((char *)nambuf, "XFCN")) { if (osfrb(fp, buf, 3) || osfrb(fp, buf + 3, (int)buf[2])) listexit(fp, "error reading file"); rsiz = osrp2(buf); buf[3 + buf[2]] = '\0'; if (fpout) { /* see if this resource is in the list */ for (op = oplist ; op ; op = op->opnxt) { if (!(op->opflag & OPFDONE) && op->oprestype == RESTYPE_XFCN && !stricmp((char *)buf + 3, op->opres)) { /* note that this resource has now been processed */ op->opflag |= OPFDONE; /* * if it's already here, and we're not deleting * it, warn that the old one will stay around */ if (!(op->opflag & OPFDEL)) { /* warn that we're going to ignore it */ rscptf("warning: XFCN resource \"%s\" already in " "file\n -- the old resource will be kept " "(use -replace to replace it)\n", op->opres); /* don't add it */ op->opflag &= ~OPFADD; } else { /* * we're deleting this resource; if adding * it back in (i.e., replacing it), process * the add operation now */ if (op->opflag & OPFADD) { /* show what we're doing */ show_op("replacing", op->opres, strlen(op->opres), op->oprestype); /* * add the external file, replacing the * one in the input file */ procop(fpout, op, &first_xfcn); } else { /* note that we're deleting it */ show_op("deleting", op->opres, strlen(op->opres), op->oprestype); } /* don't copy the one out of the file */ copyrsc = FALSE; } break; } } } else { /* no output file - just list the resource */ show_list_item(&showed_heading, "XFCN", (ulong)rsiz, buf + 3, (size_t)buf[2]); } /* note that we've found a user resource */ found_user_rsc = TRUE; } if (fpout != 0 && copyrsc) { osfseek(fp, startpos, OSFSK_SET); copyres(fp, fpout, siz, endpos_ofs); } /* skip to the next resource */ osfseek(fp, endpos, OSFSK_SET); } /* add the HTML resources if we haven't already */ if (!found_htmlres) oplist = prochtmlres(fp, fpout, oplist, ©rsc, &showed_heading, FALSE); /* now go through what's left, and add new non-HTML resources */ if (fpout != 0) { for (op = oplist ; op != 0 ; op = op->opnxt) { if (!(op->opflag & OPFDONE) && (op->opflag & OPFADD) && op->oprestype != RESTYPE_HTML) { /* show what we're doing */ show_op("adding", op->opres, strlen(op->opres), op->oprestype); /* add the file */ procop(fpout, op, &first_xfcn); /* mark the operation as completed */ op->opflag |= OPFDONE; } } } /* if just listing, and we didn't find anything, tell the user so */ if (fpout == 0 && !found_user_rsc) rscptf("No user resources found.\n"); /* done reading the file - finish it up */ if (fpout != 0) { /* write EOF resource */ if (osfwb(fpout, "\004$EOF\0\0\0\0", 9)) errexit("error writing resource", 1); /* write first_xfcn value to EXTCNT resource */ if (extcnt_pos) { osfseek(fpout, extcnt_pos + 13, OSFSK_SET); oswp4(buf, first_xfcn); osfwb(fpout, buf, 4); } } /* * return the final oplist (it may have been changed during * processing) */ return oplist; }
/* * Process an HTML resource list. If 'old_htmlres' is true, it * indicates that the input file is pointing to an old resource map; * otherwise, we need to construct a brand new one. */ static opdef *prochtmlres(osfildef *fp, osfildef *fpout, opdef *oplist, int *copyrsc, int *showed_heading, int old_htmlres) { opdef *op; opdef *add_list = 0; opdef *prev_op; opdef *next_op; int found; char buf[512]; ulong in_entry_cnt; ulong in_table_siz; ulong out_hdr_siz; ulong out_hdr_pos; ulong i; ulong out_res_cnt; ulong out_total_name_len; ulong rem; struct idx_t **in_list = 0, *out_list = 0, **p, *cur; ulong in_res_base, out_res_base; ulong out_endpos; /* * Scan the oplist for an HTML resource. If there aren't any, we * don't need to modify the HTMLRES list, so tell the caller to copy * this resource unchanged. */ for (op = oplist, found = FALSE ; op != 0 ; op = op->opnxt) { /* if this is an HTML resource, note it and stop looking */ if (op->oprestype == RESTYPE_HTML) { found = TRUE; break; } } /* * If we didn't find any operations on this resource, and we're not * simply listing resources or we don't have an old resource to * list, tell the caller to copy it unchanged. */ if (!found && (fpout != 0 || !old_htmlres)) { *copyrsc = TRUE; return oplist; } /* we'll be handling the resource - tell the caller not to copy it */ *copyrsc = FALSE; /* if there's an old HTMLRES resource, read it */ if (old_htmlres) { /* read the index entry count and size */ if (osfrb(fp, buf, 8)) listexit(fp, "unable to read HTMLRES header"); in_entry_cnt = osrp4(buf); in_table_siz = osrp4(buf + 4); /* allocate space for pointers to all of the entries */ if (in_entry_cnt != 0) { in_list = (struct idx_t **) malloc(in_entry_cnt * sizeof(struct idx_t *)); if (in_list == 0) listexit(fp, "unable to allocate space for HTMLRES entries"); } /* read the index table entries */ for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p) { ushort name_siz; ulong res_siz; ulong res_ofs; /* read the entry information */ if (osfrb(fp, buf, 10)) listexit(fp, "unable to read HTMLRES index table entry (prefix)"); /* get the resource size */ res_ofs = osrp4(buf); res_siz = osrp4(buf + 4); /* read the name */ name_siz = osrp2(buf + 8); if (name_siz > sizeof(buf)) listexit(fp, "name too large in HTMLRES index table entry"); if (osfrb(fp, buf, name_siz)) listexit(fp, "unable to read HTMLRES index table entry (name)"); /* build this entry */ *p = alloc_idx_entry(res_ofs, res_siz, buf, name_siz, 0, 0); } /* if we don't have an output file, list the HTMLRES contents */ if (fpout == 0) { /* display all of the entries */ for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p) show_list_item(showed_heading, "HTML", (*p)->siz, (*p)->nam, (*p)->namlen); /* there's no more processing to do */ goto done; } /* * The resources start at the end of the index table - note the * location of the end of the input table, since it's the base * address relative to which the resource offsets are stated. */ in_res_base = osfpos(fp); /* * Go through the resource table in the input file. Find each * one in the op list. If it's not in the op list, we'll copy * it to the output file. */ for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p) { int remove_res = FALSE; int add_res = FALSE; /* see if we can find this entry in the op list */ for (prev_op = 0, op = oplist ; op != 0 ; prev_op = op, op = op->opnxt) { /* if this one matches, note it */ if (op->oprestype == RESTYPE_HTML && strlen(op->opres) == (*p)->namlen && !memicmp(op->opres, (*p)->nam, (*p)->namlen)) { /* * if we're adding this resource (not replacing it), * warn that it's already in the file, and ignore * this op; if we're removing it or replacing it, * simply delete this entry from the input list so * it doesn't get copied to the output. */ if (!(op->opflag & OPFDEL)) { /* warn that the old one will stay */ rscptf("warning: HTML resource \"%s\" already " "present\n" " -- old version will be kept (use -replace " "to replace it)\n", op->opres); /* remove it from the processing list */ remove_res = TRUE; } else { /* we are deleting it; see if we're also adding it */ if (op->opflag & OPFADD) { /* * we're replacing this resource - take this * op out of the main list and put it into * the add list */ remove_res = TRUE; add_res = TRUE; /* note the addition */ show_op("replacing", op->opres, strlen(op->opres), op->oprestype); } else { /* note the deletion */ show_op("deleting", op->opres, strlen(op->opres), op->oprestype); /* just remove it */ remove_res = TRUE; } /* get rid of this item from the input list */ free(*p); *p = 0; } /* no need to look further in the operations list */ break; } } /* * If desired, remove this resource from the main list, and * add it into the list of resources to add. */ if (remove_res) { /* unlink it from the main list */ if (prev_op == 0) oplist = op->opnxt; else prev_op->opnxt = op->opnxt; /* if desired, add it to the additions list */ if (add_res) { /* we're adding it - put it in the additions list */ op->opnxt = add_list; add_list = op; } else { /* this item has been processed - delete it */ free(op); } } } } else { /* there are no entries in the input file */ in_entry_cnt = 0; in_table_siz = 0; } /* * Move all of the HTML resources marked as additions in the main * operations list into the additions list. */ for (prev_op = 0, op = oplist ; op != 0 ; op = next_op) { /* note the next op, in case we move this one to the other list */ next_op = op->opnxt; /* * if it's an HTML resource to be added, move it to the * additions list */ if (op->oprestype == RESTYPE_HTML && (op->opflag & OPFADD) != 0) { /* show what we're doing */ show_op("adding", op->opres, strlen(op->opres), op->oprestype); /* unlink it from the main list */ if (prev_op == 0) oplist = op->opnxt; else prev_op->opnxt = op->opnxt; /* add it to the additions list */ op->opnxt = add_list; add_list = op; /* * note that we don't want to advance the 'prev_op' pointer, * since we just removed this item - the previous item is * still the same as it was on the last iteration */ } else { /* * we're leaving this op in the original list - it's now the * previous op in the main list */ prev_op = op; } } /* * Figure out what we'll be putting in the HTMLRES list: we'll add * each surviving entry from the input file, plus all of the items * in the add list, plus all of the HTML items in the main list that * are marked for addition. */ out_res_cnt = 0; out_total_name_len = 0; /* count input file entries that we're going to copy */ for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p) { if (*p != 0) add_idx_entry(&out_list, &out_res_cnt, &out_total_name_len, 0, 0, (*p)->nam, (*p)->namlen, 0, *p); } /* * Count items in the additions list. Note that every HTML resource * marked for addition is in the additions list, since we moved all * such resources out of the main list and into the additions list * earlier. */ for (op = add_list ; op != 0 ; op = op->opnxt) add_idx_entry(&out_list, &out_res_cnt, &out_total_name_len, 0, 0, op->opres, (ushort)strlen(op->opres), op, 0); /* write the resource header */ if (osfwb(fpout, "\007HTMLRES\0\0\0\0", 12)) listexit(fp, "unable to write HTMLRES type header"); out_hdr_pos = osfpos(fpout); /* * Reserve space in the output file for the index table. We need * eight bytes for the index table prefix, then ten bytes per entry * plus the name sizes. */ out_hdr_siz = 8 + (10 * out_res_cnt) + out_total_name_len; /* write the index table prefix */ oswp4(buf, out_res_cnt); oswp4(buf + 4, out_hdr_siz); if (osfwb(fpout, buf, 8)) listexit(fp, "unable to write HTMLRES prefix"); /* * Reserve space for the headers. Don't actually write them yet, * since we don't know the actual locations and sizes of the * entries; for now, simply reserve the space, so that we can come * back here later and write the actual headers. Note that we * deduct the eight bytes we've already written from the amount of * filler to put in. */ for (rem = out_hdr_siz - 8 ; rem != 0 ; ) { ulong amt; /* write out a buffer full */ amt = (rem > sizeof(buf) ? sizeof(buf) : rem); if (osfwb(fpout, buf, amt)) listexit(fp, "unable to write HTMLRES header"); /* deduct the amount we wrote from the remainder */ rem -= amt; } /* * note the current position in the output file - this is the base * address of the resources */ out_res_base = osfpos(fpout); /* * Write the resources. */ for (cur = out_list ; cur != 0 ; cur = cur->nxt) { /* * note the current file position as an offset from the resource * base in the output file - this is the offset that we need to * store in the index entry for this object */ cur->ofs = osfpos(fpout) - out_res_base; /* * Copy the resource to the output. If it comes from the input * file, copy from there, otherwise go out and find the external * file and copy its contents. */ if (cur->src_op != 0) { osfildef *fpext; ulong fsiz; /* it comes from an external file - open the file */ fpext = osfoprb(cur->src_op->opfile, OSFTGAME); if (fpext == 0) { rscptf("%s: ", cur->src_op->opfile); errexit("unable to open file", 1); } /* figure the size of the file */ osfseek(fpext, 0L, OSFSK_END); fsiz = osfpos(fpext); osfseek(fpext, 0L, OSFSK_SET); /* copy the contents of the external file to the output */ copybytes(fpext, fpout, fsiz); /* the size is the same as the external file's size */ cur->siz = fsiz; /* done with the file */ osfcls(fpext); } else { /* * it comes from the input resource file - seek to the start * of the resource in the input file, and copy the data to * the output file */ osfseek(fp, in_res_base + cur->src_idx->ofs, OSFSK_SET); copybytes(fp, fpout, cur->src_idx->siz); /* the size is the same as in the input file */ cur->siz = cur->src_idx->siz; } } /* note the current output position - this is the end of the resource */ out_endpos = osfpos(fpout); /* * Now that we've written all of the resources and know their actual * layout in the file, we can go back and write the index table. */ osfseek(fpout, out_hdr_pos + 8, OSFSK_SET); for (cur = out_list ; cur != 0 ; cur = cur->nxt) { /* build this object's index table entry */ oswp4(buf, cur->ofs); oswp4(buf + 4, cur->siz); oswp2(buf + 8, cur->namlen); /* write the entry */ if (osfwb(fpout, buf, 10) || osfwb(fpout, cur->nam, cur->namlen)) listexit(fp, "unable to write HTML index table entry"); } /* * We're done building the resource; now all we need to do is go * back and write the ending position of the resource in the * resource header. */ osfseek(fpout, out_hdr_pos - 4, OSFSK_SET); oswp4(buf, out_endpos); if (osfwb(fpout, buf, 4)) errexit("error writing resource", 1); /* seek back to the end of the resource in the output file */ osfseek(fpout, out_endpos, OSFSK_SET); done: /* if we have an input list, free it */ if (in_list != 0) { /* delete all of the entries in the input table */ for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p) { /* delete this entry if we haven't already done so */ if (*p != 0) free(*p); } /* delete the input pointer list itself */ free(in_list); } /* * delete everything in the additions list, since we're done with * them now */ for (op = add_list ; op != 0 ; op = next_op) { /* note the next entry in the list */ next_op = op->opnxt; /* delete this entry */ free(op); } /* return the op list in its current form */ return oplist; }