Running a ROM panics #1

Closed
BurntSushi opened this Issue Oct 5, 2012 · 10 comments

Comments

Projects
None yet
3 participants

Here's the command and the panic. When I run it, I can see a window popup on my screen for at most a few milliseconds. Then it disappears.

[andrew@Ocelot Fergulator] Fergulator test_roms/nesstress.nes 
PRG-ROM Count: 2
CHR-ROM Count: 1
Vertical mirroring
Writing bank 1 to 0xC000, base value: 0x0
Mapper: 0x0
unexpected fault address 0x7f32fc6c0000
throw: fault
[signal 0xb code=0x2 addr=0x7f32fc6c0000 pc=0x42d67f]

goroutine 6 [running]:
main.(*Video).Render(0x59ae58, 0x0)
        /home/andrew/go/src/github.com/scottferg/Fergulator/video.go:58 +0x37b
created by main.main
        /home/andrew/go/src/github.com/scottferg/Fergulator/machine.go:176 +0x46e

goroutine 1 [runnable]:
main.(*Ppu).raster(0x5aa910, 0x40ea02)
        /home/andrew/go/src/github.com/scottferg/Fergulator/ppu.go:190 +0x17d
main.(*Ppu).Step(0x5aa910, 0x3)
        /home/andrew/go/src/github.com/scottferg/Fergulator/ppu.go:214 +0xfd
main.main()
        /home/andrew/go/src/github.com/scottferg/Fergulator/machine.go:182 +0x4c9

goroutine 2 [syscall]:
created by runtime.main
        /opt/go/src/pkg/runtime/proc.c:220

goroutine 3 [runnable]:
github.com/0xe2-0x9a-0x9b/Go-SDL/sdl.pollEvents()
        /home/andrew/go/src/github.com/0xe2-0x9a-0x9b/Go-SDL/sdl/event.go:52 +0xbc
created by github.com/0xe2-0x9a-0x9b/Go-SDL/sdl.init·1
        /home/andrew/go/src/github.com/0xe2-0x9a-0x9b/Go-SDL/sdl/event.go:64 +0x1f

goroutine 4 [timer goroutine (idle)]:
created by addtimer
        /opt/go/src/pkg/runtime/ztime_linux_amd64.c:70

goroutine 5 [chan receive]:
main.JoypadListen()
        /home/andrew/go/src/github.com/scottferg/Fergulator/controller.go:77 +0x46
created by main.main
        /home/andrew/go/src/github.com/scottferg/Fergulator/machine.go:175 +0x454

I get the same error with any other ROM it seems. (I first tried Super Mario.)

I am on the latest commit from master to my knowledge: 06de8e525bfb4e26d8d09a0a3ccfd7d9b0bd54d1

I'm on Archlinux: Linux Ocelot 3.5.4-1-ARCH #1 SMP PREEMPT Sat Sep 15 08:12:04 CEST 2012 x86_64 GNU/Linux.

Here are my versions of the dependencies from the README:

[andrew@Ocelot Fergulator] y -Qi sdl sdl_gfx sdl_image | egrep '^(Name|Version)'
Name           : sdl
Version        : 1.2.15-3
Name           : sdl_gfx
Version        : 2.0.24-1
Name           : sdl_image
Version        : 1.2.12-2

Go-SDL:

[andrew@Ocelot Go-SDL] git show
commit f4b2c0ad232e3955f9f9325f95e513a47bf399d6
Merge: d4ded26 c6f47f2
Author: ⚛ <0xe2.0x9a.0x9b@gmail.com>
Date:   Wed Sep 19 00:05:41 2012 -0700

    Merge pull request #12 from davecheney/master

    linux/arm support

Oh, and I'm on Go tip:

[andrew@Ocelot go-hg] go version
go version devel +97b5f757b30e Fri Oct 05 23:51:40 2012 +0800

Let me know if you want to me to try it on 1.0.3.

Oh, output of go test:

[andrew@Ocelot Fergulator] go test
PRG-ROM Count: 1
CHR-ROM Count: 1
Horizontal mirroring
Mapper: 0x0
Mapper: MMC1
  Mirroring: Vertical
Mapper: MMC1
  Mirroring: Horizontal
PASS
ok      github.com/scottferg/Fergulator 0.027s
Owner

