mirror of
https://github.com/g012/l65.git
synced 2025-03-11 16:32:17 +00:00
[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:
|
||||
- cmake . -DCMAKE_BUILD_TYPE=Release
|
||||
- make
|
||||
- cd samples
|
||||
- ../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 ..
|
||||
- cd samples; for f in *.l65; do echo $f; ../l65 $f || break; done; cd ..
|
||||
- cp l65 l65-$TRAVIS_TAG-$TRAVIS_OS_NAME
|
||||
deploy:
|
||||
provider: releases
|
||||
|
2
6502.lua
2
6502.lua
@ -515,6 +515,8 @@ end
|
||||
-- -ted positon for 'section1'.
|
||||
-- If offset1 is omitted, -offset2 is used.
|
||||
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 {}
|
||||
rel1[section2] = (offset2 or offset) or 0
|
||||
relations[section1] = rel1
|
||||
|
80
nes.l65
80
nes.l65
@ -447,18 +447,6 @@ mappers.GxROM = function(t)
|
||||
hdrrom = location{0x7ff0, 0x7fff, name='header'}
|
||||
header(t)
|
||||
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 ci, chrstart = 0, 0x8000 + bc*0x8000
|
||||
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
|
||||
chrrom = chrrom0
|
||||
-- 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
|
||||
bankregister = 0
|
||||
bankregister_shadow = -1
|
||||
-- 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)
|
||||
if bankix then
|
||||
assert(bankix < bc)
|
||||
bankregister = (bankregister & ~0x30) | (bankix << 4)
|
||||
ldx #bankregister&3|bankregister>>2 lda #bankregister sta bankbytes0,x
|
||||
lda #bc-1-bankix
|
||||
else
|
||||
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
|
||||
;and #0xc asl asl ora bankregister_shadow sta bankregister_shadow
|
||||
sta bankbytes0,x
|
||||
clc eor #0xff adc #bc -- bc-1 - A
|
||||
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
|
||||
function switchchrrom(bankix)
|
||||
if bankix then
|
||||
assert(bankix < cc)
|
||||
bankregister = (bankregister & ~3) | 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
|
||||
lda #bankix
|
||||
end
|
||||
end
|
||||
mappers.init = function()
|
||||
switchchrrom(0)
|
||||
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
|
||||
lda bankbytes0,x sta bankregister_shadow sta bankbytes0,x
|
||||
end
|
||||
end
|
||||
mappers[66] = mappers.GxROM
|
||||
|
118
samples/nes_bank2.l65
Normal file
118
samples/nes_bank2.l65
Normal file
@ -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…
x
Reference in New Issue
Block a user