static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos) { __u8 old_tos = load_byte(skb, TOS_OFF); bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2); bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0); }
void amax_disk_select (uae_u8 v, uae_u8 ov) { bfd100 = v; if (!(bfd100 & dselect) && (ov & dselect)) load_byte (); amax_check (); }
/** * @brief ROL mem */ void Cpu::rol_mem(uint16_t addr, uint8_t cycles) { uint8_t v = load_byte(addr); /* see ASL doc */ mem_->write_byte(addr,v); mem_->write_byte(addr,rol(v)); tick(cycles); }
/** * @brief BIT test */ void Cpu::bit(uint16_t addr, uint8_t cycles) { uint8_t t = load_byte(addr); of((t&0x40)!=0); SET_NF(t); SET_ZF(t&a()); tick(cycles); }
static inline int do_redirect(struct __sk_buff *skb, int nh_off, int dir) { __u16 dport, off; __u8 ip_proto, ip_vl; int *ifindex; __be32 ip_dest, ip_src; char fmt[] = "skb %p len %d ip_dest %x\n"; ip_proto = load_byte(skb, nh_off + offsetof(struct iphdr, protocol)); ip_src = load_word(skb, nh_off + offsetof(struct iphdr, saddr)); ip_dest = load_word(skb, nh_off + offsetof(struct iphdr, daddr)); if (ip_proto != IPPROTO_TCP) return 0; ip_vl = load_byte(skb, nh_off); if (likely(ip_vl == 0x45)) nh_off += sizeof(struct iphdr); else nh_off += (ip_vl & 0xF) << 2; bpf_trace_printk(fmt, sizeof(fmt), skb, skb->len, ip_dest); dport = load_half(skb, nh_off + offsetof(struct tcphdr, dest)); if (dport != 80) return 0; if (dir == 0) { ifindex = bpf_map_lookup_elem(&container_map, &ip_dest); if (ifindex) { set_tcp_dest_port(skb, 8080); bpf_clone_redirect(skb, *ifindex, 1); } } else { ifindex = bpf_map_lookup_elem(&container_map, &ip_src); if (ifindex) set_tcp_dest_port(skb, 80); } return -1; }
bool trainer_check_flag_on_spot(u8 npc_id) { void *script = npc_get_script_by_npc_id(npc_id); /* probably inject some script execution here */ u16 flag = tb_modify_flag_id(load_hword(script + 2)); /* check for line of sight */ u8 hit_result = npc_trainer_and_raycast_hit(&npc_states[npc_id]); if (hit_result == 0) return false; if (flag_check(trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START))) return false; if ((load_byte(script + 1) == 4) && (player_cant_double_battle() > 0)) return false; spot_trainer_8080334(npc_id, script); spot_trainer_8081E68(&npc_states[npc_id], hit_result - 1); return true; }
void mef_load(unsigned char* offset) { unsigned char* start = offset; unsigned char areasize = load_byte(); uint16_t relocsize; unsigned int i, j; uint16_t checksum = 0; unsigned char* buf; struct Relocation reloc; for (i = 0; i < areasize; i++) { buf = (unsigned char *) &areas[i]; for (j = 0; j < sizeof(struct Area); j++) { *buf++ = load_byte(); } } for (i = 0; i < areasize; i++) { for (j = 0; j < areas[i].size; j++) { *offset = load_byte(); checksum += *offset; offset++; } if (areas[i].checksum != checksum) { // Checksum error! } } // relocation information relocsize = load_byte(); relocsize = (load_byte() << 8) + relocsize; for (i = 0; i < relocsize; i++) { buf = (unsigned char *) &reloc; for (j = 0; j < sizeof(struct Relocation); j++) { *buf++ = load_byte(); } mef_reloc(start, &reloc); } }
static char *nscdec( vlc_object_t *p_demux, char* p_encoded ) { unsigned int i; unsigned char tmp; unsigned char j, k; unsigned int length; unsigned char encoding_type; unsigned char *buf16; char *buf8; char *p_input = p_encoded; if( strlen( p_input ) < 15 ) { msg_Err( p_demux, "input string less than 15 characters" ); return NULL; } if( load_byte( 1, &encoding_type, &p_input, NULL, NULL ) ) { msg_Err( p_demux, "unable to get NSC encoding type" ); return NULL; } if( encoding_type != 1 && encoding_type != 2 ) { msg_Err( p_demux, "encoding type %d is not supported", encoding_type ); return NULL; } j = k = 0; if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } for( i = 0; i < 4; i++ ) { if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } } length = 0; for( i = 4; i; i-- ) { if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } length |= tmp << ((i - 1) * 8); } if( length == 0 ) { msg_Err( p_demux, "Length is 0" ); return NULL; } buf16 = malloc( length ); if( buf16 == NULL ) return NULL; for( i = 0; i < length; i++ ) { if( load_byte( encoding_type, &buf16[ i ], &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); free( buf16 ); return NULL; } } buf8 = FromCharset( "UTF-16LE", buf16, length ); free( buf16 ); if( buf8 == NULL ) { msg_Err( p_demux, "iconv failed" ); return NULL; } return buf8; }
static inline __u64 parse_ip(struct __sk_buff *skb, __u64 nhoff, __u64 *ip_proto, struct bpf_flow_keys *flow) { __u64 verlen; if (unlikely(ip_is_fragment(skb, nhoff))) *ip_proto = 0; else *ip_proto = load_byte(skb, nhoff + offsetof(struct iphdr, protocol)); if (*ip_proto != IPPROTO_GRE) { flow->src = load_word(skb, nhoff + offsetof(struct iphdr, saddr)); flow->dst = load_word(skb, nhoff + offsetof(struct iphdr, daddr)); } verlen = load_byte(skb, nhoff + 0/*offsetof(struct iphdr, ihl)*/); if (likely(verlen == 0x45)) nhoff += 20; else nhoff += (verlen & 0xF) << 2; return nhoff; } static inline __u64 parse_ipv6(struct __sk_buff *skb, __u64 nhoff, __u64 *ip_proto, struct bpf_flow_keys *flow) { *ip_proto = load_byte(skb, nhoff + offsetof(struct ipv6hdr, nexthdr)); flow->src = ipv6_addr_hash(skb, nhoff + offsetof(struct ipv6hdr, saddr));
/*eBPF program. Filter IP and TCP packets, having payload not empty and containing "HTTP", "GET", "POST" ... as first bytes of payload if the program is loaded as PROG_TYPE_SOCKET_FILTER and attached to a socket return 0 -> DROP the packet return -1 -> KEEP the packet and return it to user space (userspace can read it from the socket_fd ) */ int http_filter(struct __sk_buff *skb) { u8 *cursor = 0; struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); //filter IP packets (ethernet type = 0x0800) if (!(ethernet->type == 0x0800)) { goto DROP; } struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); //filter TCP packets (ip next protocol = 0x06) if (ip->nextp != IP_TCP) { goto DROP; } u32 tcp_header_length = 0; u32 ip_header_length = 0; u32 payload_offset = 0; u32 payload_length = 0; struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp)); //calculate ip header length //value to multiply * 4 //e.g. ip->hlen = 5 ; IP Header Length = 5 x 4 byte = 20 byte ip_header_length = ip->hlen << 2; //SHL 2 -> *4 multiply //calculate tcp header length //value to multiply *4 //e.g. tcp->offset = 5 ; TCP Header Length = 5 x 4 byte = 20 byte tcp_header_length = tcp->offset << 2; //SHL 2 -> *4 multiply //calculate patload offset and length payload_offset = ETH_HLEN + ip_header_length + tcp_header_length; payload_length = ip->tlen - ip_header_length - tcp_header_length; //http://stackoverflow.com/questions/25047905/http-request-minimum-size-in-bytes //minimum length of http request is always geater than 7 bytes //avoid invalid access memory //include empty payload if(payload_length < 7) { goto DROP; } //load first 7 byte of payload into p (payload_array) //direct access to skb not allowed unsigned long p[7]; int i = 0; int j = 0; const int last_index = payload_offset + 7; for (i = payload_offset ; i < last_index ; i++) { p[j] = load_byte(skb , i); j++; } //find a match with an HTTP message //HTTP if ((p[0] == 'H') && (p[1] == 'T') && (p[2] == 'T') && (p[3] == 'P')) { goto KEEP; } //GET if ((p[0] == 'G') && (p[1] == 'E') && (p[2] == 'T')) { goto KEEP; } //POST if ((p[0] == 'P') && (p[1] == 'O') && (p[2] == 'S') && (p[3] == 'T')) { goto KEEP; } //PUT if ((p[0] == 'P') && (p[1] == 'U') && (p[2] == 'T')) { goto KEEP; } //DELETE if ((p[0] == 'D') && (p[1] == 'E') && (p[2] == 'L') && (p[3] == 'E') && (p[4] == 'T') && (p[5] == 'E')) { goto KEEP; } //HEAD if ((p[0] == 'H') && (p[1] == 'E') && (p[2] == 'A') && (p[3] == 'D')) { goto KEEP; } //no HTTP match goto DROP; //keep the packet and send it to userspace retruning -1 KEEP: return -1; //drop the packet returning 0 DROP: return 0; }
char *nscdec( vlc_object_t *p_demux, char* p_encoded ) { unsigned int i; unsigned char tmp; unsigned char j, k; unsigned int length; unsigned char encoding_type; vlc_iconv_t conv; size_t buf16_size; unsigned char *buf16; char *p_buf16; size_t buf8_size; char *buf8; char *p_buf8; char *p_input = p_encoded; if( strlen( p_input ) < 15 ) { msg_Err( p_demux, "input string less than 15 characters" ); return NULL; } if( load_byte( 1, &encoding_type, &p_input, NULL, NULL ) ) { msg_Err( p_demux, "unable to get NSC encoding type" ); return NULL; } if( encoding_type != 1 && encoding_type != 2 ) { msg_Err( p_demux, "encoding type %d is not supported", encoding_type ); return NULL; } j = k = 0; if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } for( i = 0; i < 4; i++ ) { if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } } length = 0; for( i = 4; i; i-- ) { if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); return NULL; } length |= tmp << ((i - 1) * 8); } if( length == 0 ) { msg_Err( p_demux, "Length is 0" ); return NULL; } buf16_size = length; buf16 = (unsigned char *)malloc( buf16_size ); if( buf16 == NULL ) { msg_Err( p_demux, "out of memory" ); return NULL; } for( i = 0; i < length; i++ ) { if( load_byte( encoding_type, &buf16[ i ], &p_input, &j, &k ) ) { msg_Err( p_demux, "load_byte failed" ); free( (void *)buf16 ); return NULL; } } buf8_size = length; buf8 = (char *)malloc( buf8_size + 1 ); if( buf8 == NULL ) { msg_Err( p_demux, "out of memory" ); free( (void *)buf16 ); return NULL; } conv = vlc_iconv_open( "UTF-8", "UTF-16LE" ); if( conv == (vlc_iconv_t)-1 ) { msg_Err( p_demux, "iconv_open failed" ); free( (void *)buf16 ); free( (void *)buf8 ); return NULL; } p_buf8 = &buf8[ 0 ]; p_buf16 = (char *)&buf16[ 0 ]; if( vlc_iconv( conv, &p_buf16, &buf16_size, &p_buf8, &buf8_size ) < 0 ) { msg_Err( p_demux, "iconv failed" ); return NULL; } else { buf8[ length - buf8_size ] = '\0'; } vlc_iconv_close( conv ); free( (void *)buf16 ); return buf8; }
/** * @brief emulate instruction * @return returns false if something goes wrong (e.g. illegal instruction) * * Current limitations: * * - Illegal instructions are not implemented * - Excess cycles due to page boundary crossing are not calculated * - Some known architectural bugs are not emulated */ bool Cpu::emulate() { /* fetch instruction */ uint8_t insn = fetch_op(); bool retval = true; /* emulate instruction */ switch(insn) { /* BRK */ case 0x0: brk(); break; /* ORA (nn,X) */ case 0x1: ora(load_byte(addr_indx()),6); break; /* ORA nn */ case 0x5: ora(load_byte(addr_zero()),3); break; /* ASL nn */ case 0x6: asl_mem(addr_zero(),5); break; /* PHP */ case 0x8: php(); break; /* ORA #nn */ case 0x9: ora(fetch_op(),2); break; /* ASL A */ case 0xA: asl_a(); break; /* ORA nnnn */ case 0xD: ora(load_byte(addr_abs()),4); break; /* ASL nnnn */ case 0xE: asl_mem(addr_abs(),6); break; /* BPL nn */ case 0x10: bpl(); break; /* ORA (nn,Y) */ case 0x11: ora(load_byte(addr_indy()),5); break; /* ORA nn,X */ case 0x15: ora(load_byte(addr_zerox()),4); break; /* ASL nn,X */ case 0x16: asl_mem(addr_zerox(),6); break; /* CLC */ case 0x18: clc(); break; /* ORA nnnn,Y */ case 0x19: ora(load_byte(addr_absy()),4); break; /* ORA nnnn,X */ case 0x1D: ora(load_byte(addr_absx()),4); break; /* ASL nnnn,X */ case 0x1E: asl_mem(addr_absx(),7); break; /* JSR */ case 0x20: jsr(); break; /* AND (nn,X) */ case 0x21: _and(load_byte(addr_indx()),6); break; /* BIT nn */ case 0x24: bit(addr_zero(),3); break; /* AND nn */ case 0x25: _and(load_byte(addr_zero()),3); break; /* ROL nn */ case 0x26: rol_mem(addr_zero(),5); break; /* PLP */ case 0x28: plp(); break; /* AND #nn */ case 0x29: _and(fetch_op(),2); break; /* ROL A */ case 0x2A: rol_a(); break; /* BIT nnnn */ case 0x2C: bit(addr_abs(),4); break; /* AND nnnn */ case 0x2D: _and(load_byte(addr_abs()),4); break; /* ROL nnnn */ case 0x2E: rol_mem(addr_abs(),6); break; /* BMI nn */ case 0x30: bmi(); break; /* AND (nn,Y) */ case 0x31: _and(load_byte(addr_indy()),5); break; /* AND nn,X */ case 0x35: _and(load_byte(addr_zerox()),4); break; /* ROL nn,X */ case 0x36: rol_mem(addr_zerox(),6); break; /* SEC */ case 0x38: sec(); break; /* AND nnnn,Y */ case 0x39: _and(load_byte(addr_absy()),4); break; /* AND nnnn,X */ case 0x3D: _and(load_byte(addr_absx()),4); break; /* ROL nnnn,X */ case 0x3E: rol_mem(addr_absx(),7); break; /* RTI */ case 0x40: rti(); break; /* EOR (nn,X) */ case 0x41: eor(load_byte(addr_indx()),6); break; /* EOR nn */ case 0x45: eor(load_byte(addr_zero()),3); break; /* LSR nn */ case 0x46: lsr_mem(addr_zero(),5); break; /* PHA */ case 0x48: pha(); break; /* EOR #nn */ case 0x49: eor(fetch_op(),2); break; /* BVC */ case 0x50: bvc(); break; /* JMP nnnn */ case 0x4C: jmp(); break; /* EOR nnnn */ case 0x4D: eor(load_byte(addr_abs()),4); break; /* LSR A */ case 0x4A: lsr_a(); break; /* LSR nnnn */ case 0x4E: lsr_mem(addr_abs(),6); break; /* EOR (nn,Y) */ case 0x51: eor(load_byte(addr_indy()),5); break; /* EOR nn,X */ case 0x55: eor(load_byte(addr_zerox()),4); break; /* LSR nn,X */ case 0x56: lsr_mem(addr_zerox(),6); break; /* CLI */ case 0x58: cli(); break; /* EOR nnnn,Y */ case 0x59: eor(load_byte(addr_absy()),4); break; /* EOR nnnn,X */ case 0x5D: eor(load_byte(addr_absx()),4); break; /* LSR nnnn,X */ case 0x5E: lsr_mem(addr_absx(),7); break; /* RTS */ case 0x60: rts(); break; /* ADC (nn,X) */ case 0x61: adc(load_byte(addr_indx()),6); break; /* ADC nn */ case 0x65: adc(load_byte(addr_zero()),3); break; /* ROR nn */ case 0x66: ror_mem(addr_zero(),5); break; /* PLA */ case 0x68: pla(); break; /* ADC #nn */ case 0x69: adc(fetch_op(),2); break; /* ROR A */ case 0x6A: ror_a(); break; /* JMP (nnnn) */ case 0x6C: jmp_ind(); break; /* ADC nnnn */ case 0x6D: adc(load_byte(addr_abs()),4); break; /* ROR nnnn */ case 0x6E: ror_mem(addr_abs(),6); break; /* BVS */ case 0x70: bvs(); break; /* ADC (nn,Y) */ case 0x71: adc(load_byte(addr_indy()),5); break; /* ADC nn,X */ case 0x75: adc(load_byte(addr_zerox()),4); break; /* ROR nn,X */ case 0x76: ror_mem(addr_zerox(),6); break; /* SEI */ case 0x78: sei(); break; /* ADC nnnn,Y */ case 0x79: adc(load_byte(addr_absy()),4); break; /* ADC nnnn,X */ case 0x7D: adc(load_byte(addr_absx()),4); break; /* ROR nnnn,X */ case 0x7E: ror_mem(addr_absx(),7); break; /* STA (nn,X) */ case 0x81: sta(addr_indx(),6); break; /* STY nn */ case 0x84: sty(addr_zero(),3); break; /* STA nn */ case 0x85: sta(addr_zero(),3); break; /* STX nn */ case 0x86: stx(addr_zero(),3); break; /* DEY */ case 0x88: dey(); break; /* TXA */ case 0x8A: txa(); break; /* STY nnnn */ case 0x8C: sty(addr_abs(),4); break; /* STA nnnn */ case 0x8D: sta(addr_abs(),4); break; /* STX nnnn */ case 0x8E: stx(addr_abs(),4); break; /* BCC nn */ case 0x90: bcc(); break; /* STA (nn,Y) */ case 0x91: sta(addr_indy(),6); break; /* STY nn,X */ case 0x94: sty(addr_zerox(),4); break; /* STA nn,X */ case 0x95: sta(addr_zerox(),4); break; /* STX nn,Y */ case 0x96: stx(addr_zeroy(),4); break; /* TYA */ case 0x98: tya(); break; /* STA nnnn,Y */ case 0x99: sta(addr_absy(),5); break; /* TXS */ case 0x9A: txs(); break; /* STA nnnn,X */ case 0x9D: sta(addr_absx(),5); break; /* LDY #nn */ case 0xA0: ldy(fetch_op(),2); break; /* LDA (nn,X) */ case 0xA1: lda(load_byte(addr_indx()),6); break; /* LDX #nn */ case 0xA2: ldx(fetch_op(),2); break; /* LDY nn */ case 0xA4: ldy(load_byte(addr_zero()),3); break; /* LDA nn */ case 0xA5: lda(load_byte(addr_zero()),3); break; /* LDX nn */ case 0xA6: ldx(load_byte(addr_zero()),3); break; /* TAY */ case 0xA8: tay(); break; /* LDA #nn */ case 0xA9: lda(fetch_op(),2); break; /* TAX */ case 0xAA: tax(); break; /* LDY nnnn */ case 0xAC: ldy(load_byte(addr_abs()),4); break; /* LDA nnnn */ case 0xAD: lda(load_byte(addr_abs()),4); break; /* LDX nnnn */ case 0xAE: ldx(load_byte(addr_abs()),4); break; /* BCS nn */ case 0xB0: bcs(); break; /* LDA (nn,Y) */ case 0xB1: lda(load_byte(addr_indy()),5); break; /* LDY nn,X */ case 0xB4: ldy(load_byte(addr_zerox()),3); break; /* LDA nn,X */ case 0xB5: lda(load_byte(addr_zerox()),3); break; /* LDX nn,Y */ case 0xB6: ldx(load_byte(addr_zeroy()),3); break; /* CLV */ case 0xB8: clv(); break; /* LDA nnnn,Y */ case 0xB9: lda(load_byte(addr_absy()),4); break; /* TSX */ case 0xBA: tsx(); break; /* LDY nnnn,X */ case 0xBC: ldy(load_byte(addr_absx()),4); break; /* LDA nnnn,X */ case 0xBD: lda(load_byte(addr_absx()),4); break; /* LDX nnnn,Y */ case 0xBE: ldx(load_byte(addr_absy()),4); break; /* CPY #nn */ case 0xC0: cpy(fetch_op(),2); break; /* CMP (nn,X) */ case 0xC1: cmp(load_byte(addr_indx()),6); break; /* CPY nn */ case 0xC4: cpy(load_byte(addr_zero()),3); break; /* CMP nn */ case 0xC5: cmp(load_byte(addr_zero()),3); break; /* DEC nn */ case 0xC6: dec(addr_zero(),5); break; /* INY */ case 0xC8: iny(); break; /* CMP #nn */ case 0xC9: cmp(fetch_op(),2); break; /* DEX */ case 0xCA: dex(); break; /* CPY nnnn */ case 0xCC: cpy(load_byte(addr_abs()),4); break; /* CMP nnnn */ case 0xCD: cmp(load_byte(addr_abs()),4); break; /* DEC nnnn */ case 0xCE: dec(addr_abs(),6); break; /* BNE nn */ case 0xD0: bne(); break; /* CMP (nn,Y) */ case 0xD1: cmp(load_byte(addr_indy()),5); break; /* CMP nn,X */ case 0xD5: cmp(load_byte(addr_zerox()),4); break; /* DEC nn,X */ case 0xD6: dec(addr_zerox(),6); break; /* CLD */ case 0xD8: cld(); break; /* CMP nnnn,Y */ case 0xD9: cmp(load_byte(addr_absy()),4); break; /* CMP nnnn,X */ case 0xDD: cmp(load_byte(addr_absx()),4); break; /* DEC nnnn,X */ case 0xDE: dec(addr_absx(),7); break; /* CPX #nn */ case 0xE0: cpx(fetch_op(),2); break; /* SBC (nn,X) */ case 0xE1: sbc(load_byte(addr_indx()),6); break; /* CPX nn */ case 0xE4: cpx(load_byte(addr_zero()),3); break; /* SBC nn */ case 0xE5: sbc(load_byte(addr_zero()),3); break; /* INC nn */ case 0xE6: inc(addr_zero(),5); break; /* INX */ case 0xE8: inx(); break; /* SBC #nn */ case 0xE9: sbc(fetch_op(),2); break; /* NOP */ case 0xEA: nop(); break; /* CPX nnnn */ case 0xEC: cpx(load_byte(addr_abs()),4); break; /* SBC nnnn */ case 0xED: sbc(load_byte(addr_abs()),4); break; /* INC nnnn */ case 0xEE: inc(addr_abs(),6); break; /* BEQ nn */ case 0xF0: beq(); break; /* SBC (nn,Y) */ case 0xF1: sbc(load_byte(addr_indy()),5); break; /* SBC nn,X */ case 0xF5: sbc(load_byte(addr_zerox()),4); break; /* INC nn,X */ case 0xF6: inc(addr_zerox(),6); break; /* SED */ case 0xF8: sed(); break; /* SBC nnnn,Y */ case 0xF9: sbc(load_byte(addr_absy()),4); break; /* SBC nnnn,X */ case 0xFD: sbc(load_byte(addr_absx()),4); break; /* INC nnnn,X */ case 0xFE: inc(addr_absx(),7); break; /* Unknown or illegal instruction */ default: D("Unknown instruction: %X at %04x\n", insn,pc()); retval = false; } return retval; }
uint8_t Cpu::fetch_op() { return load_byte(pc_++); }
uint8_t Cpu::pop() { uint16_t addr = ++sp_+Memory::kBaseAddrStack; return load_byte(addr); }