scottferg commented Oct 5, 2012

Actually if it's not too much of a bother, could you try 1.0.3? The line that's crashing is pretty low level so I'd just like to rule that out. If 1.0.3 still crashes I'll throw together a similar Arch VM tonight and test it more granularly. No games will run with that particular crash though.

Yikes. Everything works fine on 1.0.3. Thanks for the nudge :-)

This is really great work. I played through the first level of Mario. Nice job!

@BurntSushi BurntSushi closed this Oct 5, 2012

Owner

scottferg commented Oct 5, 2012

Awesome, glad to hear it's working :)

imarko commented Oct 6, 2012

I think this is because of the recent change of making int 64 bits on amd64.
Render() assumes that it's 32 bit.

Owner

scottferg commented Oct 6, 2012

Which int? The bitmap? I refactored this method this morning and ended up dropping one of them.

@scottferg scottferg reopened this Oct 6, 2012

imarko commented Oct 6, 2012

buf := (*[512 * 480]int)(v.screen.Pixels)[:]

When int is 64 bits this will give you a slice of 64 bit ints so it doesn't match the 32 bit SDL surface. I was able to get it to work by using int32 for the slice and then casting to int32 in the copy loop but it might be better to use int32 explicitly for all pixel work.

Owner

scottferg commented Oct 6, 2012

Oh awesome, great find!

So this fixes it?
buf := (*[512 * 480]int32)(v.screen.Pixels)[:]

imarko commented Oct 6, 2012

Yes, that plus the required int32 casts work as a quick fix (my version below) but on the long run in might be better to use int32 on the ppu side too.

diff --git a/video.go b/video.go
index 61d5e78..f9486cd 100644
--- a/video.go
+++ b/video.go
@@ -31,7 +31,7 @@ func (v *Video) Init(t <-chan []int, d <-chan []int, n string) {
 }

 func (v *Video) Render() {
-       buf := (*[512 * 480]int)(v.screen.Pixels)[:]
+       buf := (*[512 * 480]int32)(v.screen.Pixels)[:]
        for {
                select {
                case val := <-v.tick:
@@ -42,10 +42,10 @@ func (v *Video) Render() {
                                y *= 2
                                x *= 2

-                               buf[(y*512)+x] = val[i]
-                               buf[((y+1)*512)+x] = val[i]
-                               buf[(y*512)+(x+1)] = val[i]
-                               buf[((y+1)*512)+(x+1)] = val[i]
+                               buf[(y*512)+x] = int32(val[i])
+                               buf[((y+1)*512)+x] = int32(val[i])
+                               buf[(y*512)+(x+1)] = int32(val[i])
+                               buf[((y+1)*512)+(x+1)] = int32(val[i])
                        }

                        v.screen.Flip()
Owner

scottferg commented Oct 6, 2012

Awesome, just added this change. I'll test it on go tip soon and see about updating the PPU as well.

-- Scott Ferguson

On Saturday, October 6, 2012 at 3:03 PM, imarko wrote:

Yes, that plus the required int32 casts work as a quick fix (my version below) but on the long run in might be better to use int32 on the ppu side too.
diff --git a/video.go b/video.go index 61d5e78..f9486cd 100644 --- a/video.go +++ b/video.go @@ -31,7 +31,7 @@ func (v Video) Init(t <-chan []int, d <-chan []int, n string) { } func (v *Video) Render() { - buf := ([512 * 480]int)(v.screen.Pixels)[:] + buf := (_[512 * 480]int32)(v.screen.Pixels)[:] for { select { case val := <-v.tick: @@ -42,10 +42,10 @@ func (v *Video) Render() { y *= 2 x *= 2 - buf[(y_512)+x] = val[i] - buf[((y+1)_512)+x] = val[i] - buf[(y_512)+(x+1)] = val[i] - buf[((y+1)_512)+(x+1)] = val[i] + buf[(y_512)+x] = int32(val[i]) + buf[((y+1)_512)+x] = int32(val[i]) + buf[(y_512)+(x+1)] = int32(val[i]) + buf[((y+1)*512)+(x+1)] = int32(val[i]) } v.screen.Flip()


Reply to this email directly or view it on GitHub (#1 (comment)).

@scottferg scottferg closed this Oct 7, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment