Browse Source

PIT emulation improvements, +5% speed bump

tags/0.1.1
asie 2 years ago
parent
commit
a7f2a50a30
4 changed files with 270 additions and 176 deletions
  1. 2
    1
      changelog.txt
  2. 125
    95
      emu_core.lua
  3. 120
    69
      emu_core_pre.lua
  4. 23
    11
      pit.lua

+ 2
- 1
changelog.txt View File

@@ -5,8 +5,9 @@
- fix backspace/down arrow key mappings in curses mode
- fix commonly used 8086/80186 CPU detection methods
- fix crash in comms.lua
- improve PIT emulation
- make BIOS ROM memory utilize "reduced memory mode"
- progress on PIT timer emulation
- minor speed bump (+5%)

0.1.0:
- add "lunatic86.lua" as a simple CLI wrapper with arguments

+ 125
- 95
emu_core.lua View File

@@ -9,10 +9,11 @@




local ram_640k = {}
local io_ports = {}
local ram_rom = {}
local run_one = nil
local opc = 0

RAM = {}
@@ -176,7 +177,7 @@ end


function segmd(s, v)
return (CPU_SEGMENTS[(CPU_SEGMOD or s)+1]<<4) + v
return (CPU_SEGMENTS[(CPU_SEGMOD or (s+1))]<<4) + v
end


@@ -308,7 +309,7 @@ end
local readrm_table = {}
for i=0,7 do readrm_table[i] = function(data, v) return CPU_REGS[v + 1] end end
for i=8,15 do readrm_table[i] = function(data, v)
return RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 8) + 1]))+1]<<4) + (_cpu_rm_addr_t[(v - 8) + 1]((data)))))
return RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 8) + 1]+1))]<<4) + (_cpu_rm_addr_t[(v - 8) + 1]((data)))))
end end
for i=16,19 do readrm_table[i] = function(data, v)
return CPU_REGS[(v & 3) + 1] & 0xFF
@@ -316,13 +317,13 @@ end end
for i=20,23 do readrm_table[i] = function(data, v)
return CPU_REGS[(v & 3) + 1] >> 8
end end
readrm_table[24] = function(data,v) return RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (data.disp))] end
readrm_table[25] = function(data,v) return RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (data.disp))) end
readrm_table[24] = function(data,v) return RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (data.disp))] end
readrm_table[25] = function(data,v) return RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (data.disp))) end
for i=26,31 do readrm_table[i] = function(data, v)
return CPU_SEGMENTS[v - 25]
end end
for i=32,39 do readrm_table[i] = function(data, v)
return RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 32) + 1]))+1]<<4) + (_cpu_rm_addr_t[(v - 32) + 1]((data))))]
return RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 32) + 1]+1))]<<4) + (_cpu_rm_addr_t[(v - 32) + 1]((data))))]
end end
readrm_table[40] = function(data, v) return data.imm & 0xFF end
readrm_table[41] = function(data, v) return data.imm & 0xFFFF end
@@ -336,7 +337,7 @@ for i=0,7 do writerm_table[i] = function(data, v, val)
CPU_REGS[v + 1] = val & 0xFFFF
end end
for i=8,15 do writerm_table[i] = function(data, v, val)
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 8) + 1]))+1]<<4) + (_cpu_rm_addr_t[(v - 8) + 1]((data)))), val)
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 8) + 1]+1))]<<4) + (_cpu_rm_addr_t[(v - 8) + 1]((data)))), val)
end end
for i=16,19 do writerm_table[i] = function(data, v, val)
local r = CPU_REGS[(v & 3) + 1]
@@ -347,16 +348,16 @@ for i=20,23 do writerm_table[i] = function(data, v, val)
CPU_REGS[(v & 3) + 1] = (r & 0x00FF) | ((val & 0xFF) << 8)
end end
writerm_table[24] = function(data, v, val)
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (data.disp))] = val & 0xFF
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (data.disp))] = val & 0xFF
end
writerm_table[25] = function(data, v, val)
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (data.disp)), val & 0xFFFF)
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (data.disp)), val & 0xFFFF)
end
for i=26,31 do writerm_table[i] = function(data, v, val)
CPU_SEGMENTS[v - 25] = val & 0xFFFF
end end
for i=32,39 do writerm_table[i] = function(data, v, val)
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 32) + 1]))+1]<<4) + (_cpu_rm_addr_t[(v - 32) + 1]((data))))] = val & 0xFF
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (_cpu_rm_seg_t[(v - 32) + 1]+1))]<<4) + (_cpu_rm_addr_t[(v - 32) + 1]((data))))] = val & 0xFF
end end
local function cpu_write_rm(data, v, val)
writerm_table[v](data, v, val)
@@ -852,13 +853,18 @@ local function cpu_xor(mrm, opc)
_cpu_uf_bit(vr, opc)
end

local function cpu_and(mrm, opc, is_test)
local function cpu_and(mrm, opc)
local v1 = cpu_read_rm(mrm, mrm.src)
local v2 = cpu_read_rm(mrm, mrm.dst)
local vr = v1 & v2
cpu_write_rm(mrm, mrm.dst, vr)
_cpu_uf_bit(vr, opc)
end

local function cpu_test(mrm, opc)
local v1 = cpu_read_rm(mrm, mrm.src)
local v2 = cpu_read_rm(mrm, mrm.dst)
local vr = v1 & v2
if not is_test then
cpu_write_rm(mrm, mrm.dst, vr)
end
_cpu_uf_bit(vr, opc)
end

@@ -1085,7 +1091,7 @@ for i=0x21,0x25 do opcode_map[i] = opcode_map[0x20] end

