# HG changeset patch # User Michael Pavone # Date 1389077645 28800 # Node ID b7b7a1cab44ace84d3c3320563a209f9e06d3189 # Parent 7b0df1aaf3847194bb2f1a7c5926d14ae6c95210 The local clone on my laptop got messed up and some changes had not been pushed. This commit represents the status of the working copy from that clone. It unfortunately contains some changes that I did not intend to commit yet, but this seems like the best option at the moment. diff -r 7b0df1aaf384 -r b7b7a1cab44a Makefile --- a/Makefile Thu Oct 31 01:00:32 2013 -0700 +++ b/Makefile Mon Jan 06 22:54:05 2014 -0800 @@ -42,13 +42,13 @@ $(CC) -o trans trans.o $(M68KOBJS) $(TRANSOBJS) transz80 : transz80.o $(Z80OBJS) $(TRANSOBJS) - $(CC) -o transz80 $(Z80OBJS) $(TRANSOBJS) + $(CC) -o transz80 transz80.o $(Z80OBJS) $(TRANSOBJS) ztestrun : ztestrun.o $(Z80OBJS) $(TRANSOBJS) - $(CC) -o ztestrun $(Z80OBJS) $(TRANSOBJS) + $(CC) -o ztestrun ztestrun.o $(Z80OBJS) $(TRANSOBJS) ztestgen : ztestgen.o z80inst.o - $(CC) -o ztestgen ztestgen.o z80inst.o + $(CC) -ggdb -o ztestgen ztestgen.o z80inst.o stateview : stateview.o vdp.o render_sdl.o $(CONFIGOBJS) gst.o $(CC) -o stateview stateview.o vdp.o render_sdl.o $(CONFIGOBJS) gst.o $(LDFLAGS) diff -r 7b0df1aaf384 -r b7b7a1cab44a blastem.c --- a/blastem.c Thu Oct 31 01:00:32 2013 -0700 +++ b/blastem.c Mon Jan 06 22:54:05 2014 -0800 @@ -43,6 +43,7 @@ uint8_t z80_ram[Z80_RAM_BYTES]; int headless = 0; +int exit_after = 0; int z80_enabled = 1; int frame_limit = 0; @@ -186,20 +187,22 @@ { if (z80_enabled && !reset && !busreq) { genesis_context * gen = z_context->system; - if (need_reset) { - z80_reset(z_context); - need_reset = 0; - } z_context->sync_cycle = mclks / MCLKS_PER_Z80; - uint32_t vint_cycle = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80; - while (z_context->current_cycle < z_context->sync_cycle) { - if (z_context->iff1 && z_context->current_cycle < (vint_cycle + Z80_VINT_DURATION)) { - z_context->int_cycle = vint_cycle < z_context->int_enable_cycle ? z_context->int_enable_cycle : vint_cycle; + if (z_context->current_cycle < z_context->sync_cycle) { + if (need_reset) { + z80_reset(z_context); + need_reset = 0; } - z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; - dprintf("Running Z80 from cycle %d to cycle %d. Native PC: %p\n", z_context->current_cycle, z_context->sync_cycle, z_context->native_pc); - z80_run(z_context); - dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); + uint32_t vint_cycle = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80; + while (z_context->current_cycle < z_context->sync_cycle) { + if (z_context->iff1 && z_context->current_cycle < (vint_cycle + Z80_VINT_DURATION)) { + z_context->int_cycle = vint_cycle < z_context->int_enable_cycle ? z_context->int_enable_cycle : vint_cycle; + } + z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; + dprintf("Running Z80 from cycle %d to cycle %d. Native PC: %p\n", z_context->current_cycle, z_context->sync_cycle, z_context->native_pc); + z80_run(z_context); + dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); + } } } else { z_context->current_cycle = mclks / MCLKS_PER_Z80; @@ -243,6 +246,11 @@ if (!headless) { break_on_sync |= wait_render_frame(v_context, frame_limit); + } else if(exit_after){ + --exit_after; + if (!exit_after) { + exit(0); + } } frame++; mclks -= mclks_per_frame; @@ -315,6 +323,11 @@ if (!headless) { //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, v_context->cycles); wait_render_frame(v_context, frame_limit); + } else if(exit_after){ + --exit_after; + if (!exit_after) { + exit(0); + } } vdp_adjust_cycles(v_context, mclks_per_frame); genesis_context * gen = context->system; @@ -342,6 +355,11 @@ if (v_context->cycles >= mclks_per_frame) { if (!headless) { wait_render_frame(v_context, frame_limit); + } else if(exit_after){ + --exit_after; + if (!exit_after) { + exit(0); + } } vdp_adjust_cycles(v_context, mclks_per_frame); genesis_context * gen = context->system; @@ -570,7 +588,7 @@ if (reset) { need_reset = 1; //TODO: Add necessary delay between release of reset and start of execution - gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; + gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80 + 16; } reset = 0; } else { @@ -1779,6 +1797,15 @@ for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { + case 'b': + i++; + if (i >= argc) { + fputs("-b must be followed by a frame count\n", stderr); + return 1; + } + headless = 1; + exit_after = atoi(argv[i]); + break; case 'd': debug = 1; break; diff -r 7b0df1aaf384 -r b7b7a1cab44a blastem.h --- a/blastem.h Thu Oct 31 01:00:32 2013 -0700 +++ b/blastem.h Mon Jan 06 22:54:05 2014 -0800 @@ -37,6 +37,7 @@ } genesis_context; extern genesis_context * genesis; +extern int headless; extern int break_on_sync; extern int save_state; extern tern_node * config; diff -r 7b0df1aaf384 -r b7b7a1cab44a gdb_remote.c --- a/gdb_remote.c Thu Oct 31 01:00:32 2013 -0700 +++ b/gdb_remote.c Mon Jan 06 22:54:05 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "blastem.h" @@ -14,6 +14,7 @@ char * buf = NULL; char * curbuf = NULL; +char * end = NULL; size_t bufsize; int cont = 0; int expect_break_response=0; @@ -21,11 +22,54 @@ void gdb_debug_enter(genesis_context * gen, uint32_t pc) { + fcntl(STDIN_FILENO, FD_SETFL, 0); resume_pc = pc; + cont = 0; + uint8_t partial = 0; while(!cont) { + if (!curbuf) { + int numread = read(STDIN_FILENO, buf, bufsize); + curbuf = buf; + end = buf + numread; + } else if (partial) { + if (curbuf != buf) { + memmove(curbuf, buf, end-curbuf); + end -= cufbuf - buf; + } + int numread = read(STDIN_FILENO, end, bufsize - (end-buf)); + end += numread; + curbuf = buf; + } + for (; curbuf < end; curbuf++) + { + if (*curbuf == '$') + { + curbuf++; + char * start = curbuf; + while (curbuf < end && *curbuf != '#') { + curbuf++; + } + if (*curbuf == '#') { + //check to make sure we've received the checksum bytes + if (end-curbuf >= 2) { + //TODO: verify checksum + //Null terminate payload + *curbuf = 0 + //send acknowledgement + write(FILENO_STDOUT, "+", 1); + gdb_run_command(genesis_context * gen, start); + curbuf += 2; + } + } else { + curbuf--; + partial = 1; + break; + } + } + } } - cont = 0; + fcntl(STDIN_FILENO, FD_SETFL, O_NONBLOCK); } void gdb_run_command(genesis_context * gen, char * command) @@ -90,7 +134,7 @@ } } -void gdb_command_poll(genesis_context * gen) +int gdb_command_poll(genesis_context * gen) { for(;;) { @@ -104,10 +148,10 @@ } curbuf = buf + bufsize/2; } - int numread = read(STDIN_FILENO, buf, bufsize - (curbuf-buf)); + int numread = read(STDIN_FILENO, buf, bufsize); if (numread < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { - return; + return 0; } else { fprintf(stderr, "Error %d while reading GDB commands from stdin", errno); exit(1); @@ -115,8 +159,16 @@ } else if (numread == 0) { exit(0); } - gdb_run_commands(genesis_context * gen); + for (curbuf = buf, end = buf+numread; curbuf < end; curbuf++) + { + if (*curbuf = 0x03) + { + curbuf++; + return 1; + } + } } + return 0; } void gdb_remote_init() diff -r 7b0df1aaf384 -r b7b7a1cab44a psg.c --- a/psg.c Thu Oct 31 01:00:32 2013 -0700 +++ b/psg.c Mon Jan 06 22:54:05 2014 -0800 @@ -5,6 +5,7 @@ */ #include "psg.h" #include "render.h" +#include "blastem.h" #include #include @@ -118,7 +119,9 @@ } context->audio_buffer[context->buffer_pos++] = acc; if (context->buffer_pos == context->samples_frame) { - render_wait_psg(context); + if (!headless) { + render_wait_psg(context); + } } } context->cycles += context->clock_inc; diff -r 7b0df1aaf384 -r b7b7a1cab44a render_sdl.c --- a/render_sdl.c Thu Oct 31 01:00:32 2013 -0700 +++ b/render_sdl.c Mon Jan 06 22:54:05 2014 -0800 @@ -18,7 +18,7 @@ SDL_Surface *screen; uint8_t render_dbg = 0; uint8_t debug_pal = 0; -uint8_t render_gl; +uint8_t render_gl = 1; uint32_t last_frame = 0; @@ -100,7 +100,7 @@ } #ifndef DISABLE_OPENGL -GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], at_pos; +GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, at_pos; GLfloat vertex_data[] = { -1.0f, -1.0f, @@ -196,6 +196,7 @@ } un_textures[0] = glGetUniformLocation(program, "textures[0]"); un_textures[1] = glGetUniformLocation(program, "textures[1]"); + un_width = glGetUniformLocation(program, "width"); at_pos = glGetAttribLocation(program, "pos"); } else { #endif @@ -363,6 +364,8 @@ glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); glUniform1i(un_textures[1], 1); + glUniform1f(un_width, context->latched_mode & BIT_H40 ? 320.0f : 256.0f); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); glEnableVertexAttribArray(at_pos); diff -r 7b0df1aaf384 -r b7b7a1cab44a shaders/default.v.glsl --- a/shaders/default.v.glsl Thu Oct 31 01:00:32 2013 -0700 +++ b/shaders/default.v.glsl Mon Jan 06 22:54:05 2014 -0800 @@ -2,9 +2,10 @@ attribute vec2 pos; varying vec2 texcoord; +uniform float width; void main() { gl_Position = vec4(pos, 0.0, 1.0); - texcoord = sign(pos) * vec2(320.0/1024.0, 240.0/-512.0) + vec2(320.0/1024.0, 240.0/512.0); + texcoord = sign(pos) * vec2(width/1024.0, 240.0/-512.0) + vec2(width/1024.0, 240.0/512.0); } diff -r 7b0df1aaf384 -r b7b7a1cab44a transz80.c --- a/transz80.c Thu Oct 31 01:00:32 2013 -0700 +++ b/transz80.c Mon Jan 06 22:54:05 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "z80inst.h" @@ -29,6 +29,11 @@ return context; } +z80_context * z80_vdp_port_write(uint16_t location, z80_context * context, uint8_t value) +{ + return context; +} + int main(int argc, char ** argv) { long filesize; diff -r 7b0df1aaf384 -r b7b7a1cab44a vdp.c --- a/vdp.c Thu Oct 31 01:00:32 2013 -0700 +++ b/vdp.c Mon Jan 06 22:54:05 2014 -0800 @@ -50,12 +50,18 @@ memset(context, 0, sizeof(*context)); context->vdpmem = malloc(VRAM_SIZE); memset(context->vdpmem, 0, VRAM_SIZE); - /*context->oddbuf = context->framebuf = malloc(FRAMEBUF_ENTRIES * (render_depth() / 8)); - memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (render_depth() / 8)); - context->evenbuf = malloc(FRAMEBUF_ENTRIES * (render_depth() / 8)); - memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (render_depth() / 8)); + /* */ - render_alloc_surfaces(context); + if (headless) { + context->oddbuf = context->framebuf = malloc(FRAMEBUF_ENTRIES * (32 / 8)); + memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); + context->evenbuf = malloc(FRAMEBUF_ENTRIES * (32 / 8)); + memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); + context->b32 = 1; + } else { + render_alloc_surfaces(context); + context->b32 = render_depth() == 32; + } context->framebuf = context->oddbuf; context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); @@ -64,7 +70,7 @@ context->sprite_draws = MAX_DRAWS; context->fifo_write = 0; context->fifo_read = -1; - context->b32 = render_depth() == 32; + if (!color_map_init_done) { uint8_t b,g,r; for (uint16_t color = 0; color < (1 << 12); color++) { @@ -229,7 +235,7 @@ "0A: %.2X | H-Int Counter: %u\n" "0F: %.2X | Auto-increment: $%X\n" "10: %.2X | Scroll A/B Size: %sx%s\n", - context->regs[REG_BG_COLOR], context->regs[REG_BG_COLOR] & 0x3F, + context->regs[REG_BG_COLOR], context->regs[REG_BG_COLOR], context->regs[REG_HINT], context->regs[REG_HINT], context->regs[REG_AUTOINC], context->regs[REG_AUTOINC], context->regs[REG_SCROLL], sizes[context->regs[REG_SCROLL] & 0x3], sizes[context->regs[REG_SCROLL] >> 4 & 0x3]); @@ -749,65 +755,36 @@ plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK); uint32_t * colors = context->colors; src = 0; - uint8_t sprite_color = *sprite_buf & 0x3F; - if (sprite_color == 0x3E || sprite_color == 0x3F) { - if (sprite_color == 0x3F) { - colors += CRAM_SIZE; - src = DBG_SHADOW; - } else { + pixel = context->regs[REG_BG_COLOR]; + src = DBG_SRC_BG; + if (*plane_b & 0xF) { + pixel = *plane_b; + src = DBG_SRC_B; + } + if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { + pixel = *plane_a; + src = DBG_SRC_A; + } + if (*sprite_buf & 0xF) { + uint8_t sprite_color = *sprite_buf & 0x3F; + if (sprite_color == 0x3E) { colors += CRAM_SIZE*2; - src = DBG_HILIGHT; - } - if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { - pixel = *plane_a; - src |= a_src; - } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { - pixel = *plane_b; - src |= DBG_SRC_B; - } else if (*plane_a & 0xF) { - pixel = *plane_a; - src |= a_src; - } else if (*plane_b & 0xF){ - pixel = *plane_b; - src |= DBG_SRC_B; - } else { - pixel = context->regs[REG_BG_COLOR] & 0x3F; - src |= DBG_SRC_BG; - } - } else { - if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) { + src |= DBG_HILIGHT; + } else if (sprite_color == 0x3F) { + colors += CRAM_SIZE; + src |= DBG_SHADOW; + } else if ((*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { pixel = *sprite_buf; src = DBG_SRC_S; - } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { - pixel = *plane_a; - src = a_src; - } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { - pixel = *plane_b; - src = DBG_SRC_B; - } else { - if (!(*plane_a & BUF_BIT_PRIORITY || *plane_a & BUF_BIT_PRIORITY)) { + if ((pixel & 0xF) == 0xE) { + src |= DBG_SHADOW; colors += CRAM_SIZE; - src = DBG_SHADOW; } - if (*sprite_buf & 0xF) { - pixel = *sprite_buf; - if (*sprite_buf & 0xF == 0xE) { - colors = context->colors; - src = DBG_SRC_S; - } else { - src |= DBG_SRC_S; - } - } else if (*plane_a & 0xF) { - pixel = *plane_a; - src |= a_src; - } else if (*plane_b & 0xF){ - pixel = *plane_b; - src |= DBG_SRC_B; - } else { - pixel = context->regs[REG_BG_COLOR] & 0x3F; - src |= DBG_SRC_BG; - } + } + } else if (!((*plane_a | *plane_b) & BUF_BIT_PRIORITY)) { + colors += CRAM_SIZE; + src |= DBG_SHADOW; } pixel &= 0x3F; uint32_t outpixel; @@ -825,31 +802,21 @@ } } else { for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) { - uint8_t pixel; - src = 0; plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK); plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK); - if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) { - pixel = *sprite_buf; - src = DBG_SRC_S; - } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { - pixel = *plane_a; - src = a_src; - } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { + uint8_t pixel = context->regs[REG_BG_COLOR]; + src = DBG_SRC_BG; + if (*plane_b & 0xF) { pixel = *plane_b; src = DBG_SRC_B; - } else if (*sprite_buf & 0xF) { + } + if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { + pixel = *plane_a; + src = DBG_SRC_A; + } + if (*sprite_buf & 0xF && (*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { pixel = *sprite_buf; src = DBG_SRC_S; - } else if (*plane_a & 0xF) { - pixel = *plane_a; - src = a_src; - } else if (*plane_b & 0xF){ - pixel = *plane_b; - src = DBG_SRC_B; - } else { - pixel = context->regs[REG_BG_COLOR] & 0x3F; - src = DBG_SRC_BG; } uint32_t outpixel; if (context->debug) { @@ -862,15 +829,8 @@ } else { *(dst++) = outpixel; } - //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src; } } - } else { - //dst = context->framebuf + line * 320; - //sprite_buf = context->linebuf + col * 8; - //plane_a = context->tmp_buf_a + 16 - (context->hscroll_a & 0x7); - //plane_b = context->tmp_buf_b + 16 - (context->hscroll_b & 0x7); - //end = dst + 8; } context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; @@ -1243,12 +1203,55 @@ if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, 0); } - } else { - render_sprite_cells(context); - render_sprite_cells(context); - render_sprite_cells(context); - render_sprite_cells(context); + for (int i = 0; i < 19; i++) + { + scan_sprite_table(line, context); + } + external_slot(context); + for (int i = 0; i < 21; i++) + { + scan_sprite_table(line, context); + } + //reverse context slot counter so it counts the number of sprite slots + //filled rather than the number of available slots + //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; + context->cur_slot = MAX_SPRITES_LINE-1; + context->sprite_draws = MAX_DRAWS; + context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); + for (int column = 2; column < 42; column += 8) + { + external_slot(context); + if (context->flags & FLAG_DMA_RUN) { + run_dma_src(context, 0); + } + read_sprite_x(line, context); + + external_slot(context); + if (context->flags & FLAG_DMA_RUN) { + run_dma_src(context, 0); + } + read_sprite_x(line, context); + + external_slot(context); + if (context->flags & FLAG_DMA_RUN) { + run_dma_src(context, 0); + } + read_sprite_x(line, context); + + read_sprite_x(line, context); + } + external_slot(context); + if (context->flags & FLAG_DMA_RUN) { + run_dma_src(context, 0); + } + external_slot(context); + return; } + + render_sprite_cells(context); + render_sprite_cells(context); + render_sprite_cells(context); + render_sprite_cells(context); context->sprite_index = 0x80; context->slot_counter = MAX_SPRITES_LINE; for (int i = 0; i < 19; i++) @@ -1284,8 +1287,6 @@ render_sprite_cells(context); scan_sprite_table(line, context); - render_sprite_cells(context); - scan_sprite_table(line, context); read_map_scroll_a(0, line, context); render_sprite_cells(context); scan_sprite_table(line, context); @@ -1391,14 +1392,14 @@ } if (starti >= 0) { if (context->b32) { - uint32_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; + uint32_t color = context->colors[context->regs[REG_BG_COLOR]]; uint32_t * start = context->framebuf; start += starti; for (int i = 0; i < 2; i++) { *(start++) = color; } } else { - uint16_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; + uint16_t color = context->colors[context->regs[REG_BG_COLOR]]; uint16_t * start = context->framebuf; start += starti; for (int i = 0; i < 2; i++) { @@ -1625,6 +1626,9 @@ if (reg == REG_MODE_1 && (value & BIT_HVC_LATCH) && !(context->regs[reg] & BIT_HVC_LATCH)) { context->hv_latch = vdp_hv_counter_read(context); } + if (reg == REG_BG_COLOR) { + value &= 0x3F; + } context->regs[reg] = value; if (reg == REG_MODE_4) { context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); diff -r 7b0df1aaf384 -r b7b7a1cab44a vgmplay.c --- a/vgmplay.c Thu Oct 31 01:00:32 2013 -0700 +++ b/vgmplay.c Mon Jan 06 22:54:05 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "render.h" @@ -90,6 +90,8 @@ { } +uint8_t headless = 0; + #define CYCLE_LIMIT MCLKS_NTSC/60 tern_node * config; @@ -111,7 +113,7 @@ { uint32_t fps = 60; config = load_config(argv[0]); - render_init(320, 240, "vgm play", 60, 0); + render_init(320, 240, "vgm play", 60, 0, 0); ym2612_context y_context; diff -r 7b0df1aaf384 -r b7b7a1cab44a ym2612.c --- a/ym2612.c Thu Oct 31 01:00:32 2013 -0700 +++ b/ym2612.c Mon Jan 06 22:54:05 2014 -0800 @@ -10,6 +10,7 @@ #include "ym2612.h" #include "render.h" #include "wave.h" +#include "blastem.h" //#define DO_DEBUG_PRINT #ifdef DO_DEBUG_PRINT @@ -482,7 +483,9 @@ } context->buffer_pos += 2; if (context->buffer_pos == context->sample_limit) { - render_wait_ym(context); + if (!headless) { + render_wait_ym(context); + } } } } diff -r 7b0df1aaf384 -r b7b7a1cab44a z80_to_x86.c --- a/z80_to_x86.c Thu Oct 31 01:00:32 2013 -0700 +++ b/z80_to_x86.c Mon Jan 06 22:54:05 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "z80inst.h" @@ -309,19 +309,19 @@ void z80_print_regs_exit(z80_context * context) { - printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\nSP: %X\n\nIM: %d, IFF1: %d, IFF2: %d\n", + printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\nSP: %X\n\nIM: %d, IFF1: %d, IFF2: %d\n", context->regs[Z80_A], context->regs[Z80_B], context->regs[Z80_C], - context->regs[Z80_D], context->regs[Z80_E], - (context->regs[Z80_H] << 8) | context->regs[Z80_L], - (context->regs[Z80_IXH] << 8) | context->regs[Z80_IXL], - (context->regs[Z80_IYH] << 8) | context->regs[Z80_IYL], + context->regs[Z80_D], context->regs[Z80_E], + (context->regs[Z80_H] << 8) | context->regs[Z80_L], + (context->regs[Z80_IXH] << 8) | context->regs[Z80_IXL], + (context->regs[Z80_IYH] << 8) | context->regs[Z80_IYL], context->sp, context->im, context->iff1, context->iff2); puts("--Alternate Regs--"); - printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\n", + printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\n", context->alt_regs[Z80_A], context->alt_regs[Z80_B], context->alt_regs[Z80_C], - context->alt_regs[Z80_D], context->alt_regs[Z80_E], - (context->alt_regs[Z80_H] << 8) | context->alt_regs[Z80_L], - (context->alt_regs[Z80_IXH] << 8) | context->alt_regs[Z80_IXL], + context->alt_regs[Z80_D], context->alt_regs[Z80_E], + (context->alt_regs[Z80_H] << 8) | context->alt_regs[Z80_L], + (context->alt_regs[Z80_IXH] << 8) | context->alt_regs[Z80_IXL], (context->alt_regs[Z80_IYH] << 8) | context->alt_regs[Z80_IYL]); exit(0); } @@ -363,8 +363,8 @@ } dst = zcycles(dst, cycles); if (inst->addr_mode & Z80_DIR) { + dst = translate_z80_ea(inst, &dst_op, dst, opts, DONT_READ, MODIFY); dst = translate_z80_reg(inst, &src_op, dst, opts); - dst = translate_z80_ea(inst, &dst_op, dst, opts, DONT_READ, MODIFY); } else { dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); dst = translate_z80_reg(inst, &dst_op, dst, opts); @@ -418,7 +418,7 @@ dst = call(dst, (uint8_t *)z80_read_word); dst = add_ir(dst, 2, opts->regs[Z80_SP], SZ_W); if (inst->reg == Z80_AF) { - + dst = bt_ir(dst, 0, SCRATCH1, SZ_W); dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); dst = bt_ir(dst, 1, SCRATCH1, SZ_W); @@ -452,7 +452,7 @@ dst = mov_rr(dst, opts->regs[Z80_A], SCRATCH1, SZ_B); dst = mov_rdisp8r(dst, CONTEXT, zar_off(Z80_A), opts->regs[Z80_A], SZ_B); dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, zar_off(Z80_A), SZ_B); - + //Flags are currently word aligned, so we can move //them efficiently a word at a time for (int f = ZF_C; f < ZF_NUM; f+=2) { @@ -525,7 +525,7 @@ dst = call(dst, (uint8_t *)z80_write_byte); dst = add_ir(dst, 1, opts->regs[Z80_DE], SZ_W); dst = add_ir(dst, 1, opts->regs[Z80_HL], SZ_W); - + dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W); uint8_t * cont = dst+1; dst = jcc(dst, CC_Z, dst+2); @@ -563,7 +563,7 @@ dst = call(dst, (uint8_t *)z80_write_byte); dst = sub_ir(dst, 1, opts->regs[Z80_DE], SZ_W); dst = sub_ir(dst, 1, opts->regs[Z80_HL], SZ_W); - + dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W); uint8_t * cont = dst+1; dst = jcc(dst, CC_Z, dst+2); @@ -1162,7 +1162,7 @@ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); - + dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); dst = ror_ir(dst, 8, SCRATCH1, SZ_W); dst = call(dst, (uint8_t *)z80_write_byte); @@ -1192,7 +1192,7 @@ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); - + dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); dst = ror_ir(dst, 8, SCRATCH1, SZ_W); dst = call(dst, (uint8_t *)z80_write_byte); @@ -1255,7 +1255,7 @@ dst = ror_ir(dst, 8, src_op.base, SZ_W); } else { dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); - } + } } else { dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); } @@ -1297,7 +1297,7 @@ dst = ror_ir(dst, 8, src_op.base, SZ_W); } else { dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); - } + } } else { dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); } @@ -1848,6 +1848,7 @@ return; } x86_z80_options * opts = context->options; + uint32_t start_address = address; uint8_t * encoded = NULL, *next; if (address < 0x4000) { encoded = context->mem_pointers[0] + (address & 0x1FFF); @@ -1896,7 +1897,7 @@ address += next-encoded; if (address > 0xFFFF) { address &= 0xFFFF; - + } else { encoded = next; } @@ -1987,12 +1988,12 @@ } bp_stub = dst; native = call(native, bp_stub); - + //Calculate length of prologue dst = z80_check_cycles_int(dst, address); int check_int_size = dst-bp_stub; dst = bp_stub; - + //Save context and call breakpoint handler dst = call(dst, (uint8_t *)z80_save_context); dst = push_r(dst, SCRATCH1); diff -r 7b0df1aaf384 -r b7b7a1cab44a ztestgen.c --- a/ztestgen.c Thu Oct 31 01:00:32 2013 -0700 +++ b/ztestgen.c Mon Jan 06 22:54:05 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "z80inst.h" @@ -158,7 +158,7 @@ { memcpy(©, inst, sizeof(copy)); inst = © - if ((inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) + if ((inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) || (addr_mode == Z80_IMMED && inst->op != Z80_IM)) { copy.immed = rand() % (word_sized ? 65536 : 256); @@ -236,7 +236,7 @@ break; } if (inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { - reg_usage[inst->reg] = 1; + if (word_sized) { reg_values[inst->reg] = rand() % 65536; reg_usage[z80_high_reg(inst->reg)] = 1; @@ -244,13 +244,16 @@ reg_usage[z80_low_reg(inst->reg)] = 1; reg_values[z80_low_reg(inst->reg)] = reg_values[inst->reg] & 0xFF; } else { - reg_values[inst->reg] = rand() % 255; - uint8_t word_reg = z80_word_reg(inst->reg); - if (word_reg != Z80_UNUSED) { - reg_usage[word_reg] = 1; - reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); + if (!reg_usage[inst->reg]) { + reg_values[inst->reg] = rand() % 255; + uint8_t word_reg = z80_word_reg(inst->reg); + if (word_reg != Z80_UNUSED) { + reg_usage[word_reg] = 1; + reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); + } } } + reg_usage[inst->reg] = 1; } puts("--------------"); for (uint8_t reg = 0; reg < Z80_UNUSED; reg++) { @@ -287,14 +290,14 @@ cur = ld_ir16(cur, Z80_BC, reg_values[Z80_A] << 8 | (i ? 0xFF : 0)); cur = push(cur, Z80_BC); cur = pop(cur, Z80_AF); - + //setup other regs for (uint8_t reg = Z80_BC; reg <= Z80_IY; reg++) { if (reg != Z80_AF && reg != Z80_SP) { cur = ld_ir16(cur, reg, reg_values[reg]); } } - + //copy instruction if (instlen == 3) { memcpy(cur, instbuf, 2); @@ -303,7 +306,7 @@ memcpy(cur, instbuf, instlen); cur += instlen; } - + //immed/displacement byte(s) if (addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) { *(cur++) = inst->ea_reg; @@ -325,6 +328,11 @@ if (!i) { //Save AF from first run cur = push(cur, Z80_AF); + if (is_mem) { + //Save memory location from frist run + cur = ld_mema(cur, address); + cur = push(cur, Z80_AF); + } } else { //Pop AF from first run for final result for (int reg = Z80_BC; reg <= Z80_IY; reg++) { @@ -340,6 +348,21 @@ break; } } + if (is_mem) { + //Pop memory location from frist run + for (int reg = Z80_BC; reg <= Z80_IY; reg++) { + if (reg != Z80_AF && !reg_usage[reg]) { + cur = pop(cur, reg); + cur = push(cur, Z80_AF); + cur = ld_mema(cur, address); + cur = ld_rr8(cur, Z80_A, z80_low_reg(reg)); + cur = pop(cur, Z80_AF); + reg_usage[reg] = 1; + reg_usage[z80_low_reg(reg)] = 1; + break; + } + } + } } } @@ -364,7 +387,7 @@ cur = pop(cur, Z80_AF); } } - + //halt *(cur++) = 0x76; sprintf(pathbuf + strlen(pathbuf), "/%s.bin", disbuf); @@ -376,7 +399,7 @@ uint8_t should_skip(z80inst * inst) { - return inst->op >= Z80_JP || (inst->op >= Z80_LDI && inst->op <= Z80_CPDR) || inst->op == Z80_HALT + return inst->op >= Z80_JP || (inst->op >= Z80_LDI && inst->op <= Z80_CPDR) || inst->op == Z80_HALT || inst->op == Z80_DAA || inst->op == Z80_RLD || inst->op == Z80_RRD || inst->op == Z80_NOP || inst->op == Z80_DI || inst->op == Z80_EI; }