1
0
mirror of https://github.com/g012/l65.git synced 2024-05-30 23:41:31 +00:00

Added skip() to make holes in sections.

This commit is contained in:
g012 2017-09-30 14:53:27 +02:00
parent 71e6f35a3c
commit 54b5939d8d
4 changed files with 114 additions and 84 deletions

136
6502.lua
View File

@ -265,12 +265,17 @@ M.genbin = function(filler)
local sections = location.sections
table.sort(sections, function(a,b) return a.org < b.org end)
for _,section in ipairs(sections) do
assert(section.org >= #bin+of0)
for i=#bin+of0,section.org-1 do ins(bin, filler) end
local bin_offset = math.min(#bin, section.org-of0)+1
for _,instruction in ipairs(section.instructions) do
local b,f = instruction.bin,instruction.asbin
if b then mov(b,1,#b,#bin+1,bin)
elseif f then f(bin) end
local b,o = instruction.bin
if type(b) == 'function' then b,o = b(filler) end
if type(b) == 'table' then mov(b,1,#b,bin_offset,bin) bin_offset=bin_offset+#b
elseif b then bin[bin_offset]=b bin_offset=bin_offset+1 end
if o then
bin_offset=bin_offset+o
for i=#bin,bin_offset-1 do ins(bin, filler) end
end
M.size=#bin M.cycles=M.cycles+(instruction.cycles or 0)
end
end
@ -368,14 +373,22 @@ M.section = function(t)
local name = t or 'S'..id()
if (type(name) ~= 'string') then
assert(type(t) == 'table', "invalid arguments for section")
assert(type(t[1]) == 'string' and string.len(t[1]) > 0, "invalid name for section")
section=t name=t[1] section[1]=nil
if t.type == 'section' then
for _,v in ipairs(sections) do if v == t then
M.location_current = t.location
M.section_current = t
return t
end end
error("unable to find reference to section " .. (t.label or '?'))
end
section=t name=t[1] or 'S'..id() section[1]=nil
if section.offset and not section.align then error("section " .. name .. " has offset, but no align") end
end
table.insert(M.location_current.sections, section) -- TODO remove
table.insert(M.sections, section)
section.location = M.location_current
M.section_current = section
section.type = 'section'
section.id = id()
section.constraints = {}
section.instructions = {}
@ -414,7 +427,7 @@ M.label = function(name)
name = M.label_current .. name
else
M.label_current = name
label.asbin = function() M.label_current = name end
label.bin = function() M.label_current = name end
end
if symbols[name] then error("duplicate symbol: " .. name) end
symbols[name] = label
@ -443,6 +456,18 @@ M.endpage = function()
constraint.to = #section.instructions
end
-- skip(bytes)
-- Insert a hole in the section of 'bytes' bytes, which can be used by other
-- relocatable sections.
M.skip = function(bytes)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() return bytes end
local bin = function(filler) return nil,bytes end
table.insert(M.section_current.instructions, { size=size, bin=bin })
end
-- sleep(cycles [, noillegal])
-- Waste 'cycles' cycles. If 'noillegal' is true, trashes NZ flags.
M.sleep = function(cycles, noillegal)
assert(cycles > 1, "can't sleep for less than 2 cycles")
if cycles & 1 ~= 0 then
@ -537,7 +562,8 @@ M.byte_impl = function(args, nrm)
for i,v in ipairs(data) do data[i] = size_dc(v) end
return #data
end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local b={}
for k,v in ipairs(data) do
if type(v) == 'function' then v = v() end
local vt = type(v)
@ -546,8 +572,9 @@ M.byte_impl = function(args, nrm)
if type(v) ~= 'number' then error("unresolved symbol for dc.b, index " .. k) end
b[#b+1] = nrm(v)
end
return b
end
table.insert(M.section_current.instructions, { data=data, size=size, asbin=asbin })
table.insert(M.section_current.instructions, { data=data, size=size, bin=bin })
end
-- byte(...)
-- Declare bytes to go into the binary stream.
@ -602,7 +629,8 @@ M.word = function(...)
for i,v in ipairs(data) do data[i] = size_dc(v) end
return #data*2
end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local b={}
for k,v in ipairs(data) do
if type(v) == 'function' then v = v() end
local vt = type(v)
@ -613,8 +641,9 @@ M.word = function(...)
b[#b+1] = v&0xff
b[#b+1] = v>>8
end
return b
end
table.insert(M.section_current.instructions, { data=data, size=size, asbin=asbin })
table.insert(M.section_current.instructions, { data=data, size=size, bin=bin })
end
M.long = function(...)
@ -634,7 +663,8 @@ M.long = function(...)
for i,v in ipairs(data) do data[i] = size_dc(v) end
return #data*4
end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local b={}
for k,v in ipairs(data) do
if type(v) == 'function' then v = v() end
local vt = type(v)
@ -647,8 +677,9 @@ M.long = function(...)
b[#b+1] = (v>>16)&0xff
b[#b+1] = v>>24
end
return b
end
table.insert(M.section_current.instructions, { data=data, size=size, asbin=asbin })
table.insert(M.section_current.instructions, { data=data, size=size, bin=bin })
end
local op,cycles_def,xcross_def
@ -670,8 +701,7 @@ cycles_def=2 xcross_def=0 local opimp={
} M.opimp = opimp
for k,v in pairs(opimp) do
M[k .. 'imp'] = function()
local asbin = function(b) b[#b+1] = v.opc end
table.insert(M.section_current.instructions, { size=1, cycles=v.cycles, asbin=asbin })
table.insert(M.section_current.instructions, { size=1, cycles=v.cycles, bin=v.opc })
end
end
cycles_def=2 xcross_def=0 local opimm={
@ -683,8 +713,8 @@ for k,v in pairs(opimm) do
M[k .. 'imm'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=2, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=2, bin=bin })
end
end
cycles_def=3 xcross_def=0 local opzpg={
@ -698,8 +728,8 @@ for k,v in pairs(opzpg) do
M[k .. 'zpg'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
cycles_def=4 xcross_def=0 local opabs={
@ -713,11 +743,11 @@ for k,v in pairs(opabs) do
M[k .. 'abs'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { v.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
local opzab={} M.opabs = opabs
@ -742,18 +772,18 @@ for k,_ in pairs(opzab) do
if x <= 0xff and zpg then
ins.size = 2
ins.cycles = zpg.cycles
ins.asbin = function(b) b[#b+1]=zpg.opc b[#b+1]=x end
ins.bin = function() return { zpg.opc, x } end
return 2
end
ins.size = 3
ins.asbin = function(b) b[#b+1]=abs.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
ins.bin = function() return { abs.opc, x&0xff, x>>8 } end
return 3
end
ins.asbin = function(b) local l65dbg=l65dbg
ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpg[k] then print("warning: forcing abs on zpg operand for opcode " .. k) end
b[#b+1]=abs.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { abs.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, ins)
end
@ -767,8 +797,8 @@ for k,v in pairs(opzpx) do
M[k .. 'zpx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
cycles_def=4 xcross_def=1 local opabx={
@ -781,11 +811,11 @@ for k,v in pairs(opabx) do
M[k .. 'abx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { v.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
local opzax={} M.opabx = opabx
@ -810,18 +840,18 @@ for k,_ in pairs(opzax) do
if x <= 0xff and zpx then
ins.size = 2
ins.cycles = zpx.cycles
ins.asbin = function(b) b[#b+1]=zpx.opc b[#b+1]=x end
ins.bin = function() return { zpx.opc, x } end
return 2
end
ins.size = 3
ins.asbin = function(b) b[#b+1]=abx.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
ins.bin = function() return { abx.opc, x&0xff, x>>8 } end
return 3
end
ins.asbin = function(b) local l65dbg=l65dbg
ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpx[k] then print("warning: forcing abx on zpx operand for opcode " .. k) end
b[#b+1]=abx.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { abx.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, ins)
end
@ -834,8 +864,8 @@ for k,v in pairs(opzpy) do
M[k .. 'zpy'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
cycles_def=4 xcross_def=1 local opaby={
@ -848,11 +878,11 @@ for k,v in pairs(opaby) do
M[k .. 'aby'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { v.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
local opzay={} M.opaby = opaby
@ -877,18 +907,18 @@ for k,_ in pairs(opzay) do
if x <= 0xff and zpy then
ins.size = 2
ins.cycles = zpy.cycles
ins.asbin = function(b) b[#b+1]=zpy.opc b[#b+1]=x end
ins.bin = function() return { zpy.opc, x } end
return 2
end
ins.size = 3
ins.asbin = function(b) b[#b+1]=aby.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
ins.bin = function() return { aby.opc, x&0xff, x>>8 } end
return 3
end
ins.asbin = function(b) local l65dbg=l65dbg
ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpy[k] then print("warning: forcing aby on zpy operand for opcode " .. k) end
b[#b+1]=aby.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { aby.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, ins)
end
@ -907,7 +937,7 @@ for k,v in pairs(oprel) do
label = size_dc(label)
return 2
end
op.asbin = function(b) local l65dbg=l65dbg
op.bin = function() local l65dbg=l65dbg
local x,l = label,label
if type(x) == 'function' then x=x() end
if type(x) == 'string' then
@ -917,7 +947,7 @@ for k,v in pairs(oprel) do
if type(x) ~= 'number' then error("unresolved branch target: " .. tostring(x)) end
x = x-2 - offset - rorg(section.org)
if x < -128 or x > 127 then error("branch target out of range for " .. l .. ": " .. x) end
b[#b+1]=v.opc b[#b+1]=x&0xff
return { v.opc, x&0xff }
end
table.insert(M.section_current.instructions, op)
end
@ -930,11 +960,11 @@ for k,v in pairs(opind) do
M[k .. 'ind'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 3 end
local asbin = function(b) local l65dbg=l65dbg
local bin = function() local l65dbg=l65dbg
local x = op_eval_word(late,early)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
return { v.opc, x&0xff, x>>8 }
end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
cycles_def=6 xcross_def=0 local opinx={
@ -946,8 +976,8 @@ for k,v in pairs(opinx) do
M[k .. 'inx'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end
cycles_def=5 xcross_def=1 local opiny={
@ -959,8 +989,8 @@ for k,v in pairs(opiny) do
M[k .. 'iny'] = function(late, early)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() late,early = size_op(late,early) return 2 end
local asbin = function(b) local l65dbg=l65dbg b[#b+1]=v.opc b[#b+1]=op_eval_byte(late,early) end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, asbin=asbin })
local bin = function() local l65dbg=l65dbg return { v.opc, op_eval_byte(late,early) } end
table.insert(M.section_current.instructions, { size=size, cycles=v.cycles, bin=bin })
end
end

View File

@ -9,7 +9,7 @@ end
init()
@_frame
overscan() vblank() screen(kernel) jmp _frame
;
writebin(filename..'.bin')
writesym(filename..'.sym')
print(stats)

View File

@ -26,7 +26,7 @@ local wait = function() local l=label() lda INTIM bne l end
-- kernel
lda#TIM_KERNEL sta T1024T kernel() wait()
jmp main
;
writebin(filename..'.bin')
writesym(filename..'.sym')
print(stats)

58
vcs.l65
View File

@ -84,33 +84,6 @@ do
for k,v in pairs(vcs) do symbols[k] = v end
end
NTSC = {
TIM_OVERSCAN = 38, -- TIM64T, 2432 cycles = 32 scanlines
TIM_VBLANK = 45, -- TIM64T, 2880 cycles = ~ 38 scanlines
TIM_KERNEL = 15, -- T1024T, 15360 cycles = ~202 scanlines
}
PAL = {
TIM_OVERSCAN = 50, -- TIM64T, 3200 cycles = ~ 42 scanlines
TIM_VBLANK = 61, -- TIM64T, 3904 cycles = ~ 51 scanlines
TIM_KERNEL = 17, -- T1024T, 17408 cycles = ~229 scanlines
}
TV = PAL
init = function() cld ldx#0 txa local l=label() dex tsx pha bne l end
wait = function() local l=label() lda INTIM bne l end
overscan_begin = function() sta WSYNC lda#2 sta VBLANK lda#TV.TIM_OVERSCAN sta TIM64T end
overscan_end = wait
overscan = function(f) overscan_begin() if f then f() end overscan_end() end
vblank_begin = function()
lda#0b1110 local l=label() sta WSYNC sta VSYNC lsr bne l
lda#2 sta VBLANK lda#TV.TIM_VBLANK sta TIM64T
end
vblank_end = function() wait() sta WSYNC sta VBLANK end
vblank = function(f) vblank_begin() if f then f() end vblank_end() end
screen_begin = function() lda#TV.TIM_KERNEL sta T1024T end
screen_end = wait
screen = function(f) screen_begin() if f then f() end screen_end() end
nusiz = {
MSL_SIZE_1 = 16*0,
MSL_SIZE_2 = 16*1,
@ -182,9 +155,36 @@ hm = {
C74_NO_MOTION = 8*16,
}
NTSC = {
TIM_OVERSCAN = 38, -- TIM64T, 2432 cycles = 32 scanlines
TIM_VBLANK = 45, -- TIM64T, 2880 cycles = ~ 38 scanlines
TIM_KERNEL = 15, -- T1024T, 15360 cycles = ~202 scanlines
}
PAL = {
TIM_OVERSCAN = 50, -- TIM64T, 3200 cycles = ~ 42 scanlines
TIM_VBLANK = 61, -- TIM64T, 3904 cycles = ~ 51 scanlines
TIM_KERNEL = 17, -- T1024T, 17408 cycles = ~229 scanlines
}
TV = PAL
init = function() cld ldx#0 txa local l=label() dex tsx pha bne l end
wait = function() local l=label() lda INTIM bne l end
overscan_begin = function() sta WSYNC lda#2 sta VBLANK lda#TV.TIM_OVERSCAN sta TIM64T end
overscan_end = wait
overscan = function(f) overscan_begin() if f then f() end overscan_end() end
vblank_begin = function()
lda#0b1110 local l=label() sta WSYNC sta VSYNC lsr bne l
lda#2 sta VBLANK lda#TV.TIM_VBLANK sta TIM64T
end
vblank_end = function() wait() sta WSYNC sta VBLANK end
vblank = function(f) vblank_begin() if f then f() end vblank_end() end
screen_begin = function() lda#TV.TIM_KERNEL sta T1024T end
screen_end = wait
screen = function(f) screen_begin() if f then f() end screen_end() end
-- for mappers that swap banks in place
-- call an asm function into another bank and generate the stubs if needed
local far_stubs = {} M.far_stubs=far_stubs
local far_stubs = {} far_stubs=far_stubs
local far = function(dst)
local stub,loc_src,loc_dst = far_stubs[dst],location_current,dst.section.location
if not (stub and stub.stub_caller.location==loc_src and stub.stub_callee.location==loc_dst) then
@ -192,7 +192,7 @@ local far = function(dst)
local stub_caller = section() switchrom(loc_dst.rom) skip(6) rts
location(loc_dst)
local stub_callee = section() jsr dst switchrom(loc_src.rom)
location(loc_src) section_current=seccur
section(seccur)
far_stubs[dst] = relate(stub_caller, stub_callee, 3)
end
jsr stub_caller