view zdis.c @ 380:1c8d74f2ab0b

Make the PSG and YM2612 use the master clock internal with an increment based on clock divider so that they stay perflectly in sync. Run both the PSG and YM2612 whenver one of them needs to be run.
author Mike Pavone <pavone@retrodev.com>
date Mon, 03 Jun 2013 21:43:38 -0700
parents 54c0e5f22198
children 140af5509ce7
line wrap: on
line source

#include "z80inst.h"
#include <stdio.h>
#include <stdlib.h>

uint8_t visited[(64*1024)/8];
uint8_t label[(64*1024)/8];

void visit(uint16_t address)
{
	visited[address/8] |= 1 << (address % 8);
}

void reference(uint16_t address)
{
	//printf("referenced: %X\n", address);
	label[address/8] |= 1 << (address % 8);
}

uint8_t is_visited(uint16_t address)
{
	return visited[address/8] & (1 << (address % 8));
}

uint8_t is_label(uint16_t address)
{
	return label[address/8] & (1 << (address % 8));
}

typedef struct deferred {
	uint16_t address;
	struct deferred *next;
} deferred;

deferred * defer(uint16_t address, deferred * next)
{
	if (is_visited(address)) {
		return next;
	}
	//printf("deferring %X\n", address);
	deferred * d = malloc(sizeof(deferred));
	d->address = address;
	d->next = next;
	return d;
}

uint8_t labels = 0;
uint8_t addr = 0;
uint8_t only = 0;

int main(int argc, char ** argv)
{
	long filesize;
	uint8_t *filebuf;
	char disbuf[1024];
	z80inst instbuf;
	uint8_t * cur;
	FILE * f = fopen(argv[1], "rb");
	fseek(f, 0, SEEK_END);
	filesize = ftell(f);
	fseek(f, 0, SEEK_SET);
	filebuf = malloc(filesize);
	fread(filebuf, 1, filesize, f);
	fclose(f);
	deferred *def = NULL, *tmpd;
	for(uint8_t opt = 2; opt < argc; ++opt) {
		if (argv[opt][0] == '-') {
			FILE * address_log;
			switch (argv[opt][1])
			{
			case 'l':
				labels = 1;
				break;
			case 'a':
				addr = 1;
				break;
			case 'o':
				only = 1;
				break;
			case 'f':
				opt++;
				if (opt >= argc) {
					fputs("-f must be followed by a filename\n", stderr);
					exit(1);
				}
				address_log = fopen(argv[opt], "r");
				if (!address_log) {
					fprintf(stderr, "Failed to open %s for reading\n", argv[opt]);
					exit(1);
				}
				while (fgets(disbuf, sizeof(disbuf), address_log)) {
				 	if (disbuf[0]) {
						uint16_t address = strtol(disbuf, NULL, 16);
						if (address) {
							def = defer(address, def);
							reference(address);
						}
					}
				}
			}
		} else {
			uint16_t address = strtol(argv[opt], NULL, 16);
			def = defer(address, def);
			reference(address);
		}
	}
	uint16_t start = 0;
	uint8_t *encoded, *next;
	uint32_t size;
	if (!def || !only) {
		def = defer(start, def);
	}
	uint16_t address;
	while(def) {
		do {
			encoded = NULL;
			address = def->address;
			if (!is_visited(address)) {
				encoded = filebuf + address;
			}
			tmpd = def;
			def = def->next;
			free(tmpd);
		} while(def && encoded == NULL);
		if (!encoded) {
			break;
		}
		for(;;) {
			if (address > filesize || is_visited(address)) {
				break;
			}
			visit(address);
			next = z80_decode(encoded, &instbuf);
			address += (next-encoded);
			encoded = next;
			
			//z80_disasm(&instbuf, disbuf);
			//printf("%X: %s\n", address, disbuf);
			switch (instbuf.op)
			{
			case Z80_JR:
				address += instbuf.immed;
				encoded = filebuf + address;
				break;
			case Z80_JRCC:
				reference(address + instbuf.immed);
				def = defer(address + instbuf.immed, def);
				break;
			case Z80_JP:
				address = instbuf.immed;
				encoded = filebuf + address;
				break;
			case Z80_JPCC:
			case Z80_CALL:
			case Z80_CALLCC:
			case Z80_RST:
				reference(instbuf.immed);
				def = defer(instbuf.immed, def);
				break;
			default:
				if (z80_is_terminal(&instbuf)) {
					address = filesize + 1;
				}
			}
		}
	}
	if (labels) {
		for (address = filesize; address < (64*1024); address++) {
			if (is_label(address)) {
				printf("ADR_%X equ $%X\n", address, address);
			}
		}
		puts("");
	}
	for (address = 0; address < filesize; address++) {
		if (is_visited(address)) {
			encoded = filebuf + address;
			z80_decode(encoded, &instbuf);
			if (labels) {
				/*m68k_disasm_labels(&instbuf, disbuf);
				if (is_label(instbuf.address)) {
					printf("ADR_%X:\n", instbuf.address);
				}
				if (addr) {
					printf("\t%s\t;%X\n", disbuf, instbuf.address);
				} else {
					printf("\t%s\n", disbuf);
				}*/
			} else {
				z80_disasm(&instbuf, disbuf, address);
				printf("%X: %s\n", address, disbuf);
			}
		}
	}
	return 0;
}