ys2-intro/loader/tools/exomizer-3.1/exodecrs/testrun.c
2025-11-13 19:07:39 +03:00

197 lines
4.7 KiB
C

/*
* Copyright (c) 2002 - 2018 Magnus Lind.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software, alter it and re-
* distribute it freely for any non-commercial, non-profit purpose subject to
* the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in a
* product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any distribution.
*
* 4. The names of this software and/or it's copyright holders may not be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
*/
#include "../src/log.h"
#include "../src/exo_util.h"
#include "../src/6502emu.h"
#include "../src/areatrace.h"
#include "../src/int.h"
#include "../src/buf_io.h"
#include "../src/perf.h"
#include <stdlib.h>
struct mem_ctx
{
u8 *mem;
struct areatrace at;
};
static void mem_access_write(struct mem_access *this, u16 address, u8 value)
{
struct mem_ctx *ctx = this->ctx;
ctx->mem[address] = value;
areatrace_access(&ctx->at, address);
}
static u8 mem_access_read(struct mem_access *this, u16 address)
{
struct mem_ctx *ctx = this->ctx;
return ctx->mem[address];
}
void save_single(const char *in_name, struct buf *mem, int start, int end)
{
struct buf mb_name;
const char *out_name;
buf_init(&mb_name);
buf_printf(&mb_name, "%s.out", in_name);
out_name = (const char *)buf_data(&mb_name);
buf_remove(mem, end, -1);
buf_remove(mem, 0, start);
write_file(out_name, mem);
buf_free(&mb_name);
}
void test_single(const char *prg_name, const char *data_name,
int *cyclesp, int *in_lenp, int *out_lenp)
{
struct cpu_ctx r;
struct load_info prg_info;
struct load_info data_info;
struct buf mem_mb;
u8 *mem;
struct mem_ctx mem_ctx;
int start;
int end;
buf_init(&mem_mb);
buf_append(&mem_mb, NULL, 65536);
mem = buf_data(&mem_mb);
memset(mem, 0, 65536);
mem_ctx.mem = mem;
areatrace_init(&mem_ctx.at);
prg_info.basic_txt_start = 0x0801;
data_info.basic_txt_start = 0x0801;
load_located(prg_name, mem, &prg_info);
/* no start address from load*/
if(prg_info.run == -1)
{
/* look for sys line */
prg_info.run = find_sys(mem + prg_info.basic_txt_start, 0x9e, NULL);
}
if(prg_info.run == -1)
{
LOG(LOG_ERROR, ("Error, can't find entry point.\n"));
exit(-1);
}
LOG(LOG_DEBUG, ("run %04x\n", prg_info.run));
load_located(data_name, mem, &data_info);
/* communicate the data region to the prg */
mem[2] = data_info.start & 255;
mem[3] = data_info.start >> 8;
mem[4] = data_info.end & 255;
mem[5] = data_info.end >> 8;
r.cycles = 0;
r.mem.ctx = &mem_ctx;
r.mem.read = mem_access_read;
r.mem.write = mem_access_write;
r.pc = prg_info.run;
r.sp = '\xff';
r.flags = 0;
/* setting up decrunch */
while(r.sp >= 0x10)
{
next_inst(&r);
}
/* save traced area */
areatrace_merge_overlapping(&mem_ctx.at);
areatrace_get_largest(&mem_ctx.at, &start, &end);
save_single(data_name, &mem_mb, start, end);
areatrace_free(&mem_ctx.at);
buf_free(&mem_mb);
if (cyclesp != NULL)
{
*cyclesp = r.cycles;
}
if (in_lenp != NULL)
{
*in_lenp = data_info.end - data_info.start;
}
if (out_lenp != NULL)
{
*out_lenp = end - start;
}
}
int main(int argc, char *argv[])
{
struct perf_ctx perf;
struct buf buf;
int i;
int cycles;
int inlen;
int outlen;
int cycles_sum = 0;
int inlen_sum = 0;
int outlen_sum = 0;
/* init logging */
LOG_INIT_CONSOLE(LOG_TERSE);
perf_init(&perf);
for (i = 1; i < argc; i += 2)
{
test_single(argv[i], argv[i + 1], &cycles, &inlen, &outlen);
perf_add(&perf, argv[i + 1], inlen, outlen, cycles);
cycles_sum += cycles;
inlen_sum += inlen;
outlen_sum += outlen;
}
if (argc > 3)
{
perf_add(&perf, "Total", inlen_sum, outlen_sum, cycles_sum);
}
buf_init(&buf);
perf_buf_print(&perf, &buf);
LOG(LOG_TERSE, ("%s", (char*)buf_data(&buf)));
buf_free(&buf);
perf_free(&perf);
return 0;
}