This commit is contained in:
aliaspider 2014-12-10 12:53:26 +01:00
parent 6d7fd87e07
commit a926a68eb3
15 changed files with 4 additions and 980 deletions

View File

@ -45,9 +45,6 @@ void execute_swi_thumb(u32 pc);
void function_cc execute_store_u32_safe(u32 address, u32 source);
void step_debug_arm(u32 pc);
#define write32(value) \
*((u32 *)translation_ptr) = value; \
translation_ptr += 4 \
@ -1958,9 +1955,5 @@ void execute_swi_hle_div_c()
generate_update_pc(pc); \
generate_indirect_branch_no_cycle_update(type) \
#define generate_step_debug() \
generate_function_call(step_debug_arm); \
write32(pc) \
#endif

View File

@ -37,9 +37,6 @@
.global execute_bios_ptr_protected
.global execute_bios_rom_ptr
.global step_debug_arm
.global invalidate_icache_region
.global invalidate_cache_region
@ -934,35 +931,6 @@ execute_patch_bios_protect:
type##_reg_scratch(12) ;\
type##_reg_scratch(14) ;\
step_debug_arm:
save_flags()
collapse_flags(r0)
ldr r0, [reg_base, #REG_CPSR] @ r1 = cpsr
tst r0, #0x20 @ see if Thumb bit is set
ldr r0, [lr] @ load PC
mvn r1, reg_cycles @ load cycle counter
beq 1f @ if not goto ARM mode
scratch_regs_thumb(save)
store_registers_thumb() @ write back Thumb regs
call_c_function(step_debug) @ call debug step
scratch_regs_thumb(restore)
restore_flags()
add pc, lr, #4 @ return
1:
scratch_regs_arm(save)
store_registers_arm() @ write back ARM regs
call_c_function(step_debug) @ call debug step
scratch_regs_arm(restore)
restore_flags()
add pc, lr, #4 @ return, skipping PC
.pool
.comm memory_map_read 0x8000

259
cpu.c
View File

@ -1670,7 +1670,6 @@ char *cpu_mode_names[] =
\
case 0xF: \
/* Reserved - treat as "never" */ \
quit(); \
arm_next_instruction(); \
break; \
} \
@ -3988,69 +3987,6 @@ char *cpu_mode_names[] =
} \
} \
void print_arm_registers()
{
u32 i, i2, i3;
for(i = 0, i3 = 0; i < 4; i++)
{
debug_screen_printf(" ");
for(i2 = 0; i2 < 4; i2++, i3++)
{
debug_screen_printf("R%02d %08x ", i3, reg[i3]);
}
debug_screen_newline(1);
}
}
void print_thumb_instruction()
{
debug_screen_printf("Thumb instruction at PC: %04x",
read_memory16(reg[REG_PC]));
debug_screen_newline(1);
}
void print_arm_instruction()
{
debug_screen_printf("ARM instruction at PC: %08x",
read_memory32(reg[REG_PC]));
debug_screen_newline(1);
}
void print_flags()
{
u32 cpsr = reg[REG_CPSR];
debug_screen_newline(1);
debug_screen_printf(
" N: %d Z: %d C: %d V: %d CPSR: %08x SPSR: %08x mode: %s",
(cpsr >> 31) & 0x01, (cpsr >> 30) & 0x01, (cpsr >> 29) & 0x01,
(cpsr >> 28) & 0x01, cpsr, spsr[reg[CPU_MODE]],
cpu_mode_names[reg[CPU_MODE]]);
debug_screen_newline(2);
}
const u32 stack_print_lines = 2;
void print_stack()
{
u32 i, i2, i3;
debug_screen_printf("Stack:");
debug_screen_newline(1);
for(i = 0, i3 = reg[REG_SP]; i < stack_print_lines; i++)
{
for(i2 = 0; i2 < 5; i2++, i3 += 4)
{
debug_screen_printf(" %08x", read_memory32(i3));
}
if(i != stack_print_lines)
debug_screen_newline(1);
}
debug_screen_newline(1);
}
u32 instruction_count = 0;
u32 output_field = 0;
@ -4060,199 +3996,6 @@ u32 last_instruction = 0;
u32 in_interrupt = 0;
void debug_on()
{
current_debug_state = STEP;
debug_screen_start();
}
void debug_off(debug_state new_debug_state)
{
current_debug_state = new_debug_state;
debug_screen_end();
}
void function_cc step_debug(u32 pc, u32 cycles)
{
u32 thumb = 0;
reg[REG_PC] = pc;
if(reg[REG_CPSR] & 0x20)
thumb = 1;
instruction_count++;
switch(current_debug_state)
{
case PC_BREAKPOINT:
if(reg[REG_PC] == breakpoint_value)
debug_on();
break;
case Z_BREAKPOINT:
if(reg[REG_Z_FLAG] == 1)
debug_on();
break;
case VCOUNT_BREAKPOINT:
if(io_registers[REG_VCOUNT] == breakpoint_value)
debug_on();
break;
case COUNTDOWN_BREAKPOINT:
if(breakpoint_value == 0)
debug_on();
else
breakpoint_value--;
break;
case COUNTDOWN_BREAKPOINT_B:
if(breakpoint_value == instruction_count)
debug_on();
break;
case COUNTDOWN_BREAKPOINT_C:
{
if(pc == 0x18)
in_interrupt++;
if((breakpoint_value == 0) && (in_interrupt == 0))
{
debug_on();
}
else
if(in_interrupt == 0)
breakpoint_value--;
if(in_interrupt && (pc == 0x13c))
in_interrupt--;
break;
}
default:
break;
}
if((current_debug_state == STEP) ||
(current_debug_state == STEP_RUN))
{
u32 key = 0;
if(output_field >= num_output_fields)
{
output_field = 0;
debug_screen_clear();
}
if(thumb)
print_thumb_instruction(cycles);
else
print_arm_instruction(cycles);
print_arm_registers();
print_flags();
print_stack();
printf("%x instructions in, VCOUNT %d, cycles remaining: %d \n",
instruction_count, io_registers[REG_VCOUNT], cycles);
debug_screen_update();
output_field++;
if(current_debug_state != STEP_RUN)
{
key = getchar();
}
switch(key)
{
case 'd':
dump_translation_cache();
break;
case 'z':
debug_off(Z_BREAKPOINT);
break;
#ifdef STDIO_DEBUG
case 'x':
printf("break at PC (hex): ");
scanf("%08x", &breakpoint_value);
debug_off(PC_BREAKPOINT);
break;
case 'c':
printf("break after N instructions (hex): ");
scanf("%08x", &breakpoint_value);
breakpoint_value -= 1;
debug_off(COUNTDOWN_BREAKPOINT);
break;
case 'f':
printf("break after N instructions, skip in IRQ (hex): ");
scanf("%08x", &breakpoint_value);
breakpoint_value -= 1;
debug_off(COUNTDOWN_BREAKPOINT_C);
break;
case 'g':
printf("break after N instructions (since start): ");
scanf("%d", &breakpoint_value);
debug_off(COUNTDOWN_BREAKPOINT_B);
break;
case 'v':
printf("break at VCOUNT: ");
scanf("%d", &breakpoint_value);
debug_off(VCOUNT_BREAKPOINT);
break;
#endif
case 's':
current_debug_state = STEP_RUN;
break;
case 'r':
debug_off(RUN);
break;
case 'b':
debug_off(PC_BREAKPOINT);
break;
case 't':
global_cycles_per_instruction = 0;
debug_off(RUN);
break;
case 'a':
{
break;
}
case 'q':
quit();
}
}
last_instruction = reg[REG_PC];
if(thumb)
reg[REG_PC] = pc + 2;
else
reg[REG_PC] = pc + 4;
}
void set_cpu_mode(cpu_mode_type new_mode)
{
u32 i;
@ -4347,7 +4090,6 @@ void execute_arm(u32 cycles)
arm_loop:
collapse_flags();
step_debug(pc, cycles_remaining);
cycles_per_instruction = global_cycles_per_instruction;
old_pc = pc;
@ -4364,7 +4106,6 @@ void execute_arm(u32 cycles)
thumb_loop:
collapse_flags();
step_debug(pc, cycles_remaining);
old_pc = pc;
execute_thumb_instruction();

19
cpu.h
View File

@ -85,19 +85,6 @@ typedef enum
CHANGED_PC_STATUS = 31
} ext_reg_numbers;
typedef enum
{
STEP,
PC_BREAKPOINT,
VCOUNT_BREAKPOINT,
Z_BREAKPOINT,
COUNTDOWN_BREAKPOINT,
COUNTDOWN_BREAKPOINT_B,
COUNTDOWN_BREAKPOINT_C,
STEP_RUN,
RUN
} debug_state;
typedef enum
{
TRANSLATION_REGION_RAM,
@ -105,7 +92,6 @@ typedef enum
TRANSLATION_REGION_BIOS
} translation_region_type;
extern debug_state current_debug_state;
extern u32 instruction_count;
extern u32 last_instruction;
@ -113,9 +99,6 @@ void execute_arm(u32 cycles);
void raise_interrupt(irq_type irq_raised);
void set_cpu_mode(cpu_mode_type new_mode);
void debug_on();
void debug_off(debug_state new_debug_state);
u32 function_cc execute_load_u8(u32 address);
u32 function_cc execute_load_u16(u32 address);
u32 function_cc execute_load_u32(u32 address);
@ -195,8 +178,6 @@ extern u32 spsr[6];
extern u32 cpu_modes[32];
extern const u32 psr_masks[16];
extern u32 breakpoint_value;
extern u32 memory_region_access_read_u8[16];
extern u32 memory_region_access_read_s8[16];
extern u32 memory_region_access_read_u16[16];

