various improvements

This commit is contained in:
Steven Hugg 2017-04-11 22:46:06 -04:00
parent 90ec9ba94d
commit 1e6a43b273
9 changed files with 119 additions and 28 deletions

View File

@ -206,8 +206,8 @@ div.bitmap_editor {
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<!--<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>-->
<li><a class="dropdown-item" href="?platform=vicdual" id="item_platform_vicdual">VIC Dual</a></li>
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080 B&amp;W</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble" id="item_platform_galaxian_scramble">Scramble hardware</a></li>
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble" id="item_platform_galaxian_scramble">Scramble Hardware</a></li>
<li><a class="dropdown-item" href="?platform=vector-z80color" id="item_platform_vector_z80color">Atari Color Vector (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=williams-z80" id="item_platform_williams_z80">Williams (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=sound_williams-z80" id="item_platform_sound_williams_z80">Williams Sound (Z80)</a></li>

View File

@ -92,11 +92,22 @@ word rand() {
return lfsr;
}
void wait_for_vsync() {
while (VSYNC != 0) lfsr++; // wait for VSYNC end
while (VSYNC == 0) lfsr++; // wait for VSYNC start
void delay(byte msec) {
while (msec--) {
while (TIMER500HZ != 0) lfsr++;
while (TIMER500HZ == 0) lfsr++;
}
}
#define PE(fg,bg) (((fg)<<5) | ((bg)<<1))
const byte __at (0x4000) color_prom[32] = {
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
};
#define LOCHAR 0x0
#define HICHAR 0xff

View File

@ -626,6 +626,9 @@ var BaseZ80Platform = function() {
onBreakpointHit(debugBreakState);
}
}
this.wasBreakpointHit = function() {
return debugBreakState != null;
}
// TODO: lower bound of clock value
this.step = function() {
var self = this;

View File

@ -2,7 +2,7 @@
var GALAXIAN_PRESETS = [
{id:'gfxtest.c', name:'Graphics Test'},
{id:'shoot2.c', name:'Shoot-em-up Game'},
{id:'shoot2.c', name:'Solarian Game'},
];
var GALAXIAN_KEYCODE_MAP = makeKeycodeMap([

View File

@ -5,9 +5,9 @@ var VICDUAL_PRESETS = [
{id:'hello.c', name:'Hello World'},
{id:'gfxtest.c', name:'Graphics Test'},
{id:'soundtest.c', name:'Sound Test'},
{id:'snake1.c', name:'Snake Game (Prototype)'},
{id:'snake2.c', name:'Snake Game (Full)'},
{id:'music.c', name:'Music Example'},
{id:'snake1.c', name:'Siege Game (Prototype)'},
{id:'snake2.c', name:'Siege Game (Full)'},
{id:'music.c', name:'Music Player'},
];
var VicDualPlatform = function(mainElement) {

View File

@ -310,7 +310,8 @@ var WilliamsPlatform = function(mainElement, proto) {
if (cpu.requestInterrupt)
cpu.requestInterrupt();
}
self.runCPU(cpu, cpuCyclesPerFrame/4);
if (!self.wasBreakpointHit())
self.runCPU(cpu, cpuCyclesPerFrame/4);
video.updateFrame(0, 0, quarter*64, 0, 64, 304);
}
if (screenNeedsRefresh) {

View File

@ -84,12 +84,67 @@ function loadFilesystem(name) {
console.log("Loaded "+name+" filesystem", fsMeta[name].files.length, 'files', fsBlob[name].size, 'bytes');
}
var ATARI_CFG =
"FEATURES {\nSTARTADDRESS: default = $9000;\n}\n"
+ "MEMORY {\n"
+ " ZP: start = $82, size = $7E;\n"
+ " RAM: start = $0200, size = $1e00;\n"
+ " ROM: start = $9000, size = $7000;\n"
+ " VEC: start = $FFFA, size = 6;\n"
+ "}\n"
+ "SEGMENTS {\n"
+ " CODE: load = ROM, type = ro, define = no;\n"
+ " DATA: load = RAM, type = rw, define = no;\n"
+ "ZEROPAGE: load = ZP, type = zp, define = no;\n"
//+ " VECTORS: load = VEC, type = ro, define = yes;"
+ "}\n"
;
/*
+ "SYMBOLS {\n"
+ " __STACKSIZE__: type = weak, value = $0800; # 2k stack\n"
+ " __RESERVED_MEMORY__: type = weak, value = $0000;\n"
+ " __STARTADDRESS__: type = export, value = %S;\n"
+ "}\n"
+ "MEMORY {\n"
+ " ZP: file = \"\", define = yes, start = $0082, size = $007E;\n"
+ " MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S;\n"
+ "}\n"
+ "SEGMENTS {\n"
+ " ZEROPAGE: load = ZP, type = zp, optional = yes;\n"
+ " EXTZP: load = ZP, type = zp, optional = yes;\n"
+ " STARTUP: load = MAIN, type = ro, define = yes, optional = yes;\n"
+ " LOWCODE: load = MAIN, type = ro, define = yes, optional = yes;\n"
+ " ONCE: load = MAIN, type = ro, optional = yes;\n"
+ " CODE: load = MAIN, type = ro, define = yes;\n"
+ " RODATA: load = MAIN, type = ro, optional = yes;\n"
+ " DATA: load = MAIN, type = rw, optional = yes;\n"
+ " BSS: load = MAIN, type = bss, define = yes, optional = yes;\n"
+ " INIT: load = MAIN, type = bss, optional = yes;\n"
+ "}\n"
+ "FEATURES {\n"
+ " CONDES: type = constructor,\n"
+ " label = __CONSTRUCTOR_TABLE__,\n"
+ " count = __CONSTRUCTOR_COUNT__,\n"
+ " segment = ONCE;\n"
+ " CONDES: type = destructor,\n"
+ " label = __DESTRUCTOR_TABLE__,\n"
+ " count = __DESTRUCTOR_COUNT__,\n"
+ " segment = RODATA;\n"
+ " CONDES: type = interruptor,\n"
+ " label = __INTERRUPTOR_TABLE__,\n"
+ " count = __INTERRUPTOR_COUNT__,\n"
+ " segment = RODATA,\n"
+ " import = __CALLIRQ__;\n"
+ "}\n";
*/
// mount the filesystem at /share
function setupFS(FS, name) {
FS.mkdir('/share');
FS.mount(FS.filesystems['WORKERFS'], {
packages: [{ metadata: fsMeta[name], blob: fsBlob[name] }]
}, '/share');
FS.writeFile("/vector-ataricolor.cfg", ATARI_CFG);
}
var DASM_MAIN_FILENAME = "main.a";
@ -413,11 +468,14 @@ function assemblelinkCA65(code, platform, warnings) {
printErr:print_fn,
});
var FS = LD65['FS'];
var cfgfile = '/' + platform + '.cfg';
setupFS(FS, '65');
FS.writeFile("main.o", objout, {encoding:'binary'});
LD65.callMain(['--cfg-path', '/share/cfg', '--lib-path', '/share/lib',
'--start-addr', '0x6000', // TODO
'-t', platform, '-o', 'main', '-m', 'main.map', 'main.o', platform+'.lib']);
//'--start-addr', '0x6000', // TODO
'-C', cfgfile,
'-o', 'main', '-m', 'main.map', 'main.o',
'apple2.lib']);
var aout = FS.readFile("main", {encoding:'binary'});
var mapout = FS.readFile("main.map", {encoding:'utf8'});
var listing = parseCA65Listing(lstout, mapout);
@ -456,10 +514,17 @@ function compileCC65(code, platform) {
var FS = CC65['FS'];
setupFS(FS, '65');
FS.writeFile("main.c", code, {encoding:'utf8'});
CC65.callMain(['-v', '-T', '-g', /*'-Cl',*/ '-Oirs', '-I', '/share/include', '-t', platform, "main.c"]);
CC65.callMain(['-v', '-T', '-g', /*'-Cl',*/ '-Oirs', '-I', '/share/include', "main.c"]);
try {
var asmout = FS.readFile("main.s", {encoding:'utf8'});
return assemblelinkCA65(asmout, platform, errors);
var result = assemblelinkCA65(asmout, platform, errors);
/*
result.asmlines = result.lines;
result.lines = result.srclines;
result.srclines = null;
*/
//console.log(result.intermediate.listing);
return result;
} catch(e) {
return {errors:errors};
}

View File

@ -1,16 +1,29 @@
#!/usr/bin/python
import sys, string, math
import sys, string, math, argparse
import mido
min_note = 21
max_note = 21+63
max_voices = 3
one_voice_per_channel = 0
tempo = 48
compress = 0
transpose = 0
coutput = 1
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=21, help="first MIDI note")
parser.add_argument('-n', '--num', type=int, default=21+63, help="number of notes")
parser.add_argument('-v', '--voices', type=int, default=3, help="number of voices")
parser.add_argument('-T', '--transpose', type=int, default=0, help="transpose by half-steps")
parser.add_argument('-t', '--tempo', type=int, default=48, help="tempo")
parser.add_argument('-o', '--one', action="store_true", help="one voice per channel")
parser.add_argument('-z', '--compress', action="store_true", help="compress song (experimental)")
parser.add_argument('-H', '--hex', action="store_true", help="hex output")
parser.add_argument('midifile', help="MIDI file")
parser.add_argument('midichannels', nargs='?', help="comma-separated list of MIDI channels, or -")
args = parser.parse_args()
min_note = args.start
max_note = min_note + args.num
max_voices = args.voices
one_voice_per_channel = args.one
tempo = args.tempo
compress = args.compress
transpose = args.transpose
coutput = not args.hex
# for 2600
#max_voices = 2
@ -19,7 +32,7 @@ coutput = 1
#max_voices = 4
#one_voice_per_channel = 0
fn = sys.argv[1]
fn = args.midifile
mid = mido.MidiFile(fn)
@ -97,7 +110,7 @@ def channels_for_track(track):
channels.add(msg.channel)
return list(channels)
if len(sys.argv) < 3:
if not args.midichannels:
print mid
print mid.length, 'seconds'
for i, track in enumerate(mid.tracks):
@ -105,14 +118,12 @@ if len(sys.argv) < 3:
#for msg in track:
# print(msg)
else:
if len(sys.argv) > 3:
transpose = int(sys.argv[3])
gtime = 0
curtime = 0
nnotes = 0
nvoices = 0
curchans = 0
channels = [int(x) for x in string.split(sys.argv[2], ',')]
channels = [int(x) for x in string.split(args.midichannels, ',')]
print
print "// %s %s" % (mid, channels)
output = []