Mercurial > repos > blastem
view m68k.cpu @ 2237:f82c090c1e89
Implement MMAP_ONLY_ODD/EVEN in combination with MMAP_PTR_IDX. Fixes games that have SRAM when a system with TMSS is selected
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 17 Sep 2022 15:38:40 -0700 |
parents | 7d4df6b74263 |
children | d1eec03dca09 |
line wrap: on
line source
info prefix m68k_ opcode_size 16 body m68k_run_op header m68k.h interrupt m68k_interrupt include m68k_util.c sync_cycle m68k_sync_cycle declare typedef m68k_context *(*m68k_reset_handler)(m68k_context *context); void init_m68k_opts(m68k_options *opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider); m68k_context *init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler); void m68k_reset(m68k_context *context); void m68k_print_regs(m68k_context *context); regs dregs 32 d0 d1 d2 d3 d4 d5 d6 d7 aregs 32 a0 a1 a2 a3 a4 a5 a6 a7 pc 32 other_sp 32 scratch1 32 scratch2 32 int_cycle 32 prefetch 16 int_priority 8 int_num 8 int_pending 8 int_pending_num 8 int_ack 8 status 8 ccr 8 xflag 8 nflag 8 zflag 8 vflag 8 cflag 8 reset_handler ptrvoid mem_pointers ptrvoid 8 flags register ccr X 4 carry xflag N 3 sign nflag Z 2 zero zflag V 1 overflow vflag C 0 carry cflag m68k_prefetch if dynarec ccall m68k_read16_noinc context pc mov result prefetch end if interp mov pc scratch1 ocall read_16 mov scratch1 prefetch end add 2 pc pc check_user_mode_swap_ssp_usp local tmp 8 and 0x20 status tmp if tmp else xchg other_sp a7 end m68k_get_sr lsl status 8 scratch1 or ccr scratch1 scratch1 m68k_write32_lowfirst arg value 32 add 2 scratch2 scratch2 mov value scratch1 ocall write_16 sub 2 scratch2 scratch2 lsr value 16 scratch1 ocall write_16 m68k_write32 arg value 32 local tmp 32 mov value tmp lsr value 16 scratch1 ocall write_16 add 2 scratch2 scratch2 mov tmp scratch1 ocall write_16 m68k_read32 local tmp 32 add 2 scratch1 tmp ocall read_16 xchg scratch1 tmp ocall read_16 lsl tmp 16 tmp or tmp scratch1 scratch1 m68k_interrupt cmp int_cycle cycles if >=U #INT_PENDING_NONE cmp 255 int_pending if = mov int_priority int_pending mov int_num int_pending_num else #INT_PENDING_SR_CHANGE cmp 254 int_pending if = mov int_priority int_pending mov int_num int_pending_num else check_user_mode_swap_ssp_usp cycles 6 #save status reg sub 6 a7 a7 m68k_get_sr mov a7 scratch2 ocall write_16 #update status register and 0x78 status status or int_priority status status or 0x20 status status #Interrupt ack cycle mov int_pending int_ack if int_pending_num cycles 4 else #TODO: do the whole E clock variable latency nonsense cycles 13 add 24 int_pending int_pending_num end #save pc add 2 a7 scratch2 m68k_write32_lowfirst pc lsl int_pending_num 2 scratch1 m68k_read32 mov scratch1 pc update_sync end m68k_run_op dispatch prefetch m68k_mem_src arg address 32 arg size 16 arg isdst 8 mov address scratch1 if isdst mov address scratch2 meta ismem 1 end switch size case 0 ocall read_8 case 1 ocall read_16 case 2 m68k_read32 end meta op scratch1 m68k_write_size arg size 16 arg lowfirst 8 switch size case 0 ocall write_8 case 1 ocall write_16 case 2 if lowfirst m68k_write32_lowfirst scratch1 else m68k_write32 scratch1 end end m68k_index_word m68k_prefetch local disp 32 and prefetch 255 disp sext 16 disp disp sext 32 disp disp local index 16 lsr prefetch 12 index local isareg 16 and index 8 isareg and index 7 index local islong 16 and prefetch 2048 islong switch isareg case 0 switch islong case 0 sext 32 dregs.index scratch1 case 2048 mov dregs.index scratch1 end case 8 switch islong case 0 sext 32 aregs.index scratch1 case 2048 mov aregs.index scratch1 end end add disp scratch1 scratch1 m68k_fetch_op_ea arg mode 16 arg reg 16 arg Z 16 arg isdst 8 switch mode case 0 #data reg direct meta op dregs.reg if isdst meta ismem 0 end case 1 #address reg direct meta op aregs.reg if isdst meta ismem 0 end case 2 #address reg indirect m68k_mem_src aregs.reg Z isdst case 3 #postincrement m68k_mem_src aregs.reg Z isdst switch reg case 7 if Z addsize Z aregs.reg aregs.reg else addsize 1 aregs.reg aregs.reg end default addsize Z aregs.reg aregs.reg end case 4 #predecrement switch reg case 7 if Z decsize Z aregs.reg aregs.reg else decsize 1 aregs.reg aregs.reg end default decsize Z aregs.reg aregs.reg end cycles 2 m68k_mem_src aregs.reg Z isdst case 5 #displacement m68k_prefetch sext 32 prefetch scratch1 add scratch1 aregs.reg scratch1 m68k_mem_src scratch1 Z isdst case 6 #indexed m68k_index_word add aregs.reg scratch1 scratch1 m68k_mem_src scratch1 Z isdst case 7 #pc-relative and absolute modes switch reg case 0 #absolute short m68k_prefetch sext 32 prefetch scratch1 m68k_mem_src scratch1 Z isdst case 1 #absolute long local address 32 m68k_prefetch lsl prefetch 16 address m68k_prefetch or prefetch address scratch1 m68k_mem_src scratch1 Z isdst case 2 #pc displaceent m68k_prefetch sext 32 prefetch scratch1 add scratch1 pc scratch1 sub 2 scratch1 scratch1 m68k_mem_src scratch1 Z isdst case 3 #pc indexed m68k_index_word add pc scratch1 scratch1 sub 2 scratch1 scratch1 m68k_mem_src scratch1 Z isdst case 4 #immediate switch Z case 2 local tmp32 32 m68k_prefetch lsl prefetch 16 tmp32 m68k_prefetch or prefetch tmp32 scratch1 default m68k_prefetch mov prefetch scratch1 end meta op scratch1 end end m68k_fetch_src_ea arg mode 16 arg reg 16 arg Z 16 m68k_fetch_op_ea mode reg Z 0 meta src op switch mode case 0 meta src_is_mem 0 case 1 meta src_is_mem 0 default meta src_is_mem 1 end m68k_fetch_dst_ea arg mode 16 arg reg 16 arg Z 16 m68k_fetch_op_ea mode reg Z 1 meta dst op m68k_save_dst arg Z 16 if ismem m68k_write_size Z 0 end 1101DDD0ZZMMMRRR add_ea_dn invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_src_ea M R Z add src dregs.D dregs.D Z update_flags XNZVC m68k_prefetch 1101DDD1ZZMMMRRR add_dn_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_dst_ea M R Z add dregs.D dst dst Z update_flags XNZVC m68k_save_dst Z m68k_prefetch 1101AAAZ11MMMRRR adda invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 local size 16 local ext_src 32 if Z mov 2 size else mov 1 size end m68k_fetch_src_ea M R size switch size case 1 sext 32 src ext_src meta src ext_src end add src aregs.A aregs.A m68k_prefetch 00000110ZZMMMRRR addi local immed 32 invalid Z 3 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 #fetch immediate operand m68k_prefetch switch Z case 2 lsl prefetch 16 immed m68k_prefetch or prefetch immed immed default mov prefetch immed end #fetch dst EA m68k_fetch_dst_ea M R Z add immed dst dst Z update_flags XNZVC m68k_save_dst Z m68k_prefetch 0101III0ZZMMMRRR addq invalid Z 3 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 local src 32 switch I case 0 mov 8 src default mov I src end m68k_fetch_dst_ea M R Z switch M case 1 add src dst dst Z default add src dst dst Z update_flags XNZVC end m68k_save_dst Z m68k_prefetch 1101DDD1ZZ000SSS addx_dy_dx invalid Z 3 adc dregs.S dregs.D dregs.D Z update_flags XNVC switch Z case 0 local tmp8 8 mov dregs.D tmp8 if tmp8 update_flags Z0 end case 1 local tmp16 16 mov dregs.D tmp16 if tmp16 update_flags Z0 end case 2 if dregs.D update_flags Z0 end end m68k_prefetch 1101DDD1ZZ001SSS addx_ay_ax invalid Z 3 if Z decsize Z aregs.S aregs.S else switch S case 7 sub 2 aregs.S aregs.S default decsize Z aregs.S aregs.S end end mov aregs.S scratch1 switch Z case 0 ocall read_8 case 1 ocall read_16 case 2 m68k_read32 end mov scratch1 scratch2 if Z decsize Z aregs.D aregs.D else switch D case 7 sub 2 aregs.D aregs.D default decsize Z aregs.D aregs.D end end mov aregs.D scratch1 switch Z case 0 ocall read_8 case 1 ocall read_16 case 2 m68k_read32 end adc scratch2 scratch1 scratch1 Z update_flags XNVC switch Z case 0 local tmp8 8 mov dregs.D tmp8 if tmp8 update_flags Z0 end case 1 local tmp16 16 mov dregs.D tmp16 if tmp16 update_flags Z0 end case 2 if dregs.D update_flags Z0 end end mov aregs.D scratch2 m68k_write_size Z 0 m68k_prefetch 1100DDD0ZZMMMRRR and_ea_dn invalid M 1 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_src_ea M R Z and src dregs.D dregs.D Z update_flags NZV0C0 m68k_prefetch 1100DDD1ZZMMMRRR and_dn_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_dst_ea M R Z and dregs.D dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 00000010ZZMMMRRR andi local immed 32 invalid Z 3 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 #fetch immediate operand m68k_prefetch switch Z case 2 lsl prefetch 16 immed m68k_prefetch or prefetch immed immed default mov prefetch immed end #fetch dst EA m68k_fetch_dst_ea M R Z and immed dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 0000001000111100 andi_to_ccr #fetch immediate operand m68k_prefetch and prefetch ccr ccr m68k_prefetch 1011DDD1ZZMMMRRR eor_dn_ea invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_dst_ea M R Z xor dregs.D dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 00001010ZZMMMRRR eori local immed 32 invalid Z 3 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 #fetch immediate operand m68k_prefetch switch Z case 2 lsl prefetch 16 immed m68k_prefetch or prefetch immed immed default mov prefetch immed end #fetch dst EA m68k_fetch_dst_ea M R Z xor immed dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 0000001000111100 eori_to_ccr #fetch immediate operand m68k_prefetch xor prefetch ccr ccr m68k_prefetch 1000DDD0ZZMMMRRR or_ea_dn invalid M 1 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_src_ea M R Z or src dregs.D dregs.D Z update_flags NZV0C0 m68k_prefetch 1000DDD1ZZMMMRRR or_dn_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_dst_ea M R Z or dregs.D dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 00000000ZZMMMRRR ori local immed 32 invalid Z 3 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 #fetch immediate operand m68k_prefetch switch Z case 2 lsl prefetch 16 immed m68k_prefetch or prefetch immed immed default mov prefetch immed end #fetch dst EA m68k_fetch_dst_ea M R Z or immed dst dst Z update_flags NZV0C0 m68k_save_dst Z m68k_prefetch 0000000000111100 ori_to_ccr #fetch immediate operand m68k_prefetch or prefetch ccr ccr m68k_prefetch 1001DDD0ZZMMMRRR sub_ea_dn invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_src_ea M R Z sub src dregs.D dregs.D Z update_flags XNZVC m68k_prefetch 1001DDD1ZZMMMRRR sub_dn_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 invalid Z 3 m68k_fetch_dst_ea M R Z sub dregs.D dst dst Z update_flags XNZVC m68k_save_dst Z m68k_prefetch 1001AAAZ11MMMRRR suba invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 local size 16 local ext_src 32 if Z mov 2 size else mov 1 size end m68k_fetch_src_ea M R size switch size case 1 sext 32 src ext_src meta src ext_src end sub src aregs.A aregs.A m68k_prefetch 00000100ZZMMMRRR subi local immed 32 invalid Z 3 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 #fetch immediate operand m68k_prefetch switch Z case 2 lsl prefetch 16 immed m68k_prefetch or prefetch immed immed default mov prefetch immed end #fetch dst EA m68k_fetch_dst_ea M R Z sub immed dst dst Z update_flags XNZVC m68k_save_dst Z m68k_prefetch 0101III1ZZMMMRRR subq invalid Z 3 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 local src 32 switch I case 0 mov 8 src default mov I src end m68k_fetch_dst_ea M R Z switch M case 1 sub src dst dst Z default sub src dst dst Z update_flags XNZVC end m68k_save_dst Z m68k_prefetch 1110CCC0ZZ001RRR lsri invalid Z 3 switch C case 0 meta shift 8 default meta shift C end lsr dregs.R shift dregs.R Z update_flags XNZV0C add shift shift shift switch Z case 2 add 4 shift shift default add 2 shift shift end cycles shift #TODO: should this happen before or after the majority of the shift? m68k_prefetch 1110CCC0ZZ101RRR lsr_dn invalid Z 3 local shift 8 and dregs.C 63 shift lsr dregs.R shift dregs.R Z update_flags XNZV0C add shift shift shift switch Z case 2 add 4 shift shift default add 2 shift shift end cycles shift #TODO: should this happen before or after the majority of the shift? m68k_prefetch 1110001011MMMRRR lsr_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 m68k_fetch_dst_ea M R 0 lsr dst 1 dst update_flags XNZV0C m68k_save_dst 0 m68k_prefetch 1110CCC1ZZ001RRR lsli invalid Z 3 switch C case 0 meta shift 8 default meta shift C end lsl dregs.R shift dregs.R Z update_flags XNZV0C add shift shift shift switch Z case 2 add 4 shift shift default add 2 shift shift end cycles shift #TODO: should this happen before or after the majority of the shift? m68k_prefetch 1110CCC1ZZ101RRR lsl_dn invalid Z 3 local shift 8 and dregs.C 63 shift lsl dregs.R shift dregs.R Z update_flags XNZV0C add shift shift shift switch Z case 2 add 4 shift shift default add 2 shift shift end cycles shift #TODO: should this happen before or after the majority of the shift? m68k_prefetch 1110001111MMMRRR lsl_ea invalid M 0 invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 m68k_fetch_dst_ea M R 0 lsl dst 1 dst update_flags XNZV0C m68k_save_dst 0 m68k_prefetch 00ZZRRRMMMEEESSS move invalid Z 0 invalid M 1 invalid M 7 #not actually invalid, but will be handled separately due to DSL limitations invalid E 7 S 5 invalid E 7 S 6 invalid E 7 S 7 local size 8 local memsrc 32 #move uses a different size format than most instructions switch Z case 1 mov 0 size case 2 mov 2 size case 3 mov 1 size end m68k_fetch_src_ea E S size if src_is_mem #avoid clobbering src if we need scratch1 mov src memsrc meta src memsrc end cmp 0 src size update_flags NZV0C0 switch M case 0 mov src dregs.R size case 2 mov aregs.R scratch2 mov src scratch1 m68k_write_size size 0 case 3 mov aregs.R scratch2 mov src scratch1 switch R case 7 if size addsize size aregs.R aregs.R else addsize 1 aregs.R aregs.R end default addsize size aregs.R aregs.R end m68k_write_size size 0 case 4 mov src scratch1 switch R case 7 if size decsize size aregs.R aregs.R else decsize 1 aregs.R aregs.R end default decsize size aregs.R aregs.R end mov aregs.R scratch2 m68k_write_size size 1 case 5 m68k_prefetch sext 32 prefetch scratch2 add aregs.R scratch2 scratch2 mov src scratch1 m68k_write_size size 0 case 6 m68k_index_word add aregs.R scratch1 scratch2 mov src scratch1 m68k_write_size size 0 end m68k_prefetch 00ZZ00M111EEESSS move_abs invalid E 7 S 5 invalid E 7 S 6 invalid E 7 S 7 invalid Z 0 local size 8 local memsrc 32 #move uses a different size format than most instructions switch Z case 1 mov 0 size case 2 mov 2 size case 3 mov 1 size end m68k_fetch_src_ea E S size if src_is_mem #avoid clobbering src if we need scratch1 mov src memsrc meta src memsrc end cmp 0 src size update_flags NZV0C0 switch M case 0 m68k_prefetch sext 32 prefetch scratch2 case 1 m68k_prefetch lsl prefetch 16 scratch2 m68k_prefetch or prefetch scratch2 scratch2 end mov src scratch1 m68k_write_size size 0 m68k_prefetch 00ZZRRR001EEESSS movea local size 8 invalid Z 0 invalid Z 1 invalid E 7 S 5 invalid E 7 S 6 invalid E 7 S 7 switch Z case 2 mov 2 size case 3 mov 1 size end m68k_fetch_src_ea E S size switch Z case 2 mov src aregs.R case 3 sext 32 src aregs.R end m68k_prefetch 0100010011MMMRRR move_to_ccr invalid M 1 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 m68k_fetch_src_ea M R 1 mov scratch1 ccr m68k_prefetch 0100011011MMMRRR move_to_sr invalid M 1 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 m68k_fetch_src_ea M R 1 mov scratch1 ccr lsr scratch1 8 status update_sync m68k_prefetch 0100000011MMMRRR move_from_sr invalid M 1 invalid M 7 R 2 invalid M 7 R 3 invalid M 7 R 4 invalid M 7 R 5 invalid M 7 R 6 invalid M 7 R 7 m68k_fetch_dst_ea M R 1 lsl status 8 scratch1 or ccr scratch1 scratch1 mov scratch1 dst m68k_save_dst 1 m68k_prefetch 0100111001110000 reset cycles 124 if reset_handler pcall reset_handler m68k_reset_handler context end