-- ES:
opcode_map[0x26] = function(opcode)
CPU_SEGMOD = SEG_ES
CPU_SEGMOD = 1
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1119,7 +1125,7 @@ for i=0x29,0x2D do opcode_map[i] = opcode_map[0x28] end

-- CS:
opcode_map[0x2E] = function(opcode)
CPU_SEGMOD = SEG_CS
CPU_SEGMOD = 2
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1153,7 +1159,7 @@ for i=0x31,0x35 do opcode_map[i] = opcode_map[0x30] end

-- SS:
opcode_map[0x36] = function(opcode)
CPU_SEGMOD = SEG_SS
CPU_SEGMOD = 3
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1179,7 +1185,7 @@ for i=0x39,0x3D do opcode_map[i] = opcode_map[0x38] end

-- DS:
opcode_map[0x3E] = function(opcode)
CPU_SEGMOD = SEG_DS
CPU_SEGMOD = 4
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1203,28 +1209,44 @@ opcode_map[0x3F] = function(opcode)
end

-- INC
opcode_map[0x40] = function(opcode)
local v = CPU_REGS[(opcode & 0x07) + 1]
v = (v + 1) & 0xFFFF
CPU_REGS[(opcode & 0x07) + 1] = v
_cpu_uf_inc(v, 1)
end
for i=0x41,0x47 do opcode_map[i] = opcode_map[0x40] end

opcode_map[(0x40)] = function(opcode) local v = CPU_REGS[(1)]; v = (v + 1) & 0xFFFF; CPU_REGS[(1)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x41)] = function(opcode) local v = CPU_REGS[(2)]; v = (v + 1) & 0xFFFF; CPU_REGS[(2)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x42)] = function(opcode) local v = CPU_REGS[(3)]; v = (v + 1) & 0xFFFF; CPU_REGS[(3)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x43)] = function(opcode) local v = CPU_REGS[(4)]; v = (v + 1) & 0xFFFF; CPU_REGS[(4)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x44)] = function(opcode) local v = CPU_REGS[(5)]; v = (v + 1) & 0xFFFF; CPU_REGS[(5)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x45)] = function(opcode) local v = CPU_REGS[(6)]; v = (v + 1) & 0xFFFF; CPU_REGS[(6)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x46)] = function(opcode) local v = CPU_REGS[(7)]; v = (v + 1) & 0xFFFF; CPU_REGS[(7)] = v; _cpu_uf_inc(v, 1) end
opcode_map[(0x47)] = function(opcode) local v = CPU_REGS[(8)]; v = (v + 1) & 0xFFFF; CPU_REGS[(8)] = v; _cpu_uf_inc(v, 1) end

-- DEC
opcode_map[0x48] = function(opcode)
local v = CPU_REGS[(opcode & 0x07) + 1]
v = (v - 1) & 0xFFFF
CPU_REGS[(opcode & 0x07) + 1] = v
_cpu_uf_dec(v, 1)
end
for i=0x49,0x4F do opcode_map[i] = opcode_map[0x48] end

opcode_map[(0x48)] = function(opcode) local v = CPU_REGS[(1)]; v = (v - 1) & 0xFFFF; CPU_REGS[(1)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x49)] = function(opcode) local v = CPU_REGS[(2)]; v = (v - 1) & 0xFFFF; CPU_REGS[(2)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4A)] = function(opcode) local v = CPU_REGS[(3)]; v = (v - 1) & 0xFFFF; CPU_REGS[(3)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4B)] = function(opcode) local v = CPU_REGS[(4)]; v = (v - 1) & 0xFFFF; CPU_REGS[(4)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4C)] = function(opcode) local v = CPU_REGS[(5)]; v = (v - 1) & 0xFFFF; CPU_REGS[(5)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4D)] = function(opcode) local v = CPU_REGS[(6)]; v = (v - 1) & 0xFFFF; CPU_REGS[(6)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4E)] = function(opcode) local v = CPU_REGS[(7)]; v = (v - 1) & 0xFFFF; CPU_REGS[(7)] = v; _cpu_uf_dec(v, 1) end
opcode_map[(0x4F)] = function(opcode) local v = CPU_REGS[(8)]; v = (v - 1) & 0xFFFF; CPU_REGS[(8)] = v; _cpu_uf_dec(v, 1) end

-- PUSH/POP
opcode_map[0x50] = function(opcode) cpu_push16(CPU_REGS[(opcode & 0x07) + 1]) end
for i=0x51,0x57 do opcode_map[i] = opcode_map[0x50] end
opcode_map[0x58] = function(opcode) CPU_REGS[(opcode & 0x07) + 1] = cpu_pop16() end
for i=0x59,0x5F do opcode_map[i] = opcode_map[0x58] end
opcode_map[0x50] = function(opcode) cpu_push16(CPU_REGS[1]) end
opcode_map[0x51] = function(opcode) cpu_push16(CPU_REGS[2]) end
opcode_map[0x52] = function(opcode) cpu_push16(CPU_REGS[3]) end
opcode_map[0x53] = function(opcode) cpu_push16(CPU_REGS[4]) end
opcode_map[0x54] = function(opcode) cpu_push16(CPU_REGS[5]) end
opcode_map[0x55] = function(opcode) cpu_push16(CPU_REGS[6]) end
opcode_map[0x56] = function(opcode) cpu_push16(CPU_REGS[7]) end
opcode_map[0x57] = function(opcode) cpu_push16(CPU_REGS[8]) end
opcode_map[0x58] = function(opcode) CPU_REGS[1] = cpu_pop16() end
opcode_map[0x59] = function(opcode) CPU_REGS[2] = cpu_pop16() end
opcode_map[0x5A] = function(opcode) CPU_REGS[3] = cpu_pop16() end
opcode_map[0x5B] = function(opcode) CPU_REGS[4] = cpu_pop16() end
opcode_map[0x5C] = function(opcode) CPU_REGS[5] = cpu_pop16() end
opcode_map[0x5D] = function(opcode) CPU_REGS[6] = cpu_pop16() end
opcode_map[0x5E] = function(opcode) CPU_REGS[7] = cpu_pop16() end
opcode_map[0x5F] = function(opcode) CPU_REGS[8] = cpu_pop16() end