View File

@ -2846,7 +2846,6 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \
sprintf(buffer, "bad jump %x (%x) (%x)\n", pc, reg[REG_PC], \
last_instruction); \
printf("%s", buffer); \
quit(); \
} \
block_address = (u8 *)(-1); \
break; \
@ -3285,8 +3284,7 @@ s32 translate_block_arm(u32 pc, translation_region_type
while(pc != block_end_pc)
{
block_data[block_data_position].block_offset = translation_ptr;
arm_base_cycles();
/*generate_step_debug();*/
arm_base_cycles();
translate_arm_instruction();
block_data_position++;
@ -3503,8 +3501,7 @@ s32 translate_block_thumb(u32 pc, translation_region_type
while(pc != block_end_pc)
{
block_data[block_data_position].block_offset = translation_ptr;
thumb_base_cycles();
/*generate_step_debug();*/
thumb_base_cycles();
translate_thumb_instruction();
block_data_position++;

View File

@ -3418,7 +3418,6 @@ void gba_load_state(const void* src)
for(i = 0; i < 4; i++)
gbc_sound_channel[i].sample_data = square_pattern_duty[2];
current_debug_state = STEP;
instruction_count = 0;
reg[CHANGED_PC_STATUS] = 1;

226
main.c
View File

@ -26,26 +26,11 @@ void vblank_interrupt_handler(u32 sub, u32 *parg);
timer_type timer[4];
//debug_state current_debug_state = COUNTDOWN_BREAKPOINT;
//debug_state current_debug_state = PC_BREAKPOINT;
u32 breakpoint_value = 0x7c5000;
debug_state current_debug_state = RUN;
//debug_state current_debug_state = STEP_RUN;
//u32 breakpoint_value = 0;
frameskip_type current_frameskip_type = auto_frameskip;
u32 global_cycles_per_instruction = 1;
u32 random_skip = 0;
u32 fps_debug = 0;
u32 frameskip_value = 2;
u64 last_frame_interval_timestamp;
u32 skip_next_frame = 0;
u32 frameskip_counter = 0;
u32 cpu_ticks = 0;
@ -71,9 +56,6 @@ u32 flush_ram_count = 0;
u32 gbc_update_count = 0;
u32 oam_update_count = 0;
u32 synchronize_flag = 1;
u32 update_backup_flag = 1;
char main_path[512];
char save_path[512];
@ -128,8 +110,6 @@ void init_main()
{
u32 i;
skip_next_frame = 0;
for(i = 0; i < 4; i++)
{
dma[i].start_type = DMA_INACTIVE;
@ -179,102 +159,8 @@ void print_memory_stats(u32 *counter, u32 *region_stats, char *stats_str)
memset(region_stats, 0, sizeof(u32) * 16);
}
u32 event_cycles = 0;
const u32 event_cycles_trigger = 60 * 5;
u32 no_alpha = 0;
void trigger_ext_event()
{
static u32 event_number = 0;
static u64 benchmark_ticks[16];
u64 new_ticks;
return;
if(event_number)
{
get_ticks_us(&new_ticks);
benchmark_ticks[event_number - 1] =
new_ticks - benchmark_ticks[event_number - 1];
}
current_frameskip_type = no_frameskip;
no_alpha = 0;
synchronize_flag = 0;
switch(event_number)
{
case 0:
// Full benchmark, run normally
break;
case 1:
// No alpha blending
no_alpha = 1;
break;
case 2:
// No video benchmark
// Set frameskip really high + manual
current_frameskip_type = manual_frameskip;
frameskip_value = 1000000;
break;
case 3:
// No CPU benchmark
// Put CPU in halt mode, put it in IRQ mode with interrupts off
reg[CPU_HALT_STATE] = CPU_HALT;
reg[REG_CPSR] = 0xD2;
break;
case 4:
// No CPU or video benchmark
reg[CPU_HALT_STATE] = CPU_HALT;
reg[REG_CPSR] = 0xD2;
current_frameskip_type = manual_frameskip;
frameskip_value = 1000000;
break;
case 5:
{
// Done
char *print_strings[] =
{
"Full test ",
"No blending ",
"No video ",
"No CPU ",
"No CPU/video",
"CPU speed ",
"Video speed ",
"Alpha cost "
};
u32 i;
benchmark_ticks[6] = benchmark_ticks[0] - benchmark_ticks[2];
benchmark_ticks[5] = benchmark_ticks[0] - benchmark_ticks[4] -
benchmark_ticks[6];
benchmark_ticks[7] = benchmark_ticks[0] - benchmark_ticks[1];
printf("Benchmark results (%d frames): \n", event_cycles_trigger);
for(i = 0; i < 8; i++)
{
printf(" %s: %d ms (%f ms per frame)\n",
print_strings[i], (u32)benchmark_ticks[i] / 1000,
(float)(benchmark_ticks[i] / (1000.0 * event_cycles_trigger)));
if(i == 4)
printf("\n");
}
quit();
}
}
event_cycles = 0;
get_ticks_us(benchmark_ticks + event_number);
event_number++;
}
u32 update_gba()
{
irq_type irq_raised = IRQ_NONE;
@ -383,33 +269,13 @@ u32 update_gba()
oam_update_count = 0;
flush_ram_count = 0;
#ifdef __LIBRETRO__
switch_to_main_thread();
update_gbc_sound(cpu_ticks);
gbc_sound_update = 0;
#else
if(update_input())
continue;
update_gbc_sound(cpu_ticks);
update_screen();
synchronize();
if(update_backup_flag)
update_backup();
#endif
process_cheats();
event_cycles++;
if(event_cycles == event_cycles_trigger)
{
trigger_ext_event();
continue;
}
vcount = 0;
}
@ -446,98 +312,6 @@ u32 update_gba()
return execute_cycles;
}
#ifdef PSP_BUILD
u32 real_frame_count = 0;
u32 virtual_frame_count = 0;
u32 num_skipped_frames = 0;
void vblank_interrupt_handler(u32 sub, u32 *parg)
{
real_frame_count++;
}
void synchronize()
{
char char_buffer[64];
u64 new_ticks, time_delta;
s32 used_frameskip = frameskip_value;
if(!synchronize_flag)
{
used_frameskip = 4;
virtual_frame_count = real_frame_count - 1;
}
skip_next_frame = 0;
virtual_frame_count++;
if(real_frame_count >= virtual_frame_count)
{
if((real_frame_count > virtual_frame_count) &&
(current_frameskip_type == auto_frameskip) &&
(num_skipped_frames < frameskip_value))
{
skip_next_frame = 1;
num_skipped_frames++;
}
else
{
virtual_frame_count = real_frame_count;
num_skipped_frames = 0;
}
// Here so that the home button return will eventually work.
// If it's not running fullspeed anyway this won't really hurt
// it much more.
delay_us(1);
}
else
{
if(synchronize_flag)
sceDisplayWaitVblankStart();
}
if(current_frameskip_type == manual_frameskip)
{
frameskip_counter = (frameskip_counter + 1) %
(used_frameskip + 1);
if(random_skip)
{
if(frameskip_counter != (rand() % (used_frameskip + 1)))
skip_next_frame = 1;
}
else
{
if(frameskip_counter)
skip_next_frame = 1;
}
}
/* sprintf(char_buffer, "%08d %08d %d %d %d\n",
real_frame_count, virtual_frame_count, num_skipped_frames,
real_frame_count - virtual_frame_count, skip_next_frame);
print_string(char_buffer, 0xFFFF, 0x0000, 0, 10); */
/*
sprintf(char_buffer, "%02d %02d %06d %07d", frameskip, (u32)ms_needed,
ram_translation_ptr - ram_translation_cache, rom_translation_ptr -
rom_translation_cache);
print_string(char_buffer, 0xFFFF, 0x0000, 0, 0);
*/
}
#endif
void quit()
{
if(!update_backup_flag)
update_backup();
sound_exit();
}
void reset_gba()
{
init_main();

13
main.h
View File

@ -66,10 +66,7 @@ extern u32 frame_ticks;
extern u32 execute_cycles;
extern frameskip_type current_frameskip_type;
extern u32 frameskip_value;
extern u32 random_skip;
extern u32 global_cycles_per_instruction;
extern u32 synchronize_flag;
extern u32 skip_next_frame;
extern u32 cycle_memory_access;
extern u32 cycle_pc_relative_access;
@ -86,17 +83,11 @@ extern u64 base_timestamp;
extern char main_path[512];
extern char save_path[512];
extern u32 update_backup_flag;
u32 update_gba();
void reset_gba();
#ifdef __LIBRETRO__
#define synchronize()
void init_main();
#else
void synchronize();
#endif
void quit();
void delay_us(u32 us_count);
void get_ticks_us(u64 *tick_return);
void game_name_ext(char *src, char *buffer, char *extension);

View File

@ -47,8 +47,6 @@ u32 execute_ror_flags_reg(u32 value, u32 shift);
void execute_aligned_store32(u32 address, u32 value);
u32 execute_aligned_load32(u32 address);
void step_debug_mips(u32 pc);
void reg_check();
typedef enum
@ -2520,10 +2518,6 @@ u8 swi_hle_handle[256] =
generate_load_pc(reg_a0, pc); \
generate_indirect_branch_no_cycle_update(type) \
#define generate_step_debug() \
generate_load_imm(reg_a0, pc); \
generate_function_call(step_debug_mips) \
#define generate_update_pc_reg() \
generate_load_pc(reg_a0, pc); \
mips_emit_sw(reg_a0, reg_base, (REG_PC * 4)) \

View File

@ -45,7 +45,6 @@
.global execute_arm_translate
.global invalidate_icache_region
.global invalidate_all_cache
.global step_debug_mips
.global reg_check
.global memory_map_read
@ -3403,19 +3402,6 @@ iac_loop:
jr $ra # return
nop
step_debug_mips:
addiu $sp, $sp, -4
sw $ra, ($sp)
collapse_flags
save_registers
jal step_debug
addiu $5, $17, 0
restore_registers
lw $ra, ($sp)
jr $ra
addiu $sp, $sp, 4
memory_map_read:
.space 0x8000

View File

@ -123,6 +123,5 @@ void sound_read_savestate(void);
void render_audio(void);
void reset_sound();
void sound_exit();
#endif

370
video.c
View File

@ -19,77 +19,10 @@
#include "common.h"
#ifdef PSP_BUILD
#include <pspctrl.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include <psppower.h>
#include <psprtc.h>
static float *screen_vertex = (float *)0x441FC100;
static u32 *ge_cmd = (u32 *)0x441FC000;
static u16 *psp_gu_vram_base = (u16 *)(0x44000000);
static u32 *ge_cmd_ptr = (u32 *)0x441FC000;
static u32 gecbid;
static u32 video_direct = 0;
static u32 __attribute__((aligned(16))) display_list[32];
#define GBA_SCREEN_WIDTH 240
#define GBA_SCREEN_HEIGHT 160
#define PSP_SCREEN_WIDTH 480
#define PSP_SCREEN_HEIGHT 272
#define PSP_LINE_SIZE 512
#define PSP_ALL_BUTTON_MASK 0xFFFF
#define GE_CMD_FBP 0x9C
#define GE_CMD_FBW 0x9D
#define GE_CMD_TBP0 0xA0
#define GE_CMD_TBW0 0xA8
#define GE_CMD_TSIZE0 0xB8
#define GE_CMD_TFLUSH 0xCB
#define GE_CMD_CLEAR 0xD3
#define GE_CMD_VTYPE 0x12
#define GE_CMD_BASE 0x10
#define GE_CMD_VADDR 0x01
#define GE_CMD_IADDR 0x02
#define GE_CMD_PRIM 0x04
#define GE_CMD_FINISH 0x0F
#define GE_CMD_SIGNAL 0x0C
#define GE_CMD_NOP 0x00
#define GE_CMD(cmd, operand) \
*ge_cmd_ptr = (((GE_CMD_##cmd) << 24) | (operand)); \
ge_cmd_ptr++ \
static u16 *screen_texture = (u16 *)(0x4000000 + (512 * 272 * 2));
static u16 *current_screen_texture = (u16 *)(0x4000000 + (512 * 272 * 2));
static u16 *screen_pixels = (u16 *)(0x4000000 + (512 * 272 * 2));
static u32 screen_pitch = 240;
static void Ge_Finish_Callback(int id, void *arg)
{
}
#define get_screen_pixels() \
screen_pixels \
#define get_screen_pitch() \
screen_pitch \
#elif defined(__LIBRETRO__)
u16 gba_screen_pixels[GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT];
#define get_screen_pixels() gba_screen_pixels
#define get_screen_pitch() GBA_SCREEN_PITCH
#endif
static void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
u32 enable_flags, u32 dispcnt, u32 bldcnt, const tile_layer_render_struct
@ -3229,9 +3162,6 @@ void update_scanline()
order_layers((dispcnt >> 8) & active_layers[video_mode]);
if(skip_next_frame)
return;
// If the screen is in in forced blank draw pure white.
if(dispcnt & 0x80)
{
@ -3265,310 +3195,10 @@ void update_scanline()
affine_reference_y[1] += (s16)io_registers[REG_BG3PD];
}
#ifdef PSP_BUILD
u32 screen_flip = 0;
void flip_screen()
{
if(video_direct == 0)
{
u32 *old_ge_cmd_ptr = ge_cmd_ptr;
sceKernelDcacheWritebackAll();
// Render the current screen
ge_cmd_ptr = ge_cmd + 2;
GE_CMD(TBP0, ((u32)screen_pixels & 0x00FFFFFF));
GE_CMD(TBW0, (((u32)screen_pixels & 0xFF000000) >> 8) |
GBA_SCREEN_WIDTH);
ge_cmd_ptr = old_ge_cmd_ptr;
sceGeListEnQueue(ge_cmd, ge_cmd_ptr, gecbid, NULL);
// Flip to the next screen
screen_flip ^= 1;
if(screen_flip)
screen_pixels = screen_texture + (240 * 160 * 2);
else
screen_pixels = screen_texture;
}
}
#endif
#ifndef __LIBRETRO__
u32 frame_to_render;
void update_screen()
{
if(!skip_next_frame)
flip_screen();
}
#endif
#ifdef PSP_BUILD
void init_video()
{
sceDisplaySetMode(0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
sceDisplayWaitVblankStart();
sceDisplaySetFrameBuf((void*)psp_gu_vram_base, PSP_LINE_SIZE,
PSP_DISPLAY_PIXEL_FORMAT_565, PSP_DISPLAY_SETBUF_NEXTFRAME);
sceGuInit();
sceGuStart(GU_DIRECT, display_list);
sceGuDrawBuffer(GU_PSM_5650, (void*)0, PSP_LINE_SIZE);
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
(void*)0, PSP_LINE_SIZE);
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuOffset(2048 - (PSP_SCREEN_WIDTH / 2), 2048 - (PSP_SCREEN_HEIGHT / 2));
sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
sceGuScissor(0, 0, PSP_SCREEN_WIDTH + 1, PSP_SCREEN_HEIGHT + 1);
sceGuEnable(GU_SCISSOR_TEST);
sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
sceGuEnable(GU_TEXTURE_2D);
sceGuFrontFace(GU_CW);
sceGuDisable(GU_BLEND);
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
PspGeCallbackData gecb;
gecb.signal_func = NULL;
gecb.signal_arg = NULL;
gecb.finish_func = Ge_Finish_Callback;
gecb.finish_arg = NULL;
gecbid = sceGeSetCallback(&gecb);
screen_vertex[0] = 0 + 0.5;
screen_vertex[1] = 0 + 0.5;
screen_vertex[2] = 0 + 0.5;
screen_vertex[3] = 0 + 0.5;
screen_vertex[4] = 0;
screen_vertex[5] = GBA_SCREEN_WIDTH - 0.5;
screen_vertex[6] = GBA_SCREEN_HEIGHT - 0.5;
screen_vertex[7] = PSP_SCREEN_WIDTH - 0.5;
screen_vertex[8] = PSP_SCREEN_HEIGHT - 0.5;
screen_vertex[9] = 0;
// Set framebuffer to PSP VRAM
GE_CMD(FBP, ((u32)psp_gu_vram_base & 0x00FFFFFF));
GE_CMD(FBW, (((u32)psp_gu_vram_base & 0xFF000000) >> 8) | PSP_LINE_SIZE);
// Set texture 0 to the screen texture
GE_CMD(TBP0, ((u32)screen_texture & 0x00FFFFFF));
GE_CMD(TBW0, (((u32)screen_texture & 0xFF000000) >> 8) | GBA_SCREEN_WIDTH);
// Set the texture size to 256 by 256 (2^8 by 2^8)
GE_CMD(TSIZE0, (8 << 8) | 8);
// Flush the texture cache
GE_CMD(TFLUSH, 0);
// Use 2D coordinates, no indeces, no weights, 32bit float positions,
// 32bit float texture coordinates
GE_CMD(VTYPE, (1 << 23) | (0 << 11) | (0 << 9) |
(3 << 7) | (0 << 5) | (0 << 2) | 3);
// Set the base of the index list pointer to 0
GE_CMD(BASE, 0);
// Set the rest of index list pointer to 0 (not being used)
GE_CMD(IADDR, 0);
// Set the base of the screen vertex list pointer
GE_CMD(BASE, ((u32)screen_vertex & 0xFF000000) >> 8);
// Set the rest of the screen vertex list pointer
GE_CMD(VADDR, ((u32)screen_vertex & 0x00FFFFFF));
// Primitive kick: render sprite (primitive 6), 2 vertices
GE_CMD(PRIM, (6 << 16) | 2);
// Done with commands
GE_CMD(FINISH, 0);
// Raise signal interrupt
GE_CMD(SIGNAL, 0);
GE_CMD(NOP, 0);
GE_CMD(NOP, 0);
}
#endif
video_scale_type screen_scale = scaled_aspect;
video_scale_type current_scale = scaled_aspect;
video_filter_type screen_filter = filter_bilinear;
#ifdef PSP_BUILD
void video_resolution_large()
{
if(video_direct != 1)
{
video_direct = 1;
screen_pixels = psp_gu_vram_base;
screen_pitch = 512;
sceGuStart(GU_DIRECT, display_list);
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
(void*)0, PSP_LINE_SIZE);
sceGuFinish();
}
}
void set_gba_resolution(video_scale_type scale)
{
u32 filter_linear = 0;
screen_scale = scale;
switch(scale)
{
case unscaled:
screen_vertex[2] = 120 + 0.5;
screen_vertex[3] = 56 + 0.5;
screen_vertex[7] = GBA_SCREEN_WIDTH + 120 - 0.5;
screen_vertex[8] = GBA_SCREEN_HEIGHT + 56 - 0.5;
break;
case scaled_aspect:
screen_vertex[2] = 36 + 0.5;
screen_vertex[3] = 0 + 0.5;
screen_vertex[7] = 408 + 36 - 0.5;
screen_vertex[8] = PSP_SCREEN_HEIGHT - 0.5;
break;
case fullscreen:
screen_vertex[2] = 0;
screen_vertex[3] = 0;
screen_vertex[7] = PSP_SCREEN_WIDTH;
screen_vertex[8] = PSP_SCREEN_HEIGHT;
break;
}
sceGuStart(GU_DIRECT, display_list);
if(screen_filter == filter_bilinear)
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
else
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
sceGuFinish();
sceGuSync(0, 0);
clear_screen(0x0000);
}
void video_resolution_small()
{
if(video_direct != 0)
{
set_gba_resolution(screen_scale);
video_direct = 0;
screen_pixels = screen_texture;
screen_flip = 0;
screen_pitch = 240;
sceGuStart(GU_DIRECT, display_list);
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
(void*)0, PSP_LINE_SIZE);
sceGuFinish();
}
}
void clear_screen(u16 color)
{
u32 i;
u16 *src_ptr = get_screen_pixels();
sceGuSync(0, 0);
for(i = 0; i < (512 * 272); i++, src_ptr++)
{
*src_ptr = color;
}
// I don't know why this doesn't work.
/* color = (((color & 0x1F) * 255 / 31) << 0) |
((((color >> 5) & 0x3F) * 255 / 63) << 8) |
((((color >> 11) & 0x1F) * 255 / 31) << 16) | (0xFF << 24);
sceGuStart(GU_DIRECT, display_list);
sceGuDrawBuffer(GU_PSM_5650, (void*)0, PSP_LINE_SIZE);
//sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
// (void*)0, PSP_LINE_SIZE);
sceGuClearColor(color);
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuFinish();
sceGuSync(0, 0); */
}
#endif
u16 *copy_screen()
{
u16 *copy = malloc(240 * 160 * 2);
memcpy(copy, get_screen_pixels(), 240 * 160 * 2);
return copy;
}
void blit_to_screen(u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y)
{
u32 pitch = get_screen_pitch();
u16 *dest_ptr = get_screen_pixels() + dest_x + (dest_y * pitch);
s32 w1 = dest_x + w > pitch ? pitch - dest_x : w;
u16 *src_ptr = src;
s32 x, y;
for(y = 0; y < h; y++)
{
for(x = 0; x < w1; x++)
{
dest_ptr[x] = src_ptr[x];
}
src_ptr += w;
dest_ptr += pitch;
}
}
u32 debug_cursor_x = 0;
u32 debug_cursor_y = 0;
void debug_screen_clear()
{
}
void debug_screen_start()
{
}
void debug_screen_end()
{
}
void debug_screen_update()
{
}
void debug_screen_printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}
void debug_screen_newline(u32 count)
{
printf("\n");
}
void debug_screen_printl(const char *format, ...)
{
va_list ap;
va_start(ap, format);
debug_screen_printf(format, ap);
debug_screen_newline(1);
// debug_screen_printf("\n");
va_end(ap);
}
#define video_savestate_builder(type) \
void video_##type##_savestate(void) \

14
video.h
View File

@ -21,27 +21,13 @@
#define VIDEO_H
void update_scanline();
#ifndef __LIBRETRO__
void update_screen();
#endif
void init_video();
void video_resolution_large();
void video_resolution_small();
void clear_screen(u16 color);
void blit_to_screen(u16 *src, u32 w, u32 h, u32 x, u32 y);
u16 *copy_screen();
void flip_screen();
void video_write_savestate(void);
void video_read_savestate(void);
void debug_screen_clear();
void debug_screen_start();
void debug_screen_end();
void debug_screen_printf(const char *format, ...);
void debug_screen_printl(const char *format, ...);
void debug_screen_newline(u32 count);
void debug_screen_update();
extern u32 frame_speed;
extern u32 resolution_width, resolution_height;

View File

@ -30,8 +30,6 @@ void x86_indirect_branch_dual(u32 address);
void function_cc execute_store_cpsr(u32 new_cpsr, u32 store_mask);
void step_debug_x86(u32 pc);
typedef enum
{
x86_reg_number_eax,
@ -2320,8 +2318,4 @@ void function_cc swi_hle_div()
generate_update_pc(pc); \
generate_indirect_branch_no_cycle_update(type) \
#define generate_step_debug() \
generate_load_imm(a0, pc); \
generate_function_call(step_debug_x86) \
#endif

View File

@ -28,7 +28,6 @@
#define _execute_store_u32 execute_store_u32
#define _execute_store_cpsr execute_store_cpsr
#define _execute_arm_translate execute_arm_translate
#define _step_debug_x86 step_debug_x86
#define _memory_map_read memory_map_read
#define _memory_map_write memory_map_write
#define _reg reg
@ -41,7 +40,6 @@
#define _io_registers io_registers
#define _spsr spsr
#define _step_debug step_debug
#define _update_gba update_gba
#define _block_lookup_address_arm block_lookup_address_arm
#define _block_lookup_address_thumb block_lookup_address_thumb
@ -67,7 +65,6 @@
.global _execute_store_u32
.global _execute_store_cpsr
.global _execute_arm_translate
.global _step_debug_x86
.global _memory_map_read
.global _memory_map_write
@ -528,12 +525,6 @@ _execute_arm_translate:
call _block_lookup_address_thumb
jmp *%eax
_step_debug_x86:
collapse_flags
# mov $100, %edi
mov %edi, %edx
jmp _step_debug
.comm _memory_map_read 0x8000
.comm _memory_map_write 0x8000
.comm _reg 4