mirror of https://github.com/g012/l65.git
[NES] Revamped and tested all GxROM PRG bank switching, and added a sample.
Added asserts in 6502.lua.
This commit is contained in:
parent
c888a63ee3
commit
9c576ef774
13
.travis.yml
13
.travis.yml
|
@ -8,18 +8,7 @@ compiler:
|
||||||
script:
|
script:
|
||||||
- cmake . -DCMAKE_BUILD_TYPE=Release
|
- cmake . -DCMAKE_BUILD_TYPE=Release
|
||||||
- make
|
- make
|
||||||
- cd samples
|
- cd samples; for f in *.l65; do echo $f; ../l65 $f || break; done; cd ..
|
||||||
- ../l65 vcs_banks.l65
|
|
||||||
- ../l65 vcs_basic.l65
|
|
||||||
- ../l65 vcs_flush.l65
|
|
||||||
- ../l65 vcs_hello.l65
|
|
||||||
- ../l65 vcs_hooks.l65
|
|
||||||
- ../l65 vcs_music.l65
|
|
||||||
- ../l65 vcs_mcart.l65
|
|
||||||
- ../l65 vcs_spr48.l65
|
|
||||||
- ../l65 nes_hello.l65
|
|
||||||
- ../l65 nes_bank1.l65
|
|
||||||
- cd ..
|
|
||||||
- cp l65 l65-$TRAVIS_TAG-$TRAVIS_OS_NAME
|
- cp l65 l65-$TRAVIS_TAG-$TRAVIS_OS_NAME
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
|
|
2
6502.lua
2
6502.lua
|
@ -515,6 +515,8 @@ end
|
||||||
-- -ted positon for 'section1'.
|
-- -ted positon for 'section1'.
|
||||||
-- If offset1 is omitted, -offset2 is used.
|
-- If offset1 is omitted, -offset2 is used.
|
||||||
M.relate = function(section1, section2, offset, offset2)
|
M.relate = function(section1, section2, offset, offset2)
|
||||||
|
assert(section1.type == 'section', "section1 is not a section")
|
||||||
|
assert(section2.type == 'section', "section2 is not a section")
|
||||||
local rel1 = relations[section1] or {}
|
local rel1 = relations[section1] or {}
|
||||||
rel1[section2] = (offset2 or offset) or 0
|
rel1[section2] = (offset2 or offset) or 0
|
||||||
relations[section1] = rel1
|
relations[section1] = rel1
|
||||||
|
|
80
nes.l65
80
nes.l65
|
@ -447,18 +447,6 @@ mappers.GxROM = function(t)
|
||||||
hdrrom = location{0x7ff0, 0x7fff, name='header'}
|
hdrrom = location{0x7ff0, 0x7fff, name='header'}
|
||||||
header(t)
|
header(t)
|
||||||
local bc = t.prgsize//0x8000
|
local bc = t.prgsize//0x8000
|
||||||
for bi=0,bc-1 do
|
|
||||||
local o,ix = 0x8000 + bi*0x8000, bc-1-bi
|
|
||||||
_ENV['prgrom'..ix] = location{o, o+0x7fff, rorg=0x8000, name='prgrom'..ix}
|
|
||||||
section{"vectors"..ix, org=o+0x8000-6} dc.w nmi, main, irq
|
|
||||||
section{"bankbytes"..ix, org=o+0x8000-6-16} samepage -- for handling bus conflicts
|
|
||||||
dc.b 0x00, 0x01, 0x02, 0x03
|
|
||||||
dc.b 0x10, 0x11, 0x12, 0x13
|
|
||||||
dc.b 0x20, 0x21, 0x22, 0x23
|
|
||||||
dc.b 0x30, 0x31, 0x32, 0x33
|
|
||||||
end
|
|
||||||
end
|
|
||||||
prgrom = prgrom0
|
|
||||||
local cc = t.chrsize//0x2000
|
local cc = t.chrsize//0x2000
|
||||||
local ci, chrstart = 0, 0x8000 + bc*0x8000
|
local ci, chrstart = 0, 0x8000 + bc*0x8000
|
||||||
local chrmap = t.chrmap or function(ci) return ci*0x1000, 0x1000, (ci&1)*0x1000 end
|
local chrmap = t.chrmap or function(ci) return ci*0x1000, 0x1000, (ci&1)*0x1000 end
|
||||||
|
@ -471,38 +459,66 @@ mappers.GxROM = function(t)
|
||||||
until off + sz >= t.chrsize
|
until off + sz >= t.chrsize
|
||||||
chrrom = chrrom0
|
chrrom = chrrom0
|
||||||
-- RAM address of bank register copy, to switch using A instead of immediate
|
-- RAM address of bank register copy, to switch using A instead of immediate
|
||||||
bankregister_shadow = -1
|
|
||||||
-- if bankregister_shadow is negative, only immediate bankswitching is available
|
-- if bankregister_shadow is negative, only immediate bankswitching is available
|
||||||
bankregister = 0
|
bankregister_shadow = -1
|
||||||
-- otherwise, just set the value directly: xxPPxxCC in A, xxxxPPCC in X with sta bankbytes0,x
|
-- otherwise, just set the value directly: xxPPxxCC in A, xxxxPPCC in X with sta bankbytes0,x
|
||||||
|
function switchroms(prgbankix, chrbankix)
|
||||||
|
if prgbankix then
|
||||||
|
assert(prgbankix < bc) prgbankix = bc-1-prgbankix
|
||||||
|
assert(chrbankix, "GxROM must specify both PRG and CHR roms to switch simultaneously")
|
||||||
|
assert(chrbankix < cc)
|
||||||
|
local br = prgbankix<<4 | chrbankix
|
||||||
|
ldx #br&3|br>>2 lda #br sta bankbytes0,x
|
||||||
|
else -- A contains 00PP00CC
|
||||||
|
if bankregister_shadow >= 0 then
|
||||||
|
sta bankregister_shadow -- bankregister_shadow = 00PP00CC
|
||||||
|
lsr lsr -- A = 0000PP00, c
|
||||||
|
-- compute bc-1-prgbankix (reverse indexing)
|
||||||
|
eor #0xff adc #(bc-1<<2)+1 -- negate and +bc-1 combined, NN = bc-1-PP: A = 0000NN00
|
||||||
|
ora bankregister_shadow ;and #0xf tax -- X = 0000NNCC
|
||||||
|
else -- use stack instead
|
||||||
|
tsx sta 0x100,x lsr lsr -- A = 0000PP00, s[0] = 00PP00CC, c
|
||||||
|
-- compute bc-1-prgbankix (reverse indexing)
|
||||||
|
eor #0xff adc #(bc-1<<2)+1 -- negate and +bc-1 combined, NN = bc-1-PP: A = 0000NN00
|
||||||
|
ora 0x100,x ;and #0xf tax -- X = 0000NNCC
|
||||||
|
end
|
||||||
|
lda bankbytes0,x sta bankbytes0,x -- A = 00NN00CC, from table
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for bi=0,bc-1 do
|
||||||
|
local o,ix = 0x8000 + bi*0x8000, bc-1-bi
|
||||||
|
_ENV['prgrom'..ix] = location{o, o+0x7fff, rorg=0x8000, name='prgrom'..ix}
|
||||||
|
local start=section{"entry"..ix, org=o+0x8000-6-16-10} switchroms(0,0) if ix==0 then jmp main end
|
||||||
|
section{"vectors"..ix, org=o+0x8000-6} dc.w "nmi"..ix, start, "irq"..ix
|
||||||
|
section{"bankbytes"..ix, org=o+0x8000-6-16} samepage -- for handling bus conflicts
|
||||||
|
dc.b 0x00, 0x01, 0x02, 0x03
|
||||||
|
dc.b 0x10, 0x11, 0x12, 0x13
|
||||||
|
dc.b 0x20, 0x21, 0x22, 0x23
|
||||||
|
dc.b 0x30, 0x31, 0x32, 0x33
|
||||||
|
end
|
||||||
|
end
|
||||||
|
prgrom = prgrom0
|
||||||
function switchprgrom(bankix)
|
function switchprgrom(bankix)
|
||||||
if bankix then
|
if bankix then
|
||||||
assert(bankix < bc)
|
assert(bankix < bc)
|
||||||
bankregister = (bankregister & ~0x30) | (bankix << 4)
|
lda #bc-1-bankix
|
||||||
ldx #bankregister&3|bankregister>>2 lda #bankregister sta bankbytes0,x
|
|
||||||
else
|
else
|
||||||
assert(bankregister_shadow >= 0, "no RAM slot assigned to bankregister_shadow")
|
clc eor #0xff adc #bc -- bc-1 - A
|
||||||
tay lda bankregister_shadow ;and #3 sta bankregister_shadow
|
|
||||||
tya asl asl ora bankregister_shadow tax
|
|
||||||
;and #0xc asl asl ora bankregister_shadow sta bankregister_shadow
|
|
||||||
sta bankbytes0,x
|
|
||||||
end
|
end
|
||||||
|
assert(bankregister_shadow >= 0, "no RAM slot assigned to bankregister_shadow")
|
||||||
|
tay lda bankregister_shadow ;and #3 sta bankregister_shadow
|
||||||
|
tya asl asl ora bankregister_shadow tax
|
||||||
|
lda bankbytes0,x sta bankregister_shadow sta bankbytes0,x
|
||||||
end
|
end
|
||||||
function switchchrrom(bankix)
|
function switchchrrom(bankix)
|
||||||
if bankix then
|
if bankix then
|
||||||
assert(bankix < cc)
|
assert(bankix < cc)
|
||||||
bankregister = (bankregister & ~3) | bankix
|
lda #bankix
|
||||||
ldx #bankregister&3|bankregister>>2 lda #bankregister sta bankbytes0,x
|
|
||||||
else
|
|
||||||
assert(bankregister_shadow >= 0, "no RAM slot assigned to bankregister_shadow")
|
|
||||||
tay lda bankregister_shadow lsr lsr sta bankregister_shadow
|
|
||||||
tya ora bankregister_shadow tax ;and #0xc
|
|
||||||
asl asl sta bankregister_shadow tya ora bankregister_shadow sta bankregister_shadow
|
|
||||||
sta bankbytes0,x
|
|
||||||
end
|
end
|
||||||
end
|
assert(bankregister_shadow >= 0, "no RAM slot assigned to bankregister_shadow")
|
||||||
mappers.init = function()
|
tay lda bankregister_shadow lsr lsr sta bankregister_shadow
|
||||||
switchchrrom(0)
|
tya ora bankregister_shadow tax
|
||||||
|
lda bankbytes0,x sta bankregister_shadow sta bankbytes0,x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mappers[66] = mappers.GxROM
|
mappers[66] = mappers.GxROM
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
require'nes'
|
||||||
|
|
||||||
|
-- 2 32kB PRG roms
|
||||||
|
mappers.GxROM{ prgsize=(32*2)*1024 }
|
||||||
|
|
||||||
|
location(chrrom0)
|
||||||
|
|
||||||
|
local font = section("font")
|
||||||
|
dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -- <SPC>
|
||||||
|
dc.b 0x38,0x38,0x2c,0x64,0x7e,0x46,0xce,0x00,0x38,0x38,0x2c,0x64,0x7e,0x46,0xce,0x00 -- A
|
||||||
|
dc.b 0xfc,0x62,0x66,0x7c,0x62,0x66,0xfc,0x00,0xfc,0x62,0x66,0x7c,0x62,0x66,0xfc,0x00 -- B
|
||||||
|
dc.b 0x7c,0xe6,0xc2,0xc0,0xc0,0xe6,0x7c,0x00,0x7c,0xe6,0xc2,0xc0,0xc0,0xe6,0x7c,0x00 -- C
|
||||||
|
dc.b 0xfc,0x4e,0x46,0x46,0x46,0xce,0xfc,0x00,0xfc,0x4e,0x46,0x46,0x46,0xce,0xfc,0x00 -- D
|
||||||
|
dc.b 0xfe,0x66,0x60,0x7c,0x60,0x66,0xfe,0x00,0xfe,0x66,0x60,0x7c,0x60,0x66,0xfe,0x00 -- E
|
||||||
|
dc.b 0xfe,0x66,0x60,0x7c,0x60,0x60,0xf0,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0xf0,0x00 -- F
|
||||||
|
dc.b 0x7c,0xe6,0xc0,0xce,0xc6,0xe6,0x7c,0x00,0x7c,0xe6,0xc0,0xce,0xc6,0xe6,0x7c,0x00 -- G
|
||||||
|
dc.b 0xee,0x66,0x66,0x7e,0x66,0x66,0xee,0x00,0xee,0x66,0x66,0x7e,0x66,0x66,0xee,0x00 -- H
|
||||||
|
dc.b 0x3c,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x3c,0x00 -- I
|
||||||
|
dc.b 0x0e,0x06,0x06,0xc6,0xc6,0xce,0x7c,0x00,0x0e,0x06,0x06,0xc6,0xc6,0xce,0x7c,0x00 -- J
|
||||||
|
dc.b 0xce,0xdc,0xf8,0xf0,0xf8,0xdc,0xce,0x00,0xce,0xdc,0xf8,0xf0,0xf8,0xdc,0xce,0x00 -- K
|
||||||
|
dc.b 0xc0,0xc0,0xc0,0xc0,0xc6,0xc6,0xfe,0x00,0xc0,0xc0,0xc0,0xc0,0xc6,0xc6,0xfe,0x00 -- L
|
||||||
|
dc.b 0xc6,0xee,0xfe,0xd6,0xc6,0xc6,0xc6,0x00,0xc6,0xee,0xfe,0xd6,0xc6,0xc6,0xc6,0x00 -- M
|
||||||
|
dc.b 0xc6,0xe6,0xf6,0xde,0xce,0xc6,0xc6,0x00,0xc6,0xe6,0xf6,0xde,0xce,0xc6,0xc6,0x00 -- N
|
||||||
|
dc.b 0x7c,0xee,0xc6,0xc6,0xc6,0xee,0x7c,0x00,0x7c,0xee,0xc6,0xc6,0xc6,0xee,0x7c,0x00 -- O
|
||||||
|
dc.b 0xfc,0xc6,0xc6,0xc6,0xfc,0xc0,0xc0,0x00,0xfc,0xc6,0xc6,0xc6,0xfc,0xc0,0xc0,0x00 -- P
|
||||||
|
dc.b 0x7c,0xce,0xc6,0xc6,0xde,0xec,0x7e,0x00,0x7c,0xce,0xc6,0xc6,0xde,0xec,0x7e,0x00 -- Q
|
||||||
|
dc.b 0xfc,0x66,0x66,0x7c,0x58,0x6c,0xe6,0x00,0xfc,0x66,0x66,0x7c,0x58,0x6c,0xe6,0x00 -- R
|
||||||
|
dc.b 0x7c,0xc6,0xc0,0x7c,0x06,0xc6,0x7c,0x00,0x7c,0xc6,0xc0,0x7c,0x06,0xc6,0x7c,0x00 -- S
|
||||||
|
dc.b 0xfe,0x92,0x10,0x10,0x10,0x10,0x38,0x00,0xfe,0x92,0x10,0x10,0x10,0x10,0x38,0x00 -- T
|
||||||
|
dc.b 0xe6,0xe6,0xc2,0xc2,0xc2,0xe6,0x7c,0x00,0xe6,0xe6,0xc2,0xc2,0xc2,0xe6,0x7c,0x00 -- U
|
||||||
|
dc.b 0xc6,0xc6,0xc6,0x6c,0x6c,0x38,0x38,0x00,0xc6,0xc6,0xc6,0x6c,0x6c,0x38,0x38,0x00 -- V
|
||||||
|
dc.b 0xc6,0xc6,0xd6,0xfe,0xee,0xc6,0x82,0x00,0xc6,0xc6,0xd6,0xfe,0xee,0xc6,0x82,0x00 -- W
|
||||||
|
dc.b 0x86,0xcc,0x78,0x30,0x78,0xcc,0x86,0x00,0x86,0xcc,0x78,0x30,0x78,0xcc,0x86,0x00 -- X
|
||||||
|
dc.b 0xc6,0xc6,0x6c,0x38,0x18,0x18,0x38,0x00,0xc6,0xc6,0x6c,0x38,0x18,0x18,0x38,0x00 -- Y
|
||||||
|
dc.b 0x7e,0xce,0x98,0x30,0x62,0xe6,0xfc,0x00,0x7e,0xce,0x98,0x30,0x62,0xe6,0xfc,0x00 -- Z
|
||||||
|
charset(" abcdefghijklmnopqrstuvwxyz", \x(x+(font.org - font.location.start) // 16))
|
||||||
|
|
||||||
|
local copytext = function(sec_text, text)
|
||||||
|
-- load screen text in PPU RAM 0x21CA
|
||||||
|
ppu_addr(0x21ca)
|
||||||
|
ldy #0 @_loadtxt lda sec_text,y sta PPUDATA iny cpy ##text bne _loadtxt
|
||||||
|
-- reset scroll position
|
||||||
|
ppu_addr(0) sta BGSCROL sta BGSCROL
|
||||||
|
end
|
||||||
|
|
||||||
|
-- RAM
|
||||||
|
joya = 0
|
||||||
|
|
||||||
|
--[[
|
||||||
|
BANK 0 - startup bank
|
||||||
|
]]
|
||||||
|
location(prgrom0)
|
||||||
|
|
||||||
|
local text0 = "bank one"
|
||||||
|
@@text0s byte(text0)
|
||||||
|
|
||||||
|
@@nmi0 @irq0 rti
|
||||||
|
|
||||||
|
local toprg1s = section("toprg1")
|
||||||
|
switchroms(1,0)
|
||||||
|
local fromprg1s = section("fromprg1")
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
@@main
|
||||||
|
init()
|
||||||
|
--lda#0x80 sta PPUSTAT -- enable VBlank IRQ on NMI vector
|
||||||
|
vblank_waitbegin()
|
||||||
|
-- load BG palette in PPU RAM
|
||||||
|
ppu_addr(BGPAL)
|
||||||
|
for _,v in ipairs{ 0x1f, 0x00, 0x10, 0x20 } do lda #v sta PPUDATA end
|
||||||
|
-- turn screen on
|
||||||
|
lda #0x0a sta PPUMASK -- show BG
|
||||||
|
-- idle
|
||||||
|
@mainloop
|
||||||
|
vblank_waitbegin()
|
||||||
|
copytext(text0s, text0)
|
||||||
|
read_joy_a(1) bcc _noswitch
|
||||||
|
lda joya bne _switch
|
||||||
|
lda #1 sta joya jmp toprg1
|
||||||
|
@_noswitch
|
||||||
|
lda #0 sta joya
|
||||||
|
@_switch
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
BANK 1
|
||||||
|
]]
|
||||||
|
location(prgrom1)
|
||||||
|
|
||||||
|
local text1 = "bank two"
|
||||||
|
@@text1s byte(text1)
|
||||||
|
|
||||||
|
@@nmi1 @irq1 rti
|
||||||
|
|
||||||
|
local toprg0s = section("toprg0")
|
||||||
|
relate(toprg0s, fromprg1s, 7) -- switchprgrom(immediate) takes 7 bytes
|
||||||
|
switchroms(0,0)
|
||||||
|
|
||||||
|
local fromprg0s = section("fromprg0")
|
||||||
|
relate(toprg1s, fromprg0s, 7)
|
||||||
|
jmp mainloop1
|
||||||
|
|
||||||
|
@mainloop1
|
||||||
|
vblank_waitbegin()
|
||||||
|
copytext(text1s, text1)
|
||||||
|
read_joy_a(1) bcc _noswitch
|
||||||
|
lda joya bne _switch
|
||||||
|
lda #1 sta joya jmp toprg0
|
||||||
|
@_noswitch
|
||||||
|
lda #0 sta joya
|
||||||
|
@_switch
|
||||||
|
jmp mainloop1
|
||||||
|
|
||||||
|
writebin(filename..'.nes')
|
||||||
|
writesym(filename..'.mlb', 'mesen')
|
||||||
|
writesym(filename..'.nes', 'fceux')
|
||||||
|
print(stats)
|
Loading…
Reference in New Issue