if cpu_arch == "8086" or cpu_arch == "80186" then
-- PUSH SP (8086/80186 bug reproduction)
@@ -1307,14 +1329,14 @@ opcode_map[0xC9] = function(opcode)
end

opcode_map[0xA4] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
RAM[addrDst] = RAM[addrSrc]
cpu_incdec_dir(7, 1)
cpu_incdec_dir(8, 1)
end
opcode_map[0xA5] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
RAM:w16(addrDst, RAM:r16(addrSrc))
cpu_incdec_dir(7, 2)
@@ -1337,14 +1359,14 @@ end

-- OUTS Ib
opcode_map[0x6E] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
cpu_out(CPU_REGS[3], RAM[addrSrc])
cpu_incdec_dir(7, 1)
end

-- OUTS Iw
opcode_map[0x6F] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
cpu_out(CPU_REGS[3], RAM:r16(addrSrc))
cpu_incdec_dir(7, 2)
end
@@ -1379,8 +1401,8 @@ end
for i=0x81,0x83 do opcode_map[i] = opcode_map[0x80] end

-- TEST
opcode_map[0x84] = function(opcode) cpu_and(cpu_mod_rm(opcode & 0x01), opcode, true) end
opcode_map[0x85] = opcode_map[0x84]
opcode_map[0x84] = function(opcode) cpu_test(cpu_mod_rm(0), opcode) end
opcode_map[0x85] = function(opcode) cpu_test(cpu_mod_rm(1), opcode) end

-- XCHG
opcode_map[0x86] = function(opcode)
@@ -1392,8 +1414,10 @@ end
opcode_map[0x87] = opcode_map[0x86]

-- MOV mod/rm
opcode_map[0x88] = function(opcode) cpu_mov(cpu_mod_rm(opcode)) end
for i=0x89,0x8B do opcode_map[i] = opcode_map[0x88] end
opcode_map[0x88] = function(opcode) cpu_mov(cpu_mod_rm(0)) end
opcode_map[0x89] = function(opcode) cpu_mov(cpu_mod_rm(1)) end
opcode_map[0x8A] = function(opcode) cpu_mov(cpu_mod_rm(2)) end
opcode_map[0x8B] = function(opcode) cpu_mov(cpu_mod_rm(3)) end

-- MOV segment
opcode_map[0x8C] = function(opcode)
@@ -1439,9 +1463,11 @@ end

-- CWD
opcode_map[0x99] = function(opcode)
local v = 0x0000
if CPU_REGS[1] >= 0x8000 then v = 0xFFFF end
CPU_REGS[3] = v
if CPU_REGS[1] >= 0x8000 then
CPU_REGS[3] = 0xFFFF
else
CPU_REGS[3] = 0x0000
end
end


@@ -1472,37 +1498,37 @@ end
-- MOV offs->AL
opcode_map[0xA0] = function(opcode)
local addr = cpu_advance_ip16()
CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (addr))]
CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (addr))]
end

-- MOV offs->AX
opcode_map[0xA1] = function(opcode)
local addr = cpu_advance_ip16()
CPU_REGS[1] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (addr)))
CPU_REGS[1] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (addr)))
end

-- MOV AL->offs
opcode_map[0xA2] = function(opcode)
local addr = cpu_advance_ip16()
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (addr))] = CPU_REGS[1] & 0xFF
RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (addr))] = CPU_REGS[1] & 0xFF
end

-- MOV AX->offs
opcode_map[0xA3] = function(opcode)
local addr = cpu_advance_ip16()
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (addr)), CPU_REGS[1])
RAM:w16(((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (addr)), CPU_REGS[1])
end

-- MOVSB/MOVSW
opcode_map[0xA4] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
RAM[addrDst] = RAM[addrSrc]
cpu_incdec_dir(7, 1)
cpu_incdec_dir(8, 1)
end
opcode_map[0xA5] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
RAM:w16(addrDst, RAM:r16(addrSrc))
cpu_incdec_dir(7, 2)
@@ -1511,14 +1537,14 @@ end

-- CMPSB/CMPSW
opcode_map[0xA6] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
cpu_cmp(RAM[addrSrc], RAM[addrDst], opcode)
cpu_incdec_dir(7, 1)
cpu_incdec_dir(8, 1)
end
opcode_map[0xA7] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
local addrDst = ((CPU_SEGMENTS[(SEG_ES)+1]<<4)+(CPU_REGS[8]))
cpu_cmp(RAM:r16(addrSrc), RAM:r16(addrDst), opcode)
cpu_incdec_dir(7, 2)
@@ -1526,9 +1552,9 @@ opcode_map[0xA7] = function(opcode)
end

-- TEST AL, imm8
opcode_map[0xA8] = function(opcode) cpu_and({src=40,dst=16,imm=cpu_advance_ip()}, 0, true) end
opcode_map[0xA8] = function(opcode) cpu_test({src=40,dst=16,imm=cpu_advance_ip()}, 0) end
-- TEST AX, imm16
opcode_map[0xA9] = function(opcode) cpu_and({src=41,dst=0,imm=cpu_advance_ip16()}, 1, true) end
opcode_map[0xA9] = function(opcode) cpu_test({src=41,dst=0,imm=cpu_advance_ip16()}, 1) end

-- STOSB/STOSW
opcode_map[0xAA] = function(opcode)
@@ -1544,12 +1570,12 @@ end

-- LODSB/LODSW
opcode_map[0xAC] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | RAM[addrSrc]
cpu_incdec_dir(7, 1)
end
opcode_map[0xAD] = function(opcode)
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (CPU_REGS[7]))
local addrSrc = ((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (CPU_REGS[7]))
CPU_REGS[1] = RAM:r16(addrSrc)
cpu_incdec_dir(7, 2)
end
@@ -1567,22 +1593,24 @@ opcode_map[0xAF] = function(opcode)
end

-- MOV imm8
opcode_map[0xB0] = function(opcode)
local r = opcode - 0xAF
if r >= 5 then
r = r - 4
CPU_REGS[r] = (CPU_REGS[r] & 0xFF) | ((cpu_advance_ip() & 0xFF) << 8)
else
CPU_REGS[r] = (CPU_REGS[r] & 0xFF00) | (cpu_advance_ip() & 0xFF)
end
end
for i=0xB1,0xB7 do opcode_map[i] = opcode_map[0xB0] end
opcode_map[0xB0] = function(opcode) CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB1] = function(opcode) CPU_REGS[2] = (CPU_REGS[2] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB2] = function(opcode) CPU_REGS[3] = (CPU_REGS[3] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB3] = function(opcode) CPU_REGS[4] = (CPU_REGS[4] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB4] = function(opcode) CPU_REGS[1] = (CPU_REGS[1] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB5] = function(opcode) CPU_REGS[2] = (CPU_REGS[2] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB6] = function(opcode) CPU_REGS[3] = (CPU_REGS[3] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB7] = function(opcode) CPU_REGS[4] = (CPU_REGS[4] & 0xFF) | (cpu_advance_ip() << 8) end

