miker00lz Posted January 12, 2011 Share Posted January 12, 2011 i started writing a 2600 emulator the other day, and am having a weird issue with colors. first of all, the emu is FAR from done. the only TIA stuff it emulates now is playfield and player0/1. anyway, when i run the sample ROM posted in one of andrew davie's tutorials from here the colors look just fine: but whenever i try to run any actual game ROMs, the graphics are in greyscale.. for example here's pitfall: any idea what could possibly be causing this to occur? another problem i'm having is when running pacman and some other games, the picture doesn't stay vertically stable. it looks kind of like an old TV that has the v-hold set wrong. thanks for any help! Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 12, 2011 Share Posted January 12, 2011 The ROMs work fine on real hardware so you'll have to explain what your emulation code is doing to get more helpful replies. 1 Quote Link to comment Share on other sites More sharing options...
miker00lz Posted January 12, 2011 Author Share Posted January 12, 2011 (edited) The ROMs work fine on real hardware so you'll have to explain what your emulation code is doing to get more helpful replies. oh, wow i feel stupid... i just fixed it. i wasn't returning the color bit when SWCHB was read. i just needed to RTFM better. as you can see in the pic, i've still got a few issues, the biggest one being that it's drawing that log too far from towards the left. i'm wondering if it could be an issue with my countdown timer emulation, where you can set 1/8/64/1024 intervals. here are some relative snippets from my code. pardon my BASIC! i'm doing it in FreeBASIC, because i think its a really useful language for experimenting with and prototyping programs before writing in C. write to timer registers code: Case &h294 'set 1 clk interval timerint = 1 timertemp = 0 intim = value Case &h295 'set 8 clk interval timerint = 8 timertemp = 0 intim = value Case &h296 'set 64 clk interval timerint = 64 timertemp = 0 intim = value Case &h297 'set 1024 clk interval timerint = 1024 timertemp = 0 intim = value and this code is from my exec6502 loop, where it adds clock counts to timertemp and handles the countdown: timertemp = timertemp + Ticks(opcode) If timertemp >= timerint Then intim = intim - timertemp \ timerint timertemp = timertemp - (timertemp \ timerint) * timerint If intim < 0 Then intim = 256 + intim '< 0 so that intim doesn't wrap around until another cycle after reaching 0 EndIf and this is where it returns the countdown value when the timer register is read: FUNCTION Read6502% (BYVAL addr AS LONG) SELECT CASE addr Case &h282 'console switches Read6502% = 8 'this means use color, not B/W Exit Function Case &h284 'timer count read If intim < 0 Then Read6502% = 0 Else Read6502% = intim Exit Function CASE IS >= &HE000& addr = &H1000 + (addr AND 4095) END SELECT Read6502% = ram(addr) END FUNCTION and here is my main execution loop: DO Do ops = exec6502(1) Loop Until vsync = 0 And (vblank And 2) = 0 LOCATE 50, 20 PRINT "Frame" + STR$(framenum); framenum = framenum + 1 For curline = 0 To 39 wsync = 0 ops = exec6502(76) Next curline For curline = 0 TO 191 LOCATE 50, 1 PRINT "Scanline" + Str$(curline) + " "; wsync = 0 ops = exec6502(23) RenderScanline curline NEXT curline For curline = 192 To 221 wsync = 0 ops = exec6502(76) If vsync <> 0 Or vblank <> 0 Then Exit For Next curline Loop UNTIL INKEY$ <> "" and finally, my (still very incomplete) scanline render routine.. i know it's extremely inefficient, and i can see a lot of ways to change that but like i said i'm just doing this FreeBASIC version to experiment and learn right now: Sub RenderScanline (ByVal curline As Integer) FOR drawx = 0 TO 159 If (drawx Mod 3) = 0 Then ops = exec6502(1) If resp0 = -1 Then resp0 = drawx 'set player 0 horiz pos if reset was strobed If resp1 = -1 Then resp1 = drawx 'set player 1 horiz pos if reset was strobed pfx = drawx \ 4 If (ctrlpf And 1) = 1 And pfx > 19 Then Select CASE pfx Case 0 TO 3: pfreg = pf0: adjust = 0 Case 4 TO 11: pfreg = pf1: adjust = 4 Case 12 TO 19: pfreg = pf2: adjust = 12 Case 20 TO 23: pfreg = pf2: adjust = 20 Case 24 TO 31: pfreg = pf1: adjust = 24 Case ELSE: pfreg = pf0: adjust = 32 End Select Select CASE pfx - adjust Case 7: IF (pfreg AND 128) = 128 THEN curpix = colupf ELSE curpix = colubk Case 6: IF (pfreg AND 64) = 64 THEN curpix = colupf ELSE curpix = colubk Case 5: IF (pfreg AND 32) = 32 THEN curpix = colupf ELSE curpix = colubk Case 4: IF (pfreg AND 16) = 16 THEN curpix = colupf ELSE curpix = colubk Case 3: IF (pfreg AND = 8 THEN curpix = colupf ELSE curpix = colubk Case 2: IF (pfreg AND 4) = 4 THEN curpix = colupf ELSE curpix = colubk Case 1: IF (pfreg AND 2) = 2 THEN curpix = colupf ELSE curpix = colubk Case 0: IF (pfreg AND 1) = 1 THEN curpix = colupf ELSE curpix = colubk End Select Else Select CASE pfx Case 0 TO 3: pfreg = pf0: adjust = 0 Case 4 TO 11: pfreg = pf1: adjust = 4 Case 12 TO 19: pfreg = pf2: adjust = 12 Case 20 TO 27: pfreg = pf0: adjust = 20 Case 28 TO 35: pfreg = pf1: adjust = 28 Case ELSE: pfreg = pf2: adjust = 36 End Select Select CASE pfx - adjust Case 0: IF (pfreg AND 128) = 128 THEN curpix = colupf ELSE curpix = colubk Case 1: IF (pfreg AND 64) = 64 THEN curpix = colupf ELSE curpix = colubk Case 2: IF (pfreg AND 32) = 32 THEN curpix = colupf ELSE curpix = colubk Case 3: IF (pfreg AND 16) = 16 THEN curpix = colupf ELSE curpix = colubk Case 4: IF (pfreg AND = 8 THEN curpix = colupf ELSE curpix = colubk Case 5: IF (pfreg AND 4) = 4 THEN curpix = colupf ELSE curpix = colubk Case 6: IF (pfreg AND 2) = 2 THEN curpix = colupf ELSE curpix = colubk Case 7: IF (pfreg AND 1) = 1 THEN curpix = colupf ELSE curpix = colubk End Select End If Select Case resp1 - drawx Case 0: If (grp1 And 128) = 128 Then curpix = colup1 Case 1: If (grp1 And 64) = 64 Then curpix = colup1 Case 2: If (grp1 And 32) = 32 Then curpix = colup1 Case 3: If (grp1 And 16) = 16 Then curpix = colup1 Case 4: If (grp1 And = 8 Then curpix = colup1 Case 5: If (grp1 And 4) = 4 Then curpix = colup1 Case 6: If (grp1 And 2) = 2 Then curpix = colup1 Case 7: If (grp1 And 1) = 1 Then curpix = colup1 End Select Select Case resp0 - drawx Case 0: If (grp0 And 128) = 128 Then curpix = colup0 Case 1: If (grp0 And 64) = 64 Then curpix = colup0 Case 2: If (grp0 And 32) = 32 Then curpix = colup0 Case 3: If (grp0 And 16) = 16 Then curpix = colup0 Case 4: If (grp0 And = 8 Then curpix = colup0 Case 5: If (grp0 And 4) = 4 Then curpix = colup0 Case 6: If (grp0 And 2) = 2 Then curpix = colup0 Case 7: If (grp0 And 1) = 1 Then curpix = colup0 End Select scanline(drawx) = curpix NEXT drawx FOR dr = 0 TO 159 LINE (dr * 4, curline*2)-STEP(3, 1), scanline(dr), bf NEXT dr End Sub also, should my TIA emulation be resuming the CPU from a wsync BEFORE the 23 hblank CPU cycles, or after that and right before the next 53 CPU cycles? this is what it looks like if i make that change: i know this post is huge, if you're still with me thanks! btw i am aware that i need to add support for reflecting the player graphics - just haven't done it yet. Edited January 12, 2011 by miker00lz Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted January 13, 2011 Share Posted January 13, 2011 also, should my TIA emulation be resuming the CPU from a wsync BEFORE the 23 hblank CPU cycles, or after that and right before the next 53 CPU cycles? Looking good so far! WSYNC makes the CPU stop and then resume again at the leading edge of the HBLANK. The TIA keeps outputting its signal regardless, and as soon as the last playfield pixel on the current line has been drawn, the CPU will resume with the first cycle of the HBLANK (if it has been paused by WSYNC). Actually, WSYNC is slightly misnamed, because HSYNC doesn't start as soon as HBLANK begins, so it's really "wait for HBLANK," not "wait for HSYNC"-- but I guess WSYNC sounded better than WBLANK! Michael Quote Link to comment Share on other sites More sharing options...
DanBoris Posted January 22, 2011 Share Posted January 22, 2011 Looks like you are off to a good start. Emulating the 2600 is really tricky because you have to be so precise with your timing. One thing to remember about the RIOT timers is that they count down based on the interval, but when it reaches the end of the count and rolls over, it starts counting down again at an interval of 1. Quote Link to comment Share on other sites More sharing options...
miker00lz Posted January 28, 2011 Author Share Posted January 28, 2011 (edited) thanks for the comments and tips guys, i haven't been working on it as much as i'd like to due to being busy at work but i have not forgotten it. i'd love to get it playable. my NES emulator worked pretty well ( http://24.107.65.240/moarnes/ - unlike my atari emu, this one's written in C ) but yeah, the atari is quite a bit more tricky regarding the timing. i didn't expect it to be like that, although it makes sense considering the much more primitive video hardware vs. the NES. very few NES games really need dead-on timing. most will work fine with it way off. my timing in it is fairly close, but i still have problems with marble madness and battletoads. i've also been spending a lot of time working on my x86 PC emulator, Fake86.. yes i know i have too many projects at once! Fake86 is particularly fun to work on since the CPU core is actually written from scratch by me! it wasn't easy. and it has a few bugs, but it can run a BIOS and ROM BASIC. Edited January 28, 2011 by miker00lz Quote Link to comment Share on other sites More sharing options...
The Usotsuki Posted January 29, 2011 Share Posted January 29, 2011 Sounds like me. xD Quote Link to comment Share on other sites More sharing options...
yuppicide Posted January 29, 2011 Share Posted January 29, 2011 Not to be mean, but why write an emulator when Stella emulator already exists and works great? Why not put efforts into something else like designing something that isn't out there already or even a new 2600 game perhaps.. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 29, 2011 Share Posted January 29, 2011 Not to be mean, but why write an emulator when Stella emulator already exists and works great? Why not put efforts into something else like designing something that isn't out there already or even a new 2600 game perhaps.. That's like saying why develop cars when the Ford Model T did the job . Programmer's like challenges. If writing an emulator is what floats your boat then write emulators. Contributing any projects to the retro scene is always a good thing in my opinion. 2 Quote Link to comment Share on other sites More sharing options...
The Usotsuki Posted January 29, 2011 Share Posted January 29, 2011 Not to be mean, but why write an emulator when Stella emulator already exists and works great? Why not put efforts into something else like designing something that isn't out there already or even a new 2600 game perhaps.. That's like saying why develop cars when the Ford Model T did the job . Programmer's like challenges. If writing an emulator is what floats your boat then write emulators. Contributing any projects to the retro scene is always a good thing in my opinion. And miek's really into the retro stuff. I've seen pics of the breadboard he's building an XT clone on. xD And he's gotten an IRC client *and server* running on MS-DOS (he used to run his ircd off an XT). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.