mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 03:34:05 +00:00
working on vector
This commit is contained in:
parent
e579663a8d
commit
52b58f471c
@ -192,7 +192,7 @@ canvas.pixelated {
|
||||
<ul class="dropdown-menu">
|
||||
<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=atarivec" id="item_platform_atarivec">Asteroids</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=vector" id="item_platform_atarivec">Asteroids</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080 B/W</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
31
src/emu.js
31
src/emu.js
@ -374,6 +374,12 @@ var AY38910_Audio = function(master) {
|
||||
|
||||
var Base6502Platform = function() {
|
||||
|
||||
this.newCPU = function(membus) {
|
||||
var cpu = new jt.M6502();
|
||||
cpu.connectBus(membus);
|
||||
return cpu;
|
||||
}
|
||||
|
||||
this.getOpcodeMetadata = function(opcode, offset) {
|
||||
return Javatari.getOpcodeMetadata(opcode, offset); // TODO
|
||||
}
|
||||
@ -544,12 +550,13 @@ function cpuStateToLongString_Z80(c) {
|
||||
;
|
||||
}
|
||||
|
||||
window.buildZ80({
|
||||
applyContention: false // TODO???
|
||||
});
|
||||
|
||||
var BaseZ80Platform = function() {
|
||||
|
||||
window.buildZ80({
|
||||
applyContention: false // TODO???
|
||||
});
|
||||
|
||||
// TODO: refactor w/ platforms
|
||||
this.newCPU = function(membus, iobus) {
|
||||
return window.Z80({
|
||||
@ -559,6 +566,24 @@ var BaseZ80Platform = function() {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: refactor other parts into here
|
||||
this.runCPU = function(cpu, cycles) {
|
||||
var debugCond = this.getDebugCallback();
|
||||
var targetTstates = cpu.getTstates() + cycles;
|
||||
if (debugCond) { // || trace) {
|
||||
while (cpu.getTstates() < targetTstates) {
|
||||
//_trace(); // TODO
|
||||
if (debugCond && debugCond()) {
|
||||
debugCond = null;
|
||||
break;
|
||||
}
|
||||
cpu.runFrame(cpu.getTstates() + 1);
|
||||
}
|
||||
} else {
|
||||
cpu.runFrame(targetTstates);
|
||||
}
|
||||
}
|
||||
|
||||
var onBreakpointHit;
|
||||
var debugCondition;
|
||||
var debugSavedState = null;
|
||||
|
@ -1,4 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var GALAXIAN_PRESETS = [
|
||||
];
|
||||
|
||||
@ -111,7 +112,8 @@ var GalaxianPlatform = function(mainElement) {
|
||||
missile = which;
|
||||
}
|
||||
}
|
||||
for (var which of [shell,missile]) {
|
||||
for (var i=0; i<2; i++) {
|
||||
which = i ? missile : shell;
|
||||
if (which != 0xff) {
|
||||
var sx = 255 - oram.mem[0x60 + (which<<2)+3];
|
||||
var outi = pixofs+sx;
|
||||
|
@ -1,8 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
var ATARIVEC_PRESETS = [
|
||||
var VECTOR_PRESETS = [
|
||||
]
|
||||
|
||||
var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([
|
||||
[Keys.VK_SHIFT, 3, 0xff],
|
||||
[Keys.VK_SPACE, 4, 0xff],
|
||||
[Keys.VK_5, 8, 0xff],
|
||||
[Keys.VK_6, 9, 0xff],
|
||||
[Keys.VK_7, 10, 0xff],
|
||||
[Keys.VK_1, 11, 0xff],
|
||||
[Keys.VK_2, 12, 0xff],
|
||||
[Keys.VK_UP, 13, 0xff],
|
||||
[Keys.VK_RIGHT, 14, 0xff],
|
||||
[Keys.VK_LEFT, 15, 0xff],
|
||||
]);
|
||||
|
||||
|
||||
var AtariVectorPlatform = function(mainElement) {
|
||||
var self = this;
|
||||
var cpuFrequency = 1500000.0;
|
||||
@ -16,25 +30,11 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
|
||||
this.__proto__ = new Base6502Platform();
|
||||
|
||||
var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([
|
||||
[Keys.VK_SHIFT, 3, 0xff],
|
||||
[Keys.VK_SPACE, 4, 0xff],
|
||||
[Keys.VK_5, 8, 0xff],
|
||||
[Keys.VK_6, 9, 0xff],
|
||||
[Keys.VK_7, 10, 0xff],
|
||||
[Keys.VK_1, 11, 0xff],
|
||||
[Keys.VK_2, 12, 0xff],
|
||||
[Keys.VK_UP, 13, 0xff],
|
||||
[Keys.VK_RIGHT, 14, 0xff],
|
||||
[Keys.VK_LEFT, 15, 0xff],
|
||||
]);
|
||||
|
||||
this.getPresets = function() {
|
||||
return ATARIVEC_PRESETS;
|
||||
return VECTOR_PRESETS;
|
||||
}
|
||||
|
||||
this.start = function() {
|
||||
cpu = new jt.M6502();
|
||||
cpuram = new RAM(0x400);
|
||||
dvgram = new RAM(0x2000);
|
||||
//switches[5] = 0xff;
|
||||
@ -60,7 +60,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
], {gmask:0x7fff})
|
||||
|
||||
};
|
||||
cpu.connectBus(bus);
|
||||
cpu = self.newCPU(bus);
|
||||
// create video/audio
|
||||
video = new VectorVideo(mainElement,1024,1024);
|
||||
dvg = new DVGStateMachine(bus, video);
|
||||
@ -68,9 +68,6 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
video.create();
|
||||
timer = new AnimationTimer(60, function() {
|
||||
video.clear();
|
||||
// 262.5 scanlines per frame
|
||||
var iaddr = 0x4000;
|
||||
var iofs = 0;
|
||||
var debugCond = self.getDebugCallback();
|
||||
clock = 0;
|
||||
for (var i=0; i<cpuCyclesPerFrame; i++) {
|
||||
@ -101,7 +98,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
}
|
||||
|
||||
this.getRasterPosition = function() {
|
||||
return {x:0, y:0};
|
||||
return {x:0, y:0}; // TODO
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
@ -140,6 +137,107 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var VectorZ80Platform = function(mainElement, proto) {
|
||||
var self = this;
|
||||
var cpuFrequency = 3000000.0;
|
||||
var cpuCyclesPerFrame = Math.round(cpuFrequency/60);
|
||||
var cpu, cpuram, dvgram, rom, bus, dvg;
|
||||
var video, audio, timer;
|
||||
var clock;
|
||||
var switches = new RAM(16).mem;
|
||||
|
||||
this.__proto__ = new BaseZ80Platform();
|
||||
|
||||
this.getPresets = function() {
|
||||
return VECTOR_PRESETS;
|
||||
}
|
||||
|
||||
this.start = function() {
|
||||
cpuram = new RAM(0x1000);
|
||||
dvgram = new RAM(0x2000);
|
||||
//switches[5] = 0xff;
|
||||
//switches[7] = 0xff;
|
||||
// bus
|
||||
bus = {
|
||||
|
||||
read: new AddressDecoder([
|
||||
[0x0, 0x3fff, 0, function(a) { return rom[a]; }],
|
||||
[0x4000, 0x5fff, 0x1fff, function(a) { return dvgram.mem[a]; }],
|
||||
[0x6000, 0x6fff, 0xfff, function(a) { return cpuram.mem[a]; }],
|
||||
[0x7001, 0x7001, 0, function(a) { return ((clock/1000) & 1) ? 0xff : 0x00; }],
|
||||
[0x7000, 0x7007, 0x7, function(a) { return switches[a]; }],
|
||||
[0x7400, 0x7407, 0x7, function(a) { return switches[a+8]; }],
|
||||
]),
|
||||
|
||||
write: new AddressDecoder([
|
||||
[0x7000, 0x7000, 0, function(a,v) { dvg.runUntilHalt(); }],
|
||||
// TODO: draw asynchronous or allow poll of HALT ($2002)
|
||||
[0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }],
|
||||
[0x6000, 0x6fff, 0xfff, function(a,v) { cpuram.mem[a] = v; }],
|
||||
])
|
||||
|
||||
};
|
||||
cpu = self.newCPU(bus);
|
||||
// create video/audio
|
||||
video = new VectorVideo(mainElement,1024,1024);
|
||||
dvg = new DVGStateMachine(bus, video);
|
||||
audio = new SampleAudio(cpuFrequency);
|
||||
video.create();
|
||||
timer = new AnimationTimer(60, function() {
|
||||
video.clear();
|
||||
self.runCPU(cpu, cpuCyclesPerFrame);
|
||||
cpu.requestInterrupt();
|
||||
self.restartDebugState();
|
||||
});
|
||||
setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP);
|
||||
}
|
||||
|
||||
this.loadROM = function(title, data) {
|
||||
rom = padBytes(data, 0x4000);
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.getRasterPosition = function() {
|
||||
return {x:0, y:0}; // TODO
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
return timer.isRunning();
|
||||
}
|
||||
this.pause = function() {
|
||||
timer.stop();
|
||||
}
|
||||
this.resume = function() {
|
||||
timer.start();
|
||||
}
|
||||
this.reset = function() {
|
||||
cpu.reset();
|
||||
}
|
||||
this.readAddress = function(addr) {
|
||||
return bus.read(addr);
|
||||
}
|
||||
|
||||
this.loadState = function(state) {
|
||||
cpu.loadState(state.c);
|
||||
cpuram.mem.set(state.db);
|
||||
dvgram.mem.set(state.db);
|
||||
}
|
||||
this.saveState = function() {
|
||||
return {
|
||||
c:cpu.saveState(),
|
||||
cb:cpuram.mem.slice(0),
|
||||
db:dvgram.mem.slice(0),
|
||||
}
|
||||
}
|
||||
this.getCPUState = function() {
|
||||
return cpu.saveState();
|
||||
}
|
||||
}
|
||||
|
||||
// DIGITAL VIDEO GENERATOR
|
||||
|
||||
var DVGStateMachine = function(bus, video) {
|
||||
var self = this;
|
||||
var pc = 0;
|
||||
@ -172,7 +270,7 @@ var DVGStateMachine = function(bus, video) {
|
||||
|
||||
this.runUntilHalt = function() {
|
||||
this.go();
|
||||
for (var i=0; i<10000; i++) { // TODO
|
||||
for (var i=0; i<10000; i++) { // TODO: limit execution
|
||||
if (!running) break;
|
||||
this.nextInstruction();
|
||||
}
|
||||
@ -243,4 +341,7 @@ var DVGStateMachine = function(bus, video) {
|
||||
}
|
||||
}
|
||||
|
||||
PLATFORMS['atarivec'] = AtariVectorPlatform;
|
||||
//
|
||||
|
||||
PLATFORMS['vector-ataribw'] = AtariVectorPlatform;
|
||||
PLATFORMS['vector-z80'] = VectorZ80Platform;
|
@ -246,6 +246,8 @@ var WilliamsPlatform = function(mainElement, proto) {
|
||||
memwrite_williams(dstaddr, curpix);
|
||||
}
|
||||
|
||||
// TODO
|
||||
/*
|
||||
var trace = false;
|
||||
var _traceinsns = {};
|
||||
function _trace() {
|
||||
@ -255,7 +257,7 @@ var WilliamsPlatform = function(mainElement, proto) {
|
||||
console.log(hex(pc), cpu.getTstates());
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
this.start = function() {
|
||||
ram = new RAM(0xc000);
|
||||
nvram = new RAM(0x400);
|
||||
@ -283,7 +285,6 @@ var WilliamsPlatform = function(mainElement, proto) {
|
||||
timer = new AnimationTimer(60, function() {
|
||||
if (!self.isRunning())
|
||||
return;
|
||||
var debugCond = self.getDebugCallback();
|
||||
// interrupts happen every 1/4 of the screen
|
||||
for (var quarter=0; quarter<4; quarter++) {
|
||||
video_counter = [0x00, 0x3c, 0xbc, 0xfc][quarter];
|
||||
@ -293,19 +294,7 @@ var WilliamsPlatform = function(mainElement, proto) {
|
||||
if (cpu.requestInterrupt)
|
||||
cpu.requestInterrupt();
|
||||
}
|
||||
var targetTstates = cpu.getTstates() + cpuCyclesPerFrame/4;
|
||||
if (debugCond || trace) {
|
||||
while (cpu.getTstates() < targetTstates) {
|
||||
_trace();
|
||||
if (debugCond && debugCond()) {
|
||||
debugCond = null;
|
||||
break;
|
||||
}
|
||||
cpu.runFrame(cpu.getTstates() + 1);
|
||||
}
|
||||
} else {
|
||||
cpu.runFrame(targetTstates);
|
||||
}
|
||||
self.runCPU(cpu, cpuCyclesPerFrame/4);
|
||||
}
|
||||
if (screenNeedsRefresh) {
|
||||
for (var i=0; i<0x9800; i++)
|
||||
@ -377,6 +366,18 @@ var WilliamsPlatform = function(mainElement, proto) {
|
||||
|
||||
var WilliamsZ80Platform = function(mainElement) {
|
||||
this.__proto__ = new WilliamsPlatform(mainElement, BaseZ80Platform);
|
||||
|
||||
this.ramStateToLongString = function(state) {
|
||||
var blt = state.blt;
|
||||
var sstart = (blt[2] << 8) + blt[3];
|
||||
var dstart = (blt[4] << 8) + blt[5];
|
||||
var w = blt[6] ^ 4; // blitter bug fix
|
||||
var h = blt[7] ^ 4;
|
||||
return "\nBLIT"
|
||||
+ " " + hex(sstart,4) + " " + hex(dstart,4)
|
||||
+ " w:" + hex(w) + " h:" + hex(h)
|
||||
+ " f:" + hex(blt[0]) + " s:" + hex(blt[1]);
|
||||
}
|
||||
}
|
||||
|
||||
PLATFORMS['williams'] = WilliamsPlatform;
|
||||
|
@ -25,6 +25,12 @@ var PLATFORM_PARAMS = {
|
||||
data_start: 0x9000,
|
||||
data_size: 0x3000,
|
||||
},
|
||||
'vector-z80': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x4000,
|
||||
data_start: 0x4000,
|
||||
data_size: 0x3000,
|
||||
},
|
||||
};
|
||||
|
||||
var loaded = {}
|
||||
@ -96,6 +102,7 @@ function match_msvc(s) {
|
||||
var errline = parseInt(matches[2]);
|
||||
msvc_errors.push({
|
||||
line:errline,
|
||||
type:matches[3],
|
||||
msg:matches[4]
|
||||
});
|
||||
}
|
||||
@ -417,6 +424,7 @@ function compileCC65(code, platform) {
|
||||
var errors = [];
|
||||
var errline = 0;
|
||||
function match_fn(s) {
|
||||
console.log(s);
|
||||
var matches = re_err1.exec(s);
|
||||
if (matches) {
|
||||
errline = parseInt(matches[1]);
|
||||
@ -636,26 +644,38 @@ function compileSDCC(code, platform) {
|
||||
setupFS(FS, 'sdcc');
|
||||
//FS.writeFile("main.c", code, {encoding:'utf8'});
|
||||
msvc_errors = [];
|
||||
SDCC.callMain(['--vc', '--std-sdcc99', '-mz80', '-Wall',
|
||||
SDCC.callMain(['--vc', '--std-sdcc99', '-mz80', //'-Wall',
|
||||
'--c1mode', // '--debug',
|
||||
//'-S', 'main.c',
|
||||
//'--asm=z80asm',
|
||||
'--fomit-frame-pointer', '--opt-code-speed',
|
||||
'-o', 'main.asm']);
|
||||
if (msvc_errors.length) {
|
||||
// ignore if all are warnings (TODO?)
|
||||
var nwarnings = 0;
|
||||
for (var err of msvc_errors) {
|
||||
if (err.type && err.type.startsWith("warning"))
|
||||
nwarnings++;
|
||||
}
|
||||
if (msvc_errors.length && nwarnings < msvc_errors.length) {
|
||||
return {errors:msvc_errors};
|
||||
}
|
||||
try {
|
||||
var asmout = FS.readFile("main.asm", {encoding:'utf8'});
|
||||
} catch (e) {
|
||||
return {errors:[{line:1, msg:e+""}]};
|
||||
msvc_errors.push({line:1, msg:e+""});
|
||||
return {errors:msvc_errors};
|
||||
}
|
||||
var warnings = msvc_errors;
|
||||
try {
|
||||
var result = assemblelinkSDASZ80(asmout, platform, true);
|
||||
} catch (e) {
|
||||
msvc_errors.push({line:1, msg:e+""});
|
||||
return {errors:msvc_errors};
|
||||
}
|
||||
result.asmlines = result.lines;
|
||||
result.lines = result.srclines;
|
||||
result.srclines = null;
|
||||
result.errors = result.errors.concat(warnings);
|
||||
//result.errors = result.errors.concat(warnings);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
<script src="src/disasm.js"></script>
|
||||
<script src="src/platform/vcs.js"></script>
|
||||
<script src="src/platform/mw8080bw.js"></script>
|
||||
<script src="src/platform/vicdual.js"></script>
|
||||
<script src="src/platform/williams.js"></script>
|
||||
<script src="src/platform/galaxian.js"></script>
|
||||
|
||||
<script src="test/ui/testemus.js"></script>
|
||||
<script>
|
||||
|
0
tools/p4_to_48pix.py
Normal file → Executable file
0
tools/p4_to_48pix.py
Normal file → Executable file
0
tools/p4_to_pfbytes.py
Normal file → Executable file
0
tools/p4_to_pfbytes.py
Normal file → Executable file
4
tools/parsebdf3x5.py
Normal file → Executable file
4
tools/parsebdf3x5.py
Normal file → Executable file
@ -41,6 +41,7 @@ output = []
|
||||
outputlo = []
|
||||
outputhi = []
|
||||
for ch in range(lochar,hichar+1):
|
||||
x = 0
|
||||
bytes = chars.get(ch)
|
||||
#bytes = bytes + [0]
|
||||
if not bytes:
|
||||
@ -57,8 +58,11 @@ for ch in range(lochar,hichar+1):
|
||||
|
||||
def tohex(v):
|
||||
return '%02x'%v
|
||||
def tohex2(v):
|
||||
return '0x%02x'%v
|
||||
|
||||
print '\thex ' + string.join(map(tohex,output),'')
|
||||
print string.join(map(tohex2,output),',')
|
||||
print '\thex ' + string.join(map(tohex,outputlo),'')
|
||||
print '\thex ' + string.join(map(tohex,outputhi),'')
|
||||
|
||||
|
5
tools/parsebdf8.py
Normal file → Executable file
5
tools/parsebdf8.py
Normal file → Executable file
@ -36,6 +36,7 @@ with open(sys.argv[1],'r') as f:
|
||||
x = 0
|
||||
output = []
|
||||
invoutput = []
|
||||
revoutput = []
|
||||
rotoutput = []
|
||||
rot2output = []
|
||||
for ch in range(lochar,hichar+1):
|
||||
@ -48,6 +49,8 @@ for ch in range(lochar,hichar+1):
|
||||
invoutput.append(b ^ 0xff)
|
||||
rotoutput.append(0)
|
||||
rot2output.append(0)
|
||||
for i in range(0,8):
|
||||
revoutput.append(bytes[7-i])
|
||||
for x in range(0,height):
|
||||
for y in range(0,height):
|
||||
#rotoutput[-7+x] |= (((output[-1-y]>>x)&1)<<y)
|
||||
@ -59,7 +62,7 @@ def tohex(v):
|
||||
def tohex2(v):
|
||||
return '0x%02x'%v
|
||||
|
||||
for arr in [output,invoutput,rotoutput,rot2output]:
|
||||
for arr in [output,revoutput,invoutput,rotoutput,rot2output]:
|
||||
print '\thex ' + string.join(map(tohex,arr),'')
|
||||
for i in range(0,len(output),height):
|
||||
print '{', string.join(map(tohex2,arr[i:i+height]),','), '},',
|
||||
|
0
tools/pbm_to_c.py
Normal file → Executable file
0
tools/pbm_to_c.py
Normal file → Executable file
Loading…
Reference in New Issue
Block a user