-- MOV imm16
opcode_map[0xB8] = function(opcode)
CPU_REGS[opcode - 0xB7] = cpu_advance_ip16()
end
for i=0xB9,0xBF do opcode_map[i] = opcode_map[0xB8] end
opcode_map[0xB8] = function(opcode) CPU_REGS[1] = cpu_advance_ip16() end
opcode_map[0xB9] = function(opcode) CPU_REGS[2] = cpu_advance_ip16() end
opcode_map[0xBA] = function(opcode) CPU_REGS[3] = cpu_advance_ip16() end
opcode_map[0xBB] = function(opcode) CPU_REGS[4] = cpu_advance_ip16() end
opcode_map[0xBC] = function(opcode) CPU_REGS[5] = cpu_advance_ip16() end
opcode_map[0xBD] = function(opcode) CPU_REGS[6] = cpu_advance_ip16() end
opcode_map[0xBE] = function(opcode) CPU_REGS[7] = cpu_advance_ip16() end
opcode_map[0xBF] = function(opcode) CPU_REGS[8] = cpu_advance_ip16() end

-- RET near + pop
opcode_map[0xC2] = function(opcode)
@@ -1601,22 +1629,24 @@ opcode_map[0xC4] = function(opcode)
local mrm = cpu_mod_rm(3)
local addr = cpu_addr_rm(mrm, mrm.src)
local defseg = cpu_seg_rm(mrm, mrm.src)
cpu_write_rm(mrm, mrm.dst, RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg))+1]<<4) + (addr))))
cpu_write_rm(mrm, mrm.dst, RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg+1))]<<4) + (addr))))
if opcode == 0xC5 then
CPU_SEGMENTS[4] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg))+1]<<4) + (addr + 2)))
CPU_SEGMENTS[4] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg+1))]<<4) + (addr + 2)))
else
CPU_SEGMENTS[1] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg))+1]<<4) + (addr + 2)))
CPU_SEGMENTS[1] = RAM:r16(((CPU_SEGMENTS[(CPU_SEGMOD or (defseg+1))]<<4) + (addr + 2)))
end
end
opcode_map[0xC5] = opcode_map[0xC4]

-- MOV imm(rm)
opcode_map[0xC6] = function(opcode)
local mrm = cpu_mod_rm(opcode ~ 0x02)
if opcode == 0xC6 then cpu_write_rm(mrm, mrm.dst, cpu_advance_ip())
else cpu_write_rm(mrm, mrm.dst, cpu_advance_ip16()) end
local mrm = cpu_mod_rm(0)
cpu_write_rm(mrm, mrm.dst, cpu_advance_ip())
end
opcode_map[0xC7] = function(opcode)
local mrm = cpu_mod_rm(1)
cpu_write_rm(mrm, mrm.dst, cpu_advance_ip16())
end
opcode_map[0xC7] = opcode_map[0xC6]

-- RET far + pop
opcode_map[0xCA] = function(opcode)
@@ -1671,7 +1701,6 @@ local grp2_table = {
opcode_map[0xD0] = function(opcode)
local mrm = cpu_mod_rm_copy(opcode & 0x01)
local v = mrm.src & 0x07

if (opcode & 0xFE) == 0xC0 then -- C0/C1 - imm8
mrm.src = 40
@@ -1726,7 +1755,7 @@ end
-- XLAT
opcode_map[0xD7] = function(opcode)
local addr = (CPU_REGS[4] + (CPU_REGS[1] & 0xFF)) & 0xFFFF
CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (SEG_DS))+1]<<4) + (addr))]
CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | RAM[((CPU_SEGMENTS[(CPU_SEGMOD or (4))]<<4) + (addr))]
end

