Skip to content

Commit

Permalink
Add terminal component
Browse files Browse the repository at this point in the history
  • Loading branch information
drskinner committed Jan 2, 2020
1 parent cd18534 commit c5d3f63
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 3 deletions.
7 changes: 5 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@
<div id="app">
<img src="@/assets/650vue_logo.png">
<DisplayPanel />
<RunCpu />
<hr>
<Terminal />
<DebugFlags />
<RunCpu />
</div>
</template>

<script>
import DebugFlags from '@/components/debug-flags'
import DisplayPanel from './components/display-panel.vue'
import RunCpu from './components/run-cpu.vue'
import Terminal from './components/terminal.vue'
export default {
name: 'app',
components: {
DebugFlags,
DisplayPanel,
RunCpu
RunCpu,
Terminal
}
}
</script>
Expand Down
1 change: 1 addition & 0 deletions src/components/run-cpu.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div>
<h2>CONTROL</h2>
Cycles: {{ cycles }}
<!-- TODO: Contextually disable buttons -->
<button @click="run">RUN</button>
Expand Down
173 changes: 173 additions & 0 deletions src/components/terminal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<template>
<div>
<h2>TERMINAL</h2>
<input id="command" v-model="command" maxlength="40" /><br>
<button @click="send">SEND</button>
<pre v-html="output"></pre>
</div>
</template>

<script>
import store from '@/store/index'
export default {
name: 'Terminal',
data() {
return {
command: '',
monitor: Array(24).fill('')
}
},
created() {
this.showRegisters();
},
computed: {
output() {
return this.monitor.join("\n");
}
},
methods: {
hexByte(value) {
return value.toString(16).padStart(2, '0');
},
hexWord(value) {
return value.toString(16).padStart(4, '0');
},
stringToByte(value) {
return parseInt(value, 16) & 0xff;
},
asciiToChar(value) {
return (value < 32) ? '.' : String.fromCharCode(value);
},
stringToWord(value) {
return parseInt(value, 16) & 0xffff;
},
outputLine(line) {
this.monitor.shift();
this.monitor.push(line);
},
error() {
this.outputLine('?');
return;
},
showMemory() {
// TODO: handle overflow, wrap at MEMTOP
let parts = this.command.split(' ')
if (parts.length === 1) {
this.error();
return;
}
let memoryPager = parseInt(parts[1], 16);
let top = (parts.length < 3) ? memoryPager + 0x7f : parseInt(parts[2], 16);
if (top > memoryPager + 0x7f) {
top = memoryPager + 0x7f;
}
while (memoryPager <= top) {
let line = `> ${this.hexWord(memoryPager)} `
for (let i = 0; i < 8; i += 1) {
line += `${this.hexByte(store.state.ram[memoryPager + i])} `;
}
for (let i = 0; i < 8; i += 1) {
line += this.asciiToChar(store.state.ram[memoryPager + i]);
}
this.outputLine(line);
memoryPager += 0x08;
}
},
writeMemory() {
let parts = this.command.split(' ');
if (parts.length < 3) {
this.error();
return;
}
let startAddress = parseInt(parts[1], 16);
if (startAddress < 0x000 || startAddress > 0xffff) {
this.error();
return;
}
// rewrite with shift or similar? (see Ruby 6502)
// loop through additional parts
for (let i = 0; i < (parts.length - 2); i += 1) {
store.commit('writeRam', { address: startAddress + i,
value: this.stringToByte(parts[2 + i]) });
}
return;
},
showRegisters() {
this.outputLine(' PC SR AC XR YR SP');
let registerLine = '; ';
registerLine += `${this.hexWord(store.state.cpu.pc)} `;
registerLine += `${this.hexByte(store.state.cpu.sr)} `;
registerLine += `${this.hexByte(store.state.cpu.ac)} `;
registerLine += `${this.hexByte(store.state.cpu.xr)} `;
registerLine += `${this.hexByte(store.state.cpu.yr)} `;
registerLine += `${this.hexByte(store.state.cpu.sp)} `;
this.outputLine(registerLine);
},
setRegisters() {
let parts = this.command.split(' ');
if (parts.length != 7) {
this.error();
return;
}
store.commit('writeRegister',
{ register: 'pc', value: this.stringToWord(parts[1]) });
store.commit('writeRegister',
{ register: 'sr', value: this.stringToByte(parts[2]) });
store.commit('writeRegister',
{ register: 'ac', value: this.stringToByte(parts[3]) });
store.commit('writeRegister',
{ register: 'xr', value: this.stringToByte(parts[4]) });
store.commit('writeRegister',
{ register: 'yr', value: this.stringToByte(parts[5]) });
store.commit('writeRegister',
{ register: 'sp', value: this.stringToByte(parts[6]) });
this.showRegisters();
return;
},
send() {
this.outputLine(`<span style="color:yellow;">${this.command}</span>`);
// switch block?
if (this.command[0] === 'g') {
this.outputLine('Go where?');
} else if (this.command[0] === 'm') {
this.showMemory();
} else if (this.command[0] === 'r') {
this.showRegisters();
} else if (this.command[0] === '>') {
this.writeMemory();
} else if (this.command[0] === ';') {
this.setRegisters();
} else {
this.outputLine('?');
}
this.command = '';
}
}
}
</script>

<style scoped>
div {
text-align: left;
}
pre {
font-family: monospace, sans-serif;
font-size: 100%;
width: 395px;
padding: 3px 0 0 5px;
background-color: black;
color: lime;
}
</style>
11 changes: 10 additions & 1 deletion src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export default new Vuex.Store({
},
mutations: {
resetPc(state) {
state.cpu.pc = (state.ram[0xffdd] * 0x100) + state.ram[0xffdc];
state.cpu.pc = (state.ram[0xfffd] * 0x100) + state.ram[0xfffc];
},
// Reset _could_ actually JMP to the reset vector like it's meant to,
// and then some code in "ROM" could initialize the registers.
resetRegisters({ cpu }) {
cpu.ac = 0x00;
cpu.xr = 0x00;
Expand All @@ -35,9 +37,16 @@ export default new Vuex.Store({
// Subtracting 0x01 is equivalent to adding 0xff with a subsequent mask.
decrementRegister({ cpu }, register) {
cpu[register] = (cpu[register] + 0xff) & 0xff;
},
writeRegister({ cpu }, data) {
cpu[data.register] = data.value;
},
writeRam({ ram }, data) {
ram[data.address] = data.value;
}
// TODO:
// * set and clear individual status flags
// * set individual registers
// * write to ram
// * push/pull to stack
},
Expand Down

0 comments on commit c5d3f63

Please sign in to comment.