fix conditions, add ien flag, improve keyboard, add gpio
This commit is contained in:
parent
4af6f46a51
commit
b75ff48300
@ -42,7 +42,7 @@
|
||||
#define ldi cpu->instr = readmemory(cpu->i); cpu->cycle = 0;
|
||||
#define addf(x,y) { x=(x+y); cpu->cf=x>=256; x&=0xFF; setzf(x); }
|
||||
#define subf(x,y) addf(x,-y);
|
||||
#define cmpf(x,y) { int t=x-y; cpu->cf=(t>=256); setzf(t); }
|
||||
#define cmpf(x,y) { int t=x-y; cpu->cf=(t<0); setzf(t); }
|
||||
#define rol(x,y) x=(x<<y)|(x>>(8-y));
|
||||
#define ror(x,y) x=(x>>y)|(x<<(8-y));
|
||||
#define sra(x,y) x=(x>>y);
|
||||
@ -80,6 +80,7 @@ struct CPU {
|
||||
int irq;
|
||||
int ifg;
|
||||
int rfg;
|
||||
int ien;
|
||||
int instr;
|
||||
int cycle;
|
||||
int instrpre;
|
||||
@ -130,14 +131,15 @@ typedef void(*CPUInstruction)(struct CPU* const cpu, struct Memory* const mem);
|
||||
|
||||
#include "instructions_gen.c"
|
||||
|
||||
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs) {
|
||||
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr) {
|
||||
int i = 0;
|
||||
while(i<count) {
|
||||
if(cpu->irq && !cpu->ifg && cpu->cycle==0) { cpu->instr = 0xF2; }
|
||||
if(cpu->irq && !cpu->ifg && cpu->cycle==0 && cpu->ien) { cpu->instr = 0xF2; }
|
||||
if(cpu->rfg || cpu->ifg || cpu->irq) {
|
||||
CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle];
|
||||
if(instr) instr(cpu, mem);
|
||||
if(!countinstrs || cpu->cycle==0) { i++; }
|
||||
if(cpu->i==breakaddr) { i = count; break; }
|
||||
} else { i = count; break; }
|
||||
if(mem->numevents!=0) { break; }
|
||||
}
|
||||
|
Binary file not shown.
@ -11,6 +11,7 @@ local lg = love.graphics
|
||||
local li = love.image
|
||||
local le = love.event
|
||||
local lt = love.timer
|
||||
local lk = love.keyboard
|
||||
|
||||
----
|
||||
local function InitColorset()
|
||||
@ -43,7 +44,7 @@ local function handleEvents(cpu, mem)
|
||||
end
|
||||
|
||||
local RegDisplay = {
|
||||
scrX = 384+16, scrY = 32,
|
||||
scrX = 384+16, scrY = 32+8,
|
||||
width = 128, height = 192,
|
||||
fontWidth = 8, fontHeight = 12,
|
||||
registers = {
|
||||
@ -63,7 +64,8 @@ local RegDisplay = {
|
||||
flags = {
|
||||
{ name = "CF" , idx = "cf" , x=64+8,y=8 },
|
||||
{ name = "NZ" , idx = "nz" , x=64+8,y=8+16 },
|
||||
{ name = "IRQ", idx = "irq", x=64+8,y=8+16*2},
|
||||
{ name = "IRq", idx = "irq", x=64+8,y=8+16*2},
|
||||
{ name = "IEn", idx = "ien", x=64+8,y=8+16*5},
|
||||
{ name = "Int", idx = "ifg", x=64+8,y=8+16*3},
|
||||
{ name = "Run", idx = "rfg", x=64+8,y=8+16*4},
|
||||
},
|
||||
@ -107,8 +109,9 @@ local function RedrawRegDisplay(rd, cpu, mem)
|
||||
end
|
||||
|
||||
local ReadMemory
|
||||
local WriteMemory
|
||||
local StackDisplay = {
|
||||
scrX = 8+384+32+6, scrY = 32+192+32,
|
||||
scrX = 8+384+32+6, scrY = 32+192+32-4,
|
||||
lines = 16, fontHeight = 12,
|
||||
}
|
||||
local function InitStackDisplay(sd)
|
||||
@ -130,11 +133,11 @@ end
|
||||
|
||||
local MemoryDisplays = {
|
||||
{
|
||||
scrX = 8, scrY = 32+192+32,
|
||||
scrX = 8, scrY = 32+192+32-4,
|
||||
columns = 16, columnSpace = 4, rows = 16,
|
||||
fontHeight = 12,
|
||||
showAscii = false,
|
||||
addr = 0x0000,
|
||||
addr = 0x3000,
|
||||
highlightTime = 8,
|
||||
},
|
||||
}
|
||||
@ -205,9 +208,9 @@ local function RedrawMemoryDisplay(md, cpu, mem)
|
||||
end
|
||||
|
||||
local ProgramDisplay = {
|
||||
scrX = 8+384+8+128+8, scrY = 32,
|
||||
scrX = 8+384+8+128+8, scrY = 32+8,
|
||||
fontHeight = 12,
|
||||
numLines = 35,
|
||||
numLines = 34,
|
||||
highlightTime = 8,
|
||||
}
|
||||
local function pdLinesFromDasm(dasm)
|
||||
@ -301,20 +304,12 @@ local CharDisplay = {
|
||||
width = 64*6, height = 16*12,
|
||||
rows = 16, cols = 64,
|
||||
fontWidth = 6, fontHeight = 12,
|
||||
scrX = 8, scrY = 32,
|
||||
scrX = 8, scrY = 32+8,
|
||||
addrChar = 0x0800,
|
||||
addrColor = 0x0C00,
|
||||
}
|
||||
local function InitCharDisplay(cd)
|
||||
lg.print("Char Display", cd.scrX, cd.scrY-16)
|
||||
cd.chars = {}
|
||||
cd.colors = {}
|
||||
cd.highlight = {}
|
||||
for a = 0, cd.rows*cd.cols-1 do
|
||||
cd.chars[a] = ""
|
||||
cd.colors[a] = ColorSet[1]
|
||||
cd.highlight[a] = false
|
||||
end
|
||||
cd.font = lg.newFont("consola.ttf", cd.fontHeight-1, "mono")
|
||||
end
|
||||
|
||||
@ -346,19 +341,92 @@ local keycodes = require("keycodes")
|
||||
local CPURequestInterrupt
|
||||
local function KeyboardOnKey(kb, key, press, cpu, mem)
|
||||
local code = keycodes[key] or keycodes["invalid"]
|
||||
table.insert(kb.queue, code)
|
||||
if code==0x7F then print("invalid key: "..key) end
|
||||
table.insert(kb.queue, code + (press and 128 or 0))
|
||||
if #kb.queue > kb.queueSize then table.remove(kb.queue, 1) end
|
||||
kb.queueEmpty = false
|
||||
kbSetNext(kb, cpu, mem)
|
||||
if kb.interrupts then CPURequestInterrupt(cpu) end
|
||||
end
|
||||
|
||||
local function RedrawFPSCounter(x,y)
|
||||
local function RedrawFPSCounter(x, y)
|
||||
lg.setColor(0,0,0)
|
||||
lg.rectangle("fill",x,y,64,12)
|
||||
lg.setColor(1,1,1)
|
||||
lg.print("FPS: "..lt.getFPS(), x,y)
|
||||
end
|
||||
local function printHighlight(s, o, h, x, y)
|
||||
x = x+o*7
|
||||
local w = 7*#s
|
||||
lg.setColor(1,1,1)
|
||||
if h then
|
||||
lg.rectangle("fill", x, y, w, 12)
|
||||
lg.setColor(0,0,0)
|
||||
end
|
||||
lg.print(s, x, y)
|
||||
end
|
||||
local function RedrawKeyInfo(x, y, uk, run)
|
||||
lg.setColor(0,0,0)
|
||||
lg.rectangle("fill",x,y,768,12)
|
||||
lg.setColor(1,1,1)
|
||||
printHighlight("[ESC] Toggle keyboard", 0, lk.isDown("escape"), x, y)
|
||||
lg.setColor(1,1,1)
|
||||
if uk then
|
||||
printHighlight("Keystrokes passed to device", 23, false, x, y)
|
||||
else
|
||||
printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y)
|
||||
printHighlight("[T] Tick once", 33, lk.isDown("t"), x, y)
|
||||
printHighlight("[S] Step once", 48, lk.isDown("s"), x, y)
|
||||
printHighlight("[Q] Quit", 63, lk.isDown("q"), x, y)
|
||||
end
|
||||
end
|
||||
|
||||
local GPIO = {}
|
||||
local function InitGPIO(gpio)
|
||||
gpio.mulLeft = 0
|
||||
gpio.mulRight = 0
|
||||
gpio.divLeft = 0
|
||||
gpio.divRight = 0
|
||||
gpio.intQueued = false
|
||||
end
|
||||
local function UpdateGPIO(gpio, cpu, mem)
|
||||
if gpio.intQueued then
|
||||
gpio.intQueued = false
|
||||
CPURequestInterrupt(cpu)
|
||||
end
|
||||
end
|
||||
local function gpioSetValue(name, func)
|
||||
return function(addr, cpu, mem, gpio)
|
||||
gpio[name] = ReadMemory(mem, addr)
|
||||
func(addr, cpu, mem, gpio)
|
||||
end
|
||||
end
|
||||
local function gpioMul(addr, cpu, mem, gpio)
|
||||
local base = math.floor(addr/256)*256
|
||||
local res = gpio.mulLeft*gpio.mulRight
|
||||
WriteMemory(mem, base+0x00, math.floor(res/256))
|
||||
WriteMemory(mem, base+0x01, res%256)
|
||||
end
|
||||
local function gpioDiv(addr, cpu, mem, gpio)
|
||||
local base = math.floor(addr/256)*256
|
||||
WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight))
|
||||
WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight)
|
||||
end
|
||||
local gpioFunctions = {
|
||||
[0x00] = gpioSetValue("mulLeft" , gpioMul),
|
||||
[0x01] = gpioSetValue("mulRight", gpioMul),
|
||||
[0x02] = gpioSetValue("divLeft" , gpioDiv),
|
||||
[0x03] = gpioSetValue("divRight", gpioDiv),
|
||||
[0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(readMemory(mem, addr))) end,
|
||||
[0x05] = function(addr, cpu, mem, gpio) gpio.intQueued = true; WriteMemory(mem, addr, 0); end
|
||||
}
|
||||
local function GPIOOnWrite(addr, cpu, mem, gpio)
|
||||
local offset = addr%256
|
||||
local func = gpioFunctions[offset]
|
||||
if func then
|
||||
func(addr, cpu, mem, gpio)
|
||||
end
|
||||
end
|
||||
|
||||
local peripherals = {
|
||||
CharDisplay = { range = {0x0800, 0x0FFF}, write = true },
|
||||
@ -371,6 +439,9 @@ local peripherals = {
|
||||
onread = function(addr, cpu, mem) KeyboardOnRead (addr, cpu, mem, Keyboard) end,
|
||||
onwrite = function(addr, cpu, mem) KeyboardOnWrite(addr, cpu, mem, Keyboard) end,
|
||||
},
|
||||
GPIO = { range = {0x0400, 0x04FF}, write = true,
|
||||
onwrite = function(addr, cpu, mem) GPIOOnWrite(addr, cpu, mem, GPIO) end,
|
||||
},
|
||||
}
|
||||
|
||||
----
|
||||
@ -413,7 +484,7 @@ end
|
||||
ReadMemory = function(mem, addr)
|
||||
return mem.c.data[addr%65536]%256
|
||||
end
|
||||
local function WriteMemory(mem, addr, val)
|
||||
WriteMemory = function(mem, addr, val)
|
||||
if mem.c.canwrite[addr%65536]~=0 then
|
||||
mem.c.data[addr%65536] = val%256
|
||||
end
|
||||
@ -445,21 +516,22 @@ struct CPU {
|
||||
int irq;
|
||||
int ifg;
|
||||
int rfg;
|
||||
int ien;
|
||||
int instr;
|
||||
int cycle;
|
||||
int instrpre;
|
||||
int frame;
|
||||
};
|
||||
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs);
|
||||
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr);
|
||||
]]
|
||||
local CPU = {
|
||||
c = ffi.new("struct CPU"),
|
||||
}
|
||||
local cpuDll = ffi.load("8608emulator.dll")
|
||||
local function TickCPU(cpu, mem, count, countinstrs)
|
||||
local function TickCPU(cpu, mem, count, countinstrs, breakaddr)
|
||||
local countleft = count
|
||||
while countleft>0 do
|
||||
countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0)
|
||||
countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF)
|
||||
handleEvents(cpu, mem)
|
||||
end
|
||||
end
|
||||
@ -470,6 +542,10 @@ CPURequestInterrupt = function(cpu)
|
||||
cpu.c.irq = 1;
|
||||
end
|
||||
|
||||
function RunToNextInstr(cpu)
|
||||
|
||||
end
|
||||
|
||||
----
|
||||
|
||||
local function RedrawVideoDisplay(vd, mem)
|
||||
@ -497,9 +573,11 @@ local function RedrawCharDisplay(cd, mem)
|
||||
local abase = cy*cd.cols + cx
|
||||
local achar = cd.addrChar + abase
|
||||
local acolor = cd.addrColor + abase
|
||||
local colorid = ReadMemory(mem, acolor)%64
|
||||
local colormem = ReadMemory(mem, acolor)
|
||||
local colorid = colormem%64
|
||||
local highlight = colormem>=128
|
||||
lg.setColor(ColorSet[colorid])
|
||||
if cd.highlight[a] then
|
||||
if highlight then
|
||||
lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight)
|
||||
lg.setColor(0, 0, 0)
|
||||
end
|
||||
@ -524,7 +602,7 @@ local function InitWindowCanvas()
|
||||
lg.setFont(InfoFont)
|
||||
lg.print("8608 CPU Emulator", 4, 4)
|
||||
end
|
||||
local function RedrawWindow()
|
||||
local function RedrawWindow(usekeyboard, runcpu)
|
||||
lg.setCanvas(WindowCanvas)
|
||||
lg.setFont(InfoFont)
|
||||
RedrawCharDisplay(CharDisplay, Memory)
|
||||
@ -534,6 +612,7 @@ local function RedrawWindow()
|
||||
RedrawProgramDisplay(ProgramDisplay, CPU, Memory)
|
||||
for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end
|
||||
RedrawFPSCounter(128+32, 4)
|
||||
RedrawKeyInfo(128+32+64+16, 4, usekeyboard, runcpu)
|
||||
|
||||
lg.setCanvas()
|
||||
end
|
||||
@ -547,6 +626,7 @@ function love.load()
|
||||
InitMemory(Memory, peripherals)
|
||||
InitWindowCanvas()
|
||||
InitCPU(CPU)
|
||||
InitGPIO(GPIO)
|
||||
--InitVideoDisplay(VideoDisplay)
|
||||
InitCharDisplay(CharDisplay)
|
||||
InitRegDisplay(RegDisplay)
|
||||
@ -560,24 +640,38 @@ end
|
||||
|
||||
local RunCPU = false
|
||||
local CPUSpeed = 4999
|
||||
local UseKeyboard = false
|
||||
function love.draw()
|
||||
UpdateGPIO(GPIO, CPU, Memory)
|
||||
|
||||
CPU.c.frame = CPU.c.frame + 1
|
||||
if RunCPU then
|
||||
TickCPU(CPU, Memory, CPUSpeed, false)
|
||||
TickCPU(CPU, Memory, CPUSpeed, false, nil)
|
||||
end
|
||||
|
||||
RedrawWindow()
|
||||
RedrawWindow(UseKeyboard, RunCPU)
|
||||
|
||||
lg.setColor(1,1,1)
|
||||
lg.draw(WindowCanvas, 0, 0, 0, 2, 2)
|
||||
lg.print(CPU.c.frame)
|
||||
end
|
||||
|
||||
function love.keypressed(k)
|
||||
if k=="escape" then le.quit()
|
||||
elseif k=="t" then TickCPU(CPU, Memory, 1, true )
|
||||
elseif k=="e" then TickCPU(CPU, Memory, 1, false)
|
||||
elseif k=="r" then RunCPU = not RunCPU
|
||||
elseif k=="i" then CPU.c.irq = 1
|
||||
else KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
||||
if k=="escape" then
|
||||
UseKeyboard = not UseKeyboard
|
||||
else
|
||||
if UseKeyboard then
|
||||
KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
||||
else
|
||||
if k=="q" then le.quit()
|
||||
elseif k=="s" then TickCPU(CPU, Memory, 1, true , nil)
|
||||
elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil)
|
||||
elseif k=="o" then RunToNextInstr(cpu)
|
||||
elseif k=="r" then RunCPU = not RunCPU
|
||||
elseif k=="i" then CPU.c.irq = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function love.keyreleased(k)
|
||||
if k~="escape" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Auto-generated by gendefs.lua
|
||||
|
||||
void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; lni; }
|
||||
void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; }
|
||||
void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; }
|
||||
void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1 ); lni; }
|
||||
void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; }
|
||||
@ -73,9 +73,9 @@ void cpu_instr_51_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->
|
||||
void cpu_instr_52_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||
void cpu_instr_52_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->cf ) { jmprelt } else { lni } }
|
||||
void cpu_instr_53_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||
void cpu_instr_53_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->nz && cpu->cf) { jmprelt } else { lni } }
|
||||
void cpu_instr_53_1(struct CPU* const cpu, struct Memory* const mem) { if(cpu->nz && (!cpu->cf)) { jmprelt } else { lni } }
|
||||
void cpu_instr_54_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||
void cpu_instr_54_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->nz && !cpu->cf) { jmprelt } else { lni } }
|
||||
void cpu_instr_54_1(struct CPU* const cpu, struct Memory* const mem) { if((!cpu->nz) || cpu->cf) { jmprelt } else { lni } }
|
||||
void cpu_instr_55_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->p); lni; }
|
||||
void cpu_instr_56_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=hibyte(cpu->p); lni; }
|
||||
void cpu_instr_57_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->q); lni; }
|
||||
@ -445,6 +445,8 @@ void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg
|
||||
void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; }
|
||||
void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
|
||||
void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
|
||||
void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; }
|
||||
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; }
|
||||
void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||
|
||||
CPUInstruction CPUInstructions[256][8] = {
|
||||
@ -693,8 +695,8 @@ CPUInstruction CPUInstructions[256][8] = {
|
||||
{cpu_instr_242_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_243_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_244_0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_245_0,0,0,0,0,0,0,0},
|
||||
{cpu_instr_246_0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
|
@ -18,6 +18,7 @@ return {
|
||||
["="] = 25,
|
||||
[","] = 26,
|
||||
["."] = 27,
|
||||
["-"] = 28,
|
||||
["/"] = 29,
|
||||
["`"] = 30,
|
||||
|
||||
|
@ -6,6 +6,8 @@ run F1 1 Resume non-interrupt execution
|
||||
brk F3 1 Trigger interrupt
|
||||
irt F4 1 Return from interrupt
|
||||
nop FF 1 Do nothing
|
||||
ien F5 1 Enbale interrupts
|
||||
idi F6 1 Disable interrupts
|
||||
|
||||
16-bit Inc/Dec (I):
|
||||
inc p 12 1 P++
|
||||
@ -127,8 +129,8 @@ rts E1 3 I=*(----S)+1
|
||||
jpr imm8 31 2 I+=imm8
|
||||
jnz imm8 30 2 I+=imm8 if !Zero
|
||||
jpz imm8 32 2 I+=imm8 if Zero
|
||||
jlt imm8 33 2 I+=imm8 if !Carry
|
||||
jge imm8 34 2 I+=imm8 if Carry
|
||||
jge imm8 33 2 I+=imm8 if !Carry
|
||||
jlt imm8 34 2 I+=imm8 if Carry
|
||||
jgt imm8 35 2 I+=imm8 if !Zero & Carry
|
||||
jle imm8 36 2 I+=imm8 if Zero | !Carry
|
||||
|
||||
@ -238,7 +240,7 @@ ldq p 8E 1 Q=P
|
||||
lds p 8F 1 S=P
|
||||
ldv p 90 1 V=P
|
||||
|
||||
Opcodes used: 226/255
|
||||
Opcodes used: 228/255
|
||||
0123456789ABCDEF
|
||||
00 | C---------------
|
||||
10 | UUIIUIIUUUUUUUUU
|
||||
@ -255,4 +257,4 @@ B0 | AAAAAAAAAAAAAAAA
|
||||
C0 | BBBBBBBBBBBBWWWW
|
||||
D0 | AAAAAAAAAAAAAAAA
|
||||
E0 | MJJJJJXXXSS-----
|
||||
F0 | CCCCC----------C
|
||||
F0 | CCCCCCC--------C
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
8608
|
||||
8608 - an 8-bit data, 16-bit address, CISC architecture.
|
||||
|
||||
For a list of instructions, see instructionList.txt
|
||||
|
||||
How to use the assembler:
|
||||
1. Install bllua3 from https://notabug.org/redo/bllua3
|
||||
@ -11,4 +13,6 @@ How to use the assembler:
|
||||
You can also run the assembler from the command line to get a memory dump and disassembly in stdout, if you have lua installed:
|
||||
luajit "your_path/assembler-8608.lua" "other_path/filename.asm"
|
||||
|
||||
For a list of instructions, see instructionList.txt
|
||||
How to use the emulator:
|
||||
1. Install love2d from https://love2d.org
|
||||
2. Open a command prompt in the "emulator" folder and run "love . C:/path/filename.asm"
|
||||
|
@ -130,13 +130,15 @@ operations = {
|
||||
|
||||
instructions = {
|
||||
{ category = "Control", catlet="C" },
|
||||
{ mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; lni;"} },
|
||||
{ mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} },
|
||||
{ mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} },
|
||||
{ mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} },
|
||||
{ mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} },
|
||||
{ mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
|
||||
{ mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
|
||||
{ mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, },
|
||||
{ mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, },
|
||||
{ mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, },
|
||||
|
||||
{ category = "16-bit Inc/Dec", catlet="I" },
|
||||
{ mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} },
|
||||
@ -258,10 +260,10 @@ instructions = {
|
||||
{ mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} },
|
||||
{ mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jlt imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jge imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf) { jmprelt } else { lni }"} },
|
||||
{ mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if(!cpu.nz && !cpu.cf) { jmprelt } else { lni }"} },
|
||||
{ mnem="jge imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jlt imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} },
|
||||
{ mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(cpu.nz && (!cpu.cf)) { jmprelt } else { lni }"} },
|
||||
{ mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || cpu.cf) { jmprelt } else { lni }"} },
|
||||
|
||||
{ category = "Stack", catlet="S" },
|
||||
{ mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },
|
||||
|
Loading…
x
Reference in New Issue
Block a user