static void put_data(int fd, char *null_buf, const CELL * cell, int row, int n, int zeros_r_nulls) { struct fileinfo *fcb = &R__.fileinfo[fd]; int compressed = fcb->cellhd.compressed; int len = compressed ? sizeof(CELL) : fcb->nbytes; unsigned char *work_buf, *wk; ssize_t nwrite; if (row < 0 || row >= fcb->cellhd.rows) return; if (n <= 0) return; work_buf = G__alloca(fcb->cellhd.cols * sizeof(CELL) + 1); wk = work_buf; if (compressed) set_file_pointer(fd, row); if (compressed) wk++; convert_int(wk, null_buf, cell, n, len, zeros_r_nulls); if (compressed) { unsigned char *wk = work_buf + 1; int nbytes = count_bytes(wk, n, len); unsigned char *compressed_buf; int total; if (fcb->nbytes < nbytes) fcb->nbytes = nbytes; /* first trim away zero high bytes */ if (nbytes < len) trim_bytes(wk, n, len, len - nbytes); total = nbytes * n; compressed_buf = G__alloca(total + 1); compressed_buf[0] = work_buf[0] = nbytes; /* then compress the data */ nwrite = compressed == 1 ? rle_compress(compressed_buf + 1, work_buf + 1, n, nbytes) : zlib_compress(compressed_buf + 1, work_buf + 1, n, nbytes); if (nwrite > 0) { nwrite++; if (write(fd, compressed_buf, nwrite) != nwrite) G_fatal_error(_("Error writing compressed data for row %d of <%s>"), row, fcb->name); } else { nwrite = nbytes * n + 1; if (write(fd, work_buf, nwrite) != nwrite) G_fatal_error(_("Error writing compressed data for row %d of <%s>"), row, fcb->name); } G__freea(compressed_buf); } else { nwrite = fcb->nbytes * n; if (write(fd, work_buf, nwrite) != nwrite) G_fatal_error(_("Error writing uncompressed data for row %d of <%s>"), row, fcb->name); } G__freea(work_buf); }
static DECL_SYMBOL_ACTION(emulate_set_mem) { char *str, *typ; int addr; char hexstr[256]; char memtyp[4]; mem_domain dmn; u8 vector[64]; u8 rle[64]; int vectorlen, rlelen, idx; bool force; if (task == csa_READ) { static int saveaddr; u8 verify[64]; /* Write memory to a hex string, CPU RAM followed by VDP RAM */ if (!iter) saveaddr = 0; addr = saveaddr; // spit out 64 bytes at a time if (addr < 65536) { /* Note: this may not seem right, when we could have a * MemoryEntry for a MEMENT_STORED RAM block covering * this area already, but this preserves the state of * that RAM at the time of the session being saved. */ mrstruct *mrarea; while (!HAS_RAM_ACCESS(md_cpu, addr)) addr = (addr & ~4095) + 4096; dmn = md_cpu; mrarea = THE_AREA(md_cpu, addr); memtyp[0] = 'C'; memtyp[1] = 0; // not compressed memtyp[2] = 0; } else if (addr < 65536 + 16384) { addr -= 65536; memtyp[0] = 'V'; memtyp[1] = 0; // not compressed memtyp[2] = 0; dmn = md_video; } else { return 0; } command_arg_set_num(sym->args->next, addr); /* Read 64 bytes from memory */ vectorlen = 0; do { vector[vectorlen++] = domain_read_byte(dmn, addr); addr++; } while (addr & 63); /* RLE compress the vector */ rlelen = rle_compress(vector, vectorlen, rle, sizeof(rle)); /* Returns zero if it couldn't compress any */ if (rlelen) { memtyp[1] = '*'; // compressed rle_uncompress(rle, rlelen, verify, sizeof(verify)); if (memcmp(vector, verify, vectorlen)) { command_logger(_L|LOG_ABORT, _("Mismatched on RLE compress:\n" "In : %s\n" "Out: %s\n" "Ver: %s\n"), emulate_bin2hex(vector, 0L, vectorlen), emulate_bin2hex(rle, 0L, rlelen), emulate_bin2hex(verify, 0L, sizeof(verify))); } } else { rlelen = vectorlen; memcpy(rle, vector, rlelen); } str = hexstr; idx = 0; while (idx < rlelen) { u8 byt; byt = rle[idx++]; *str++ = NUMHEX(byt>>4); *str++ = NUMHEX(byt&0xf); } *str = 0; saveaddr = addr + (dmn == md_video ? 65536 : 0); command_arg_set_string(sym->args, memtyp); command_arg_set_string(sym->args->next->next, hexstr); return 1; } // write memory command_arg_get_string(sym->args, &typ); command_arg_get_num(sym->args->next, &addr); addr &= 0xffff; command_arg_get_string(sym->args->next->next, &str); // get memory type dmn = emulate_parse_mem_type(typ, &force); if ((int)dmn < 0) return 0; // decode string, assuming it's rle-encoded rlelen = 0; while (*str) { u8 byt = (HEXNUM(*str) << 4) + HEXNUM(*(str+1)); rle[rlelen++] = byt; str+=2; } // second char of memory type indicates compression if (typ[1] && typ[1] == '*') { vectorlen = rle_uncompress(rle, rlelen, vector, sizeof(vector)); } else { memcpy(vector, rle, rlelen); vectorlen = rlelen; } idx = 0; while (idx < vectorlen) { domain_write_byte(dmn, addr, vector[idx++]); addr++; } return 1; }