-- LOOPNZ r8
@@ -1868,7 +1897,7 @@ opcode_map[0xF6] = function(opcode)
mrm.src = 40
mrm.imm = cpu_advance_ip()
end
cpu_and(mrm, opcode, true)
cpu_test(mrm, opcode)
elseif v == 2 then -- NOT
if (opcode & 0x01) == 1 then
cpu_write_rm(mrm, mrm.dst, cpu_read_rm(mrm, mrm.dst) ~ 0xFFFF)
@@ -1942,7 +1971,7 @@ opcode_map[0xFF] = function(opcode)
cpu_push16(CPU_IP)
CPU_IP = newIp
elseif v == 3 then -- CALL far abs
local addr = ((CPU_SEGMENTS[(CPU_SEGMOD or (cpu_seg_rm(mrm,mrm.dst)))+1]<<4) + (cpu_addr_rm(mrm,mrm.dst)))
local addr = ((CPU_SEGMENTS[(CPU_SEGMOD or (cpu_seg_rm(mrm,mrm.dst)+1))]<<4) + (cpu_addr_rm(mrm,mrm.dst)))
local newIp = RAM:r16(addr)
local newCs = RAM:r16(addr+2)
cpu_push16(CPU_SEGMENTS[2])
@@ -1952,7 +1981,7 @@ opcode_map[0xFF] = function(opcode)
elseif v == 4 then -- JMP near abs
CPU_IP = cpu_read_rm(mrm,mrm.dst)
elseif v == 5 then -- JMP far
local addr = ((CPU_SEGMENTS[(CPU_SEGMOD or (cpu_seg_rm(mrm,mrm.dst)))+1]<<4) + (cpu_addr_rm(mrm,mrm.dst)))
local addr = ((CPU_SEGMENTS[(CPU_SEGMOD or (cpu_seg_rm(mrm,mrm.dst)+1))]<<4) + (cpu_addr_rm(mrm,mrm.dst)))
local newIp = RAM:r16(addr)
local newCs = RAM:r16(addr+2)
CPU_IP = newIp
@@ -1975,7 +2004,12 @@ if cpu_arch == "8086" then
opcode_map[0xC9] = opcode_map[0xCB]
end

function run_one(no_interrupting, pr_state)





run_one = function(no_interrupting, pr_state)
if not no_interrupting and (#CPU_INTQUEUE > 0) then
-- local intr = table.remove(CPU_INTQUEUE, 1)
local intr = CPU_INTQUEUE[1]
@@ -2009,6 +2043,9 @@ function run_one(no_interrupting, pr_state)

local om = opcode_map[opcode]




if om ~= nil then
local result = om(opcode)
if result ~= nil then
@@ -2077,13 +2114,11 @@ end

local oc_tick_i = 0

local last_pit_clock = clock

local function upd_tick(cv)
local last_clock = clock
clock = cv

upd_count(last_clock)

-- handle pc speaker
if (kbd_get_spkr_latch() & 0x03) == 0x03 then
@@ -2096,8 +2131,7 @@ local function upd_tick(cv)
-- handle video
video_update()
keyboard_update()
pit_tick(last_pit_clock, clock)
last_pit_clock = clock
pit_tick(clock)
-- handle OC waits
cv = os.clock()
if (cv - clock) < 0.05 then
@@ -2107,12 +2141,6 @@ local function upd_tick(cv)
-- end
end
clock = cv
-- handle interrupt
for i=last_clock,clock,0.05 do
if pic_interrupt_enabled(PIC_INTERRUPT_TIMER) then
cpu_emit_interrupt(0x08, false)
end
end
end

local function cpu_execute()

+ 120
- 69
emu_core_pre.lua View File

@@ -1,11 +1,12 @@
// #define DEBUG_IO
// #define DEBUG_INTRS
// #define DEBUG_IPS
#define DEBUG_IPS
// #define DEBUG_OPC_CALLS
// #define DEBUG_MEM_UNINITIALIZED
local ram_640k = {}
local io_ports = {}
local ram_rom = {}
local run_one = nil
local opc = 0

RAM = {}
@@ -169,9 +170,9 @@ end
#define seg(s, v) ((CPU_SEGMENTS[(s)+1]<<4)+(v))

function segmd(s, v)
return (CPU_SEGMENTS[(CPU_SEGMOD or s)+1]<<4) + v
return (CPU_SEGMENTS[(CPU_SEGMOD or (s+1))]<<4) + v
end
#define segmd(s, v) ((CPU_SEGMENTS[(CPU_SEGMOD or (s))+1]<<4) + (v))
#define segmd(s, v) ((CPU_SEGMENTS[(CPU_SEGMOD or (s+1))]<<4) + (v))

local function cpu_advance_ip()
local ip = seg(SEG_CS, CPU_IP)
@@ -845,13 +846,18 @@ local function cpu_xor(mrm, opc)
_cpu_uf_bit(vr, opc)
end

local function cpu_and(mrm, opc, is_test)
local function cpu_and(mrm, opc)
local v1 = cpu_read_rm(mrm, mrm.src)
local v2 = cpu_read_rm(mrm, mrm.dst)
local vr = v1 & v2
cpu_write_rm(mrm, mrm.dst, vr)
_cpu_uf_bit(vr, opc)
end

local function cpu_test(mrm, opc)
local v1 = cpu_read_rm(mrm, mrm.src)
local v2 = cpu_read_rm(mrm, mrm.dst)
local vr = v1 & v2
if not is_test then
cpu_write_rm(mrm, mrm.dst, vr)
end
_cpu_uf_bit(vr, opc)
end

@@ -1078,7 +1084,7 @@ for i=0x21,0x25 do opcode_map[i] = opcode_map[0x20] end

-- ES:
opcode_map[0x26] = function(opcode)
CPU_SEGMOD = SEG_ES
CPU_SEGMOD = SEG_ES+1
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1112,7 +1118,7 @@ for i=0x29,0x2D do opcode_map[i] = opcode_map[0x28] end

-- CS:
opcode_map[0x2E] = function(opcode)
CPU_SEGMOD = SEG_CS
CPU_SEGMOD = SEG_CS+1
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1146,7 +1152,7 @@ for i=0x31,0x35 do opcode_map[i] = opcode_map[0x30] end

-- SS:
opcode_map[0x36] = function(opcode)
CPU_SEGMOD = SEG_SS
CPU_SEGMOD = SEG_SS+1
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1172,7 +1178,7 @@ for i=0x39,0x3D do opcode_map[i] = opcode_map[0x38] end

-- DS:
opcode_map[0x3E] = function(opcode)
CPU_SEGMOD = SEG_DS
CPU_SEGMOD = SEG_DS+1
local r = run_one(true, true)
CPU_SEGMOD = nil
return r
@@ -1196,28 +1202,58 @@ opcode_map[0x3F] = function(opcode)
end

-- INC
opcode_map[0x40] = function(opcode)
local v = CPU_REGS[(opcode & 0x07) + 1]
v = (v + 1) & 0xFFFF
CPU_REGS[(opcode & 0x07) + 1] = v
_cpu_uf_inc(v, 1)
end
for i=0x41,0x47 do opcode_map[i] = opcode_map[0x40] end
#define INC_MACRO(a, b) \
opcode_map[(a)] = function(opcode) \
local v = CPU_REGS[(b)]; \
v = (v + 1) & 0xFFFF; \
CPU_REGS[(b)] = v; \
_cpu_uf_inc(v, 1) \
end

INC_MACRO(0x40, 1)
INC_MACRO(0x41, 2)
INC_MACRO(0x42, 3)
INC_MACRO(0x43, 4)
INC_MACRO(0x44, 5)
INC_MACRO(0x45, 6)
INC_MACRO(0x46, 7)
INC_MACRO(0x47, 8)

-- DEC
opcode_map[0x48] = function(opcode)
local v = CPU_REGS[(opcode & 0x07) + 1]
v = (v - 1) & 0xFFFF
CPU_REGS[(opcode & 0x07) + 1] = v
_cpu_uf_dec(v, 1)
end
for i=0x49,0x4F do opcode_map[i] = opcode_map[0x48] end
#define DEC_MACRO(a, b) \
opcode_map[(a)] = function(opcode) \
local v = CPU_REGS[(b)]; \
v = (v - 1) & 0xFFFF; \
CPU_REGS[(b)] = v; \
_cpu_uf_dec(v, 1) \
end

DEC_MACRO(0x48, 1)
DEC_MACRO(0x49, 2)
DEC_MACRO(0x4A, 3)
DEC_MACRO(0x4B, 4)
DEC_MACRO(0x4C, 5)
DEC_MACRO(0x4D, 6)
DEC_MACRO(0x4E, 7)
DEC_MACRO(0x4F, 8)

-- PUSH/POP
opcode_map[0x50] = function(opcode) cpu_push16(CPU_REGS[(opcode & 0x07) + 1]) end
for i=0x51,0x57 do opcode_map[i] = opcode_map[0x50] end
opcode_map[0x58] = function(opcode) CPU_REGS[(opcode & 0x07) + 1] = cpu_pop16() end
for i=0x59,0x5F do opcode_map[i] = opcode_map[0x58] end
opcode_map[0x50] = function(opcode) cpu_push16(CPU_REGS[1]) end
opcode_map[0x51] = function(opcode) cpu_push16(CPU_REGS[2]) end
opcode_map[0x52] = function(opcode) cpu_push16(CPU_REGS[3]) end
opcode_map[0x53] = function(opcode) cpu_push16(CPU_REGS[4]) end
opcode_map[0x54] = function(opcode) cpu_push16(CPU_REGS[5]) end
opcode_map[0x55] = function(opcode) cpu_push16(CPU_REGS[6]) end
opcode_map[0x56] = function(opcode) cpu_push16(CPU_REGS[7]) end
opcode_map[0x57] = function(opcode) cpu_push16(CPU_REGS[8]) end
opcode_map[0x58] = function(opcode) CPU_REGS[1] = cpu_pop16() end
opcode_map[0x59] = function(opcode) CPU_REGS[2] = cpu_pop16() end
opcode_map[0x5A] = function(opcode) CPU_REGS[3] = cpu_pop16() end
opcode_map[0x5B] = function(opcode) CPU_REGS[4] = cpu_pop16() end
opcode_map[0x5C] = function(opcode) CPU_REGS[5] = cpu_pop16() end
opcode_map[0x5D] = function(opcode) CPU_REGS[6] = cpu_pop16() end
opcode_map[0x5E] = function(opcode) CPU_REGS[7] = cpu_pop16() end
opcode_map[0x5F] = function(opcode) CPU_REGS[8] = cpu_pop16() end

if cpu_arch == "8086" or cpu_arch == "80186" then
-- PUSH SP (8086/80186 bug reproduction)
@@ -1372,8 +1408,8 @@ end
for i=0x81,0x83 do opcode_map[i] = opcode_map[0x80] end

-- TEST
opcode_map[0x84] = function(opcode) cpu_and(cpu_mod_rm(opcode & 0x01), opcode, true) end
opcode_map[0x85] = opcode_map[0x84]
opcode_map[0x84] = function(opcode) cpu_test(cpu_mod_rm(0), opcode) end
opcode_map[0x85] = function(opcode) cpu_test(cpu_mod_rm(1), opcode) end

-- XCHG
opcode_map[0x86] = function(opcode)
@@ -1385,8 +1421,10 @@ end
opcode_map[0x87] = opcode_map[0x86]

-- MOV mod/rm
opcode_map[0x88] = function(opcode) cpu_mov(cpu_mod_rm(opcode)) end
for i=0x89,0x8B do opcode_map[i] = opcode_map[0x88] end
opcode_map[0x88] = function(opcode) cpu_mov(cpu_mod_rm(0)) end
opcode_map[0x89] = function(opcode) cpu_mov(cpu_mod_rm(1)) end
opcode_map[0x8A] = function(opcode) cpu_mov(cpu_mod_rm(2)) end
opcode_map[0x8B] = function(opcode) cpu_mov(cpu_mod_rm(3)) end

-- MOV segment
opcode_map[0x8C] = function(opcode)
@@ -1432,9 +1470,11 @@ end

-- CWD
opcode_map[0x99] = function(opcode)
local v = 0x0000
if CPU_REGS[1] >= 0x8000 then v = 0xFFFF end
CPU_REGS[3] = v
if CPU_REGS[1] >= 0x8000 then
CPU_REGS[3] = 0xFFFF
else
CPU_REGS[3] = 0x0000
end
end


@@ -1519,9 +1559,9 @@ opcode_map[0xA7] = function(opcode)
end

-- TEST AL, imm8
opcode_map[0xA8] = function(opcode) cpu_and({src=40,dst=16,imm=cpu_advance_ip()}, 0, true) end
opcode_map[0xA8] = function(opcode) cpu_test({src=40,dst=16,imm=cpu_advance_ip()}, 0) end
-- TEST AX, imm16
opcode_map[0xA9] = function(opcode) cpu_and({src=41,dst=0,imm=cpu_advance_ip16()}, 1, true) end
opcode_map[0xA9] = function(opcode) cpu_test({src=41,dst=0,imm=cpu_advance_ip16()}, 1) end

-- STOSB/STOSW
opcode_map[0xAA] = function(opcode)
@@ -1560,22 +1600,24 @@ opcode_map[0xAF] = function(opcode)
end

-- MOV imm8
opcode_map[0xB0] = function(opcode)
local r = opcode - 0xAF
if r >= 5 then
r = r - 4
CPU_REGS[r] = (CPU_REGS[r] & 0xFF) | ((cpu_advance_ip() & 0xFF) << 8)
else
CPU_REGS[r] = (CPU_REGS[r] & 0xFF00) | (cpu_advance_ip() & 0xFF)
end
end
for i=0xB1,0xB7 do opcode_map[i] = opcode_map[0xB0] end
opcode_map[0xB0] = function(opcode) CPU_REGS[1] = (CPU_REGS[1] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB1] = function(opcode) CPU_REGS[2] = (CPU_REGS[2] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB2] = function(opcode) CPU_REGS[3] = (CPU_REGS[3] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB3] = function(opcode) CPU_REGS[4] = (CPU_REGS[4] & 0xFF00) | (cpu_advance_ip()) end
opcode_map[0xB4] = function(opcode) CPU_REGS[1] = (CPU_REGS[1] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB5] = function(opcode) CPU_REGS[2] = (CPU_REGS[2] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB6] = function(opcode) CPU_REGS[3] = (CPU_REGS[3] & 0xFF) | (cpu_advance_ip() << 8) end
opcode_map[0xB7] = function(opcode) CPU_REGS[4] = (CPU_REGS[4] & 0xFF) | (cpu_advance_ip() << 8) end

-- MOV imm16
opcode_map[0xB8] = function(opcode)
CPU_REGS[opcode - 0xB7] = cpu_advance_ip16()
end
for i=0xB9,0xBF do opcode_map[i] = opcode_map[0xB8] end
opcode_map[0xB8] = function(opcode) CPU_REGS[1] = cpu_advance_ip16() end
opcode_map[0xB9] = function(opcode) CPU_REGS[2] = cpu_advance_ip16() end
opcode_map[0xBA] = function(opcode) CPU_REGS[3] = cpu_advance_ip16() end
opcode_map[0xBB] = function(opcode) CPU_REGS[4] = cpu_advance_ip16() end
opcode_map[0xBC] = function(opcode) CPU_REGS[5] = cpu_advance_ip16() end
opcode_map[0xBD] = function(opcode) CPU_REGS[6] = cpu_advance_ip16() end
opcode_map[0xBE] = function(opcode) CPU_REGS[7] = cpu_advance_ip16() end
opcode_map[0xBF] = function(opcode) CPU_REGS[8] = cpu_advance_ip16() end

-- RET near + pop
opcode_map[0xC2] = function(opcode)
@@ -1605,11 +1647,13 @@ opcode_map[0xC5] = opcode_map[0xC4]

-- MOV imm(rm)
opcode_map[0xC6] = function(opcode)
local mrm = cpu_mod_rm(opcode ~ 0x02)
if opcode == 0xC6 then cpu_write_rm(mrm, mrm.dst, cpu_advance_ip())
else cpu_write_rm(mrm, mrm.dst, cpu_advance_ip16()) end
local mrm = cpu_mod_rm(0)
cpu_write_rm(mrm, mrm.dst, cpu_advance_ip())
end
opcode_map[0xC7] = function(opcode)
local mrm = cpu_mod_rm(1)
cpu_write_rm(mrm, mrm.dst, cpu_advance_ip16())
end
opcode_map[0xC7] = opcode_map[0xC6]

-- RET far + pop
opcode_map[0xCA] = function(opcode)
@@ -1664,7 +1708,6 @@ local grp2_table = {
opcode_map[0xD0] = function(opcode)
local mrm = cpu_mod_rm_copy(opcode & 0x01)
local v = mrm.src & 0x07
-- emu_debug(0, "GRP2/"..v)

if (opcode & 0xFE) == 0xC0 then -- C0/C1 - imm8
mrm.src = 40
@@ -1861,7 +1904,7 @@ opcode_map[0xF6] = function(opcode)
mrm.src = 40
mrm.imm = cpu_advance_ip()
end
cpu_and(mrm, opcode, true)
cpu_test(mrm, opcode)
elseif v == 2 then -- NOT
if (opcode & 0x01) == 1 then
cpu_write_rm(mrm, mrm.dst, cpu_read_rm(mrm, mrm.dst) ~ 0xFFFF)
@@ -1968,7 +2011,12 @@ if cpu_arch == "8086" then
opcode_map[0xC9] = opcode_map[0xCB]
end

function run_one(no_interrupting, pr_state)
#ifdef DEBUG_OPC_CALLS
local opc_calls = {}
for i=0,255 do opc_calls[i] = 0 end
#endif

run_one = function(no_interrupting, pr_state)
if not no_interrupting and (#CPU_INTQUEUE > 0) then
-- local intr = table.remove(CPU_INTQUEUE, 1)
local intr = CPU_INTQUEUE[1]
@@ -2001,6 +2049,9 @@ function run_one(no_interrupting, pr_state)
-- if pr_state then cpu_print_state(opcode) end

local om = opcode_map[opcode]
#ifdef DEBUG_OPC_CALLS
opc_calls[opcode] = opc_calls[opcode] + 1
#endif

if om ~= nil then
local result = om(opcode)
@@ -2070,13 +2121,19 @@ end

local oc_tick_i = 0

local last_pit_clock = clock

local function upd_tick(cv)
local last_clock = clock
clock = cv
#ifdef DEBUG_IPS
upd_count(last_clock)
#endif
#ifdef DEBUG_OPC_CALLS
for i=0,255 do
if opc_calls[i] > 0 then
emu_debug(2, "opcode " .. i .. ": " .. opc_calls[i])
opc_calls[i] = 0
end
end
#endif
-- handle pc speaker
if (kbd_get_spkr_latch() & 0x03) == 0x03 then
@@ -2089,8 +2146,7 @@ local function upd_tick(cv)
-- handle video
video_update()
keyboard_update()
pit_tick(last_pit_clock, clock)
last_pit_clock = clock
pit_tick(clock)
-- handle OC waits
cv = os.clock()
if (cv - clock) < 0.05 then
@@ -2100,12 +2156,6 @@ local function upd_tick(cv)
-- end
end
clock = cv
-- handle interrupt
for i=last_clock,clock,0.05 do
if pic_interrupt_enabled(PIC_INTERRUPT_TIMER) then
cpu_emit_interrupt(0x08, false)
end
end
end

local function cpu_execute()

+ 23
- 11
pit.lua View File

@@ -14,9 +14,10 @@ local function pit_init(c,first)
channels[c] = {
mode=3,
addr_mode=3,
reload=0xFFFF,
reload=0x10000,
reload_set_lo=false,
reload_set_hi=false,
bcd=false,
paused=false,
count=0
}
@@ -24,8 +25,15 @@ end

-- THIS IS REALLY INACCURATE OKAY
-- but that is fine as we're not using it right now anyway
function pit_tick(last_t, curr_t)
local osc_count = math.floor((curr_t - last_t) * 1000000 * pit_osc_freq)
local pit_last_tick = -1

function pit_tick(curr_t)
if pit_last_tick == -1 then
pit_last_tick = curr_t
return
end
local osc_count = math.floor((curr_t - pit_last_tick) * 1000000 * pit_osc_freq)
pit_last_tick = curr_t
for c=1,3 do
local trig=0
local ch=channels[c]
@@ -44,7 +52,7 @@ function pit_tick(last_t, curr_t)
ch.count = 0
ch.paused = true
end
elseif (ch.mode == 2 or ch.mode == 3) and ch_ready then
elseif (ch.mode == 2 or ch.mode == 3 or ch.mode == 6 or ch.mode == 7) and ch_ready then
emu_debug(2, "PIT " .. ch.count .. " -> " .. (ch.count - osc_count))
ch.count = ch.count - osc_count
while ch.count < 0 do
@@ -65,8 +73,8 @@ local access_lohi = false
local function pit_data(n) return function(cond, val)
local ch = channels[n]
if not val then
emu_debug(2, "PIT read data " .. n)
if ch.addr_mode == 3 then
emu_debug(2, "PIT read data " .. n .. " mode " .. ch.addr_mode)
if (ch.addr_mode == 3) or (ch.addr_mode == 0) then
access_lohi = not access_lohi
if access_lohi then
return ch.count & 0xFF
@@ -81,7 +89,7 @@ local function pit_data(n) return function(cond, val)
return 0x00 -- TODO
end
else
emu_debug(2, "PIT write data " .. n)
emu_debug(2, "PIT write data " .. n .. " mode " .. ch.addr_mode)
if ch.addr_mode == 3 then
access_lohi = not access_lohi
if access_lohi then
@@ -98,8 +106,6 @@ local function pit_data(n) return function(cond, val)
elseif ch.addr_mode == 2 then
ch.reload = (ch.reload & 0xFF) | (val << 8)
ch.reload_set_hi = true
elseif ch.addr_mode == 0 then
-- TODO
end
end
end end
@@ -110,12 +116,16 @@ cpu_port_set(0x42, pit_data(3))
cpu_port_set(0x43, function(cond, val)
if val then
emu_debug(2, "PIT write control " .. val)
pit_tick(os.clock())
local c = (val >> 6) + 1
if c < 4 then
pit_init(c,false)
channels[c].mode = (val >> 1) & 0x07
channels[c].addr_mode = (val >> 4) & 0x03
channels[c].paused = false
if channels[c].addr_mode ~= 0 then
channels[c].mode = (val >> 1) & 0x07
channels[c].bcd = (val & 1) and true or false
channels[c].paused = false
end
access_lohi = false
end
else
@@ -128,3 +138,5 @@ pit_init(1,true)
pit_init(2,true)
pit_init(3,true)

channels[1].reload_set_lo = true
channels[1].reload_set_hi = true

Loading…
Cancel
Save