static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) { unsigned int *start, *end, *alt_start, *alt_end, *src, *dest; start = calc_addr(fcur, fcur->start_off); end = calc_addr(fcur, fcur->end_off); alt_start = calc_addr(fcur, fcur->alt_start_off); alt_end = calc_addr(fcur, fcur->alt_end_off); if ((alt_end - alt_start) > (end - start)) return 1; if ((value & fcur->mask) == fcur->value) return 0; src = alt_start; dest = start; for (; src < alt_end; src++, dest++) { if (patch_alt_instruction(src, dest, alt_start, alt_end)) return 1; } for (; dest < end; dest++) patch_instruction(dest, PPC_INST_NOP); return 0; }
static void internal_blk0_store(WORD addr, BYTE value, WORD base, int ro) { BYTE mode; int bank; unsigned int faddr; mode = register_a & REGA_MODE_MASK; /* Blk0 is hardwired to bank 0 */ bank = 0; /* Calculate Address */ faddr = calc_addr(addr, bank, base); /* Perform access */ switch (mode) { case MODE_ROM_RAM: case MODE_RAM1: case MODE_RAM2: if (!ro) { cart_ram[faddr] = value; } break; case MODE_SUPER_ROM: case MODE_SUPER_RAM: cart_ram[faddr] = value; break; default: break; } }
/* * Reset */ void CTcDataStream::reset() { /* move the write pointer back to the start */ ofs_ = 0; obj_file_start_ofs_ = 0; /* back to the first page */ page_cur_ = 0; /* set up to write to the first page, if we have any pages at all */ if (pages_ != 0) { /* we have all of the first page available again */ wp_ = calc_addr(0); rem_ = TCCS_PAGE_SIZE; } /* reset the allocator */ allocator_->reset(); /* * forget all of the anchors (no need to delete them explicitly - * they were allocated from our allocator pool, which we've reset to * completely discard everything it contained) */ first_anchor_ = last_anchor_ = 0; }
/* * Get a pointer to a block at a given offset and a given length. */ const char *CTcDataStream::get_block_ptr(ulong ofs, ulong requested_len, ulong *available_len) { size_t page_rem; /* * determine how much is left on the page containing the offset * after the given offset */ page_rem = TCCS_PAGE_SIZE - (ofs % TCCS_PAGE_SIZE); /* * if the amount remaining on the page is greater than the request * length, the available length is the entire request; otherwise, * the available length is the amount remaining on the page */ if (page_rem >= requested_len) *available_len = requested_len; else *available_len = page_rem; /* return the address at this offset */ return calc_addr(ofs); }
/* * Copy a chunk of the stream to the given buffer */ void CTcDataStream::copy_to_buf(char *buf, ulong start_ofs, ulong len) { /* read the data from each page that the block spans */ while (len != 0) { size_t cur; /* * determine how much is left on the page containing the current * starting offset */ cur = TCCS_PAGE_SIZE - (start_ofs % TCCS_PAGE_SIZE); /* * figure out how much we can copy - copy the whole remaining * size, but no more than the amount remaining on this page */ if (cur > len) cur = (size_t)len; /* copy the data */ memcpy(buf, calc_addr(start_ofs), cur); /* advance past this chunk */ len -= cur; start_ofs += cur; buf += cur; } }
static BYTE internal_blk0_read(WORD addr, WORD base) { BYTE mode; int bank; unsigned int faddr; BYTE value; mode = register_a & REGA_MODE_MASK; /* Blk0 is hardwired to bank 0 */ bank = 0; /* Calculate Address */ faddr = calc_addr(addr, bank, base); /* Perform access */ switch (mode) { case MODE_ROM_RAM: case MODE_RAM1: case MODE_RAM2: case MODE_SUPER_ROM: case MODE_SUPER_RAM: value = cart_ram[faddr]; break; default: value = vic20_cpu_last_data; break; } return value; }
/* * docmdline() - handle a colon command * * Handles a colon command received interactively by getcmdln() or from * the environment variable "BVIINIT" (or eventually .bvirc). */ void docmdline(char *cmdline) { char buff[CMDSZ]; char cmdbuf[CMDSZ]; char cmdname[MAXNAME]; char *cmd; char *p; size_t len; int n, ok, ret; int force = 0; int saveflag; if(*cmdline == '\0') { return; } if(*cmdline == '"') { return; /** comment **/ } if(strlen(cmdline) > CMDSZ - 2) { emsg("Command too long"); return; } strcpy(buff, cmdline); cmd = buff; /* With no address given, we start at the beginning of the file and * go to the end of the file (not line like in vi). */ addr_flag = 0; start_addr = mem; end_addr = maxpos - 1; SKIP_WHITE if(*cmd == '%') { cmd++; addr_flag = 2; } else { if((start_addr = calc_addr(&cmd, mem)) == NULL) { return; } if(*cmd == ',') { cmd++; addr_flag = 1; SKIP_WHITE if((end_addr = calc_addr(&cmd, maxpos - 1)) == NULL) { return; } } else { if(addr_flag) {
void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) { struct fixup_entry *fcur, *fend; fcur = fixup_start; fend = fixup_end; for (; fcur < fend; fcur++) { if (patch_feature_section(value, fcur)) { WARN_ON(1); printk("Unable to patch feature section at %p - %p" \ " with %p - %p\n", calc_addr(fcur, fcur->start_off), calc_addr(fcur, fcur->end_off), calc_addr(fcur, fcur->alt_start_off), calc_addr(fcur, fcur->alt_end_off)); } } }
void vl_idct_stage2_vert_shader(struct vl_idct *idct, struct ureg_program *shader, unsigned first_output, struct ureg_dst tex) { struct ureg_src vrect, vpos; struct ureg_src scale; struct ureg_dst t_start; struct ureg_dst o_l_addr[2], o_r_addr[2]; vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_start = ureg_DECL_temporary(shader); --first_output; o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR0); o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR1); o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR0); o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR1); scale = ureg_imm2f(shader, (float)VL_BLOCK_WIDTH / idct->buffer_width, (float)VL_BLOCK_HEIGHT / idct->buffer_height); ureg_MUL(shader, ureg_writemask(tex, TGSI_WRITEMASK_Z), ureg_scalar(vrect, TGSI_SWIZZLE_X), ureg_imm1f(shader, VL_BLOCK_WIDTH / idct->nr_of_render_targets)); ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale); calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, VL_BLOCK_WIDTH / 4); calc_addr(shader, o_r_addr, ureg_src(tex), ureg_src(t_start), true, false, idct->buffer_height / 4); ureg_MOV(shader, ureg_writemask(o_r_addr[0], TGSI_WRITEMASK_Z), ureg_src(tex)); ureg_MOV(shader, ureg_writemask(o_r_addr[1], TGSI_WRITEMASK_Z), ureg_src(tex)); }
static void * create_mismatch_vert_shader(struct vl_idct *idct) { struct ureg_program *shader; struct ureg_src vpos; struct ureg_src scale; struct ureg_dst t_tex; struct ureg_dst o_vpos, o_addr[2]; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return NULL; vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_tex = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0); o_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1); /* * scale = (VL_BLOCK_WIDTH, VL_BLOCK_HEIGHT) / (dst.width, dst.height) * * t_vpos = vpos + 7 / VL_BLOCK_WIDTH * o_vpos.xy = t_vpos * scale * * o_addr = calc_addr(...) * */ scale = ureg_imm2f(shader, (float)VL_BLOCK_WIDTH / idct->buffer_width, (float)VL_BLOCK_HEIGHT / idct->buffer_height); ureg_MAD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), vpos, scale, scale); ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, scale); calc_addr(shader, o_addr, ureg_src(t_tex), ureg_src(t_tex), false, false, idct->buffer_width / 4); ureg_release_temporary(shader, t_tex); ureg_END(shader); return ureg_create_shader_and_destroy(shader, idct->pipe); }
/* * Decrement the write offset */ void CTcDataStream::dec_ofs(int amount) { /* adjust the offset */ ofs_ -= amount; /* * calculate the new page we're on, since this may take us to a * different page */ page_cur_ = ofs_ / TCCS_PAGE_SIZE; /* calculate the remaining size in this page */ rem_ = TCCS_PAGE_SIZE - (ofs_ % TCCS_PAGE_SIZE); /* calculate the current write pointer */ wp_ = calc_addr(ofs_); }
static int finalexpansion_mon_dump(void) { BYTE mode; int blk, active, ro; mode = register_a & REGA_MODE_MASK; mon_out("Register A: $%02x, B: $%02x, lock bit %i\n", register_a, register_b, lock_bit); mon_out("Mode: %s\n", finalexpansion_mode_name[mode >> 5]); /* BLK 0 */ mon_out("BLK 0: "); active = 0; ro = 0; if (!(register_b & REGB_BLK0_OFF)) { switch (mode) { case MODE_SUPER_ROM: case MODE_SUPER_RAM: active = 1; break; case MODE_ROM_RAM: case MODE_RAM1: case MODE_RAM2: active = 1; ro = register_a & REGA_BLK0_RO; break; default: break; } } if (active) { mon_out("RAM%s (offset $%06x)\n", ro ? " (read only)" : "", calc_addr(0, 0, BLK0_BASE)); } else { mon_out("off\n"); } /* BLK 1, 2, 3, 5 */ for (blk = 1; blk <= 5; blk++) { finalexpansion_mon_dump_blk(blk); } return 0; }
/* * Write bytes to the stream at an earlier offset */ void CTcDataStream::write_at(ulong ofs, const char *buf, size_t len) { /* if we're writing to the current offset, use the normal writer */ if (ofs == ofs_) write(buf, len); /* * log an internal error, and skip writing anything, if the desired * range of offsets has not been previously written */ if (ofs + len > ofs_) G_tok->throw_internal_error(TCERR_WRITEAT_PAST_END); /* write the data to each page it spans */ while (len != 0) { size_t cur; /* * determine how much is left on the page containing the current * starting offset */ cur = TCCS_PAGE_SIZE - (ofs % TCCS_PAGE_SIZE); /* * figure out how much we can copy - copy the whole remaining * size, but no more than the amount remaining on this page */ if (cur > len) cur = len; /* copy the data */ memcpy(calc_addr(ofs), buf, cur); /* advance past this chunk */ len -= cur; ofs += cur; buf += cur; } }
static BYTE internal_read(WORD addr, int blk, WORD base, int sel) { BYTE mode; int bank; unsigned int faddr; BYTE value; mode = register_a & REGA_MODE_MASK; /* Determine which bank to access */ switch (mode) { case MODE_FLASH: case MODE_SUPER_ROM: case MODE_SUPER_RAM: bank = register_a & REGA_BANK_MASK; break; case MODE_ROM_RAM: case MODE_RAM1: bank = 1; break; case MODE_RAM2: if (sel) { bank = 2; } else { bank = 1; } break; default: bank = 0; break; } /* Calculate Address */ faddr = calc_addr(addr, bank, base); /* Perform access */ switch (mode) { case MODE_START: if (blk == 5) { value = flash040core_read(&flash_state, faddr); } else { value = vic20_cpu_last_data; } break; case MODE_FLASH: case MODE_SUPER_ROM: value = flash040core_read(&flash_state, faddr); break; case MODE_ROM_RAM: if (sel) { value = flash040core_read(&flash_state, faddr); } else { value = cart_ram[faddr]; } break; case MODE_RAM1: case MODE_RAM2: case MODE_SUPER_RAM: value = cart_ram[faddr]; break; default: value = vic20_cpu_last_data; break; } return value; }
/* * Write the stream, its anchors, and its fixups to an object file. */ void CTcDataStream::write_to_object_file(CVmFile *fp) { ulong ofs; CTcStreamAnchor *anchor; long cnt; /* * First, write the data stream bytes. Write the length prefix * followed by the data. Just blast the whole thing out in one huge * byte stream, one page at a time. */ fp->write_int4(ofs_); /* write the data one page at a time */ for (ofs = 0 ; ofs < ofs_ ; ) { size_t cur; /* * write out one whole page, or the balance of the current page * if we have less than a whole page remaining */ cur = TCCS_PAGE_SIZE; if (ofs + cur > ofs_) cur = (size_t)(ofs_ - ofs); /* write out this chunk */ fp->write_bytes(calc_addr(ofs), cur); /* move to the next page's offset */ ofs += cur; } /* count the anchors */ for (cnt = 0, anchor = first_anchor_ ; anchor != 0 ; anchor = anchor->nxt_, ++cnt) ; /* write the count */ fp->write_int4(cnt); /* * Write all of the anchors, and all of their fixups. (We have the * code to write the anchor and fixup information in-line here for * efficiency - there will normally be a large number of these tiny * objects, so anything we can do to improve the speed of this loop * will help quite a lot in the overall write performance.) */ for (anchor = first_anchor_ ; anchor != 0 ; anchor = anchor->nxt_) { char buf[6]; /* write the stream offset */ oswp4(buf, anchor->get_ofs()); /* * If the anchor has an external fixup list, write the symbol's * name to the file; otherwise write a zero length to indicate * that we have an internal fixup list. */ if (anchor->get_fixup_owner_sym() == 0) { /* no external list - indicate with a zero symbol length */ oswp2(buf+4, 0); fp->write_bytes(buf, 6); } else { /* external list - write the symbol length and name */ oswp2(buf+4, anchor->get_fixup_owner_sym()->get_sym_len()); fp->write_bytes(buf, 6); fp->write_bytes(anchor->get_fixup_owner_sym()->get_sym(), anchor->get_fixup_owner_sym()->get_sym_len()); } /* write the fixup list */ CTcAbsFixup:: write_fixup_list_to_object_file(fp, *anchor->fixup_list_head_); } }
static void internal_store(WORD addr, BYTE value, int blk, WORD base, int sel) { BYTE mode; int bank; unsigned int faddr; mode = register_a & REGA_MODE_MASK; /* Determine which bank to access */ switch (mode) { case MODE_FLASH: case MODE_SUPER_RAM: bank = register_a & REGA_BANK_MASK; break; case MODE_SUPER_ROM: #ifdef FE3_2_SUPER_ROM_BUG bank = 1 | (register_a & REGA_BANK_MASK); break; #endif case MODE_START: bank = 1; break; case MODE_ROM_RAM: case MODE_RAM1: if (sel) { bank = 2; } else { bank = 1; } break; case MODE_RAM2: bank = 1; break; default: bank = 0; break; } /* Calculate Address */ faddr = calc_addr(addr, bank, base); /* Perform access */ switch (mode) { case MODE_FLASH: flash040core_store(&flash_state, faddr, value); break; case MODE_ROM_RAM: if (sel) { cart_ram[faddr] = value; } break; case MODE_START: case MODE_RAM1: case MODE_RAM2: case MODE_SUPER_ROM: case MODE_SUPER_RAM: cart_ram[faddr] = value; break; default: break; } }
static void finalexpansion_mon_dump_blk(int blk) { int mode; BYTE reg_mask; int sel; int bank_r, bank_w; WORD base; enum { ACC_OFF, ACC_RAM, ACC_FLASH } acc_mode_r, acc_mode_w; switch (blk) { case 1: reg_mask = REGA_BLK1_SEL; base = BLK1_BASE; break; case 2: reg_mask = REGA_BLK2_SEL; base = BLK2_BASE; break; case 3: reg_mask = REGA_BLK3_SEL; base = BLK3_BASE; break; case 5: reg_mask = REGA_BLK5_SEL; base = BLK5_BASE; break; default: /* ignore block 4 */ return; } mon_out("BLK %i: ", blk); if (register_b & reg_mask) { mon_out("off\n"); return; } mode = register_a & REGA_MODE_MASK; sel = register_a & reg_mask; bank_r = register_a & REGA_BANK_MASK; bank_w = bank_r; switch (mode) { default: case MODE_START: bank_r = 0; bank_w = 1; acc_mode_r = (blk == 5) ? ACC_FLASH : ACC_OFF; acc_mode_w = ACC_RAM; break; case MODE_FLASH: acc_mode_r = ACC_FLASH; acc_mode_w = ACC_FLASH; break; case MODE_SUPER_ROM: #ifdef FE3_2_SUPER_ROM_BUG bank_w = 1 | (register_a & REGA_BANK_MASK); #endif acc_mode_r = ACC_FLASH; acc_mode_w = ACC_RAM; break; case MODE_SUPER_RAM: acc_mode_r = ACC_RAM; acc_mode_w = ACC_RAM; break; case MODE_ROM_RAM: bank_r = 1; bank_w = sel ? 2 : 1; acc_mode_r = sel ? ACC_FLASH : ACC_RAM; acc_mode_w = sel ? ACC_RAM : ACC_OFF; break; case MODE_RAM1: bank_r = 1; bank_w = sel ? 2 : 1; acc_mode_r = ACC_RAM; acc_mode_w = ACC_RAM; break; case MODE_RAM2: bank_r = sel ? 2 : 1; bank_w = 1; acc_mode_r = ACC_RAM; acc_mode_w = ACC_RAM; break; } mon_out("\n read %s ", finalexpansion_acc_mode[acc_mode_r]); if (acc_mode_r != ACC_OFF) { mon_out("bank $%02x (offset $%06x)", bank_r, calc_addr(0, bank_r, base)); } mon_out("\n write %s ", finalexpansion_acc_mode[acc_mode_w]); if (acc_mode_w != ACC_OFF) { mon_out("bank $%02x (offset $%06x)", bank_w, calc_addr(0, bank_w, base)); } mon_out("\n"); }
//---------------------------------------------------------------------- static void handle_operand(op_t &x, bool read_access) { ea_t ea; dref_t dreftype; switch ( x.type ) { case o_void: case o_reg: break; case o_imm: QASSERT(557, read_access); dreftype = dr_O; MAKE_IMMD: doImmdValue(); if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dreftype); break; case o_displ: dreftype = read_access ? dr_R : dr_W; switch ( x.phrase ) { case rD: // "dp" case rDX: // "dp, X" case rDY: // "dp, Y" case riDX: // "(dp, X)" case rDi: // "(dp,n)" case rDiL: // "long(dp,n)" case rDiY: // "(dp,n), Y" case rDiLY: // "long(dp,n), Y" { sel_t dp = get_segreg(cmd.ea, rD); if ( dp != BADSEL ) { ea_t orig_ea = dp + x.addr; ea = xlat(orig_ea); goto MAKE_DREF; } else { goto MAKE_IMMD; } } case rAbsi: // "(abs)" case rAbsX: // "abs, X" case rAbsY: // "abs, Y" case rAbsiL: // "long(abs)" ea = toEA(dataSeg_op(x.n), x.addr); goto MAKE_DREF; case rAbsXi: // "(abs,X)" ea = toEA(codeSeg(cmd.ea, x.n), x.addr); // jmp, jsr goto MAKE_DREF; case rAbsLX: // "long abs, X" ea = x.addr; goto MAKE_DREF; default: goto MAKE_IMMD; } case o_mem: case o_mem_far: ea = calc_addr(x); MAKE_DREF: ua_dodata2(x.offb, ea, x.dtyp); if ( !read_access ) doVar(ea); ua_add_dref(x.offb, ea, read_access ? dr_R : dr_W); break; case o_near: case o_far: { ea_t orig_ea; ea = calc_addr(x, &orig_ea); if ( cmd.itype == M65816_per ) { ua_add_dref(x.offb, ea, dr_O); } else { bool iscall = InstrIsSet(cmd.itype, CF_CALL); cref_t creftype = x.type == o_near ? iscall ? fl_CN : fl_JN : iscall ? fl_CF : fl_JF; ua_add_cref(x.offb, ea, creftype); if ( flow && iscall ) flow = func_does_return(ea); } } break; default: INTERR(558); } }