Jump to content

Altirra 2.60 released


Recommended Posts

  • 2 weeks later...

Not sure which thread exactly you're referring to, but I haven't intentionally done any changes to the video encoder lately. One known issue when uploading the videos to YouTube is that the option to encode duplicate frames as full frames needs to be checked, as the encoder that YouTube uses doesn't handle pad frames correctly in AVI files. If that option is on and the screen is animating below 50/60Hz, you'll get at best incorrect timing on some of the frames. If you happen to know an approximate bracket of last known good / first known bad for the emulator, that would be very helpful in tracking down the issue.

Link to comment
Share on other sites

Phaeron... I guess it was around test26... but not sure... maybe youtube changed something but I thought that you as virtualdub master could help :D


I never managed to upload 60/50 fps video... so far... ;) so could be me...


but here on my laptop I definitly see that uploading now videos from my windows machine causes low playback quality on same machine which was not there before... but on my iphone is good so I guess it is more something here in Chrome...


another question as I can not find the answer...


;bp -n main "r @t2 @frame-@t0; r @t3 @clk-@t1; r @t0 @frame; r @t1 @clk"
;wx @t2
;wx @t3
how can I add that to the ini file? so I can enable that every time I start altirra from WUDSN?
Link to comment
Share on other sites

I don't actually have much experience with uploading videos to YouTube, so my past experience won't really help here. From what I gather, the problem is in YouTube's heuristics for what resolutions it should offer -- it is now deciding that your video can suitably be displayed at 144p... which is a bad choice. Apparently this has been a problem with a bunch of let's play videos over the past couple of years, as well. :(


About the only suggestions I could come up with are to try resizing the video up to SD or HD resolution before uploading, or pre-encoding it to H.264 in the hope that YouTube won't actually bother reencoding it. This is likely content specific, so you'd have to try it on your own footage. The former I might be able to include in the emulator if it helps -- I have a resampler embedded already for display -- but including an H.264 encoder is rather out of scope. You could probably rig mencoder or ffmpeg to do the necessary conversion.


Regarding making the profiling displays default, place the commands in startup.atdbg in Altirra's program directory. It can also be named after/next to the executable that's being loaded, i.e. foo.atdbg for foo.xex, but I believe WUDSN already uses that. You will probably want to move the breakpoint to a named group so it isn't cleared by normal commands, i.e. bp -g frametimes, and pre-clear both the watches and the breakpoints on startup in case the program instance is reused: bc frametimes.* and wc *. Also, don't use semicolons in the .atdbg file; those are only used to separate commands in a breakpoint statement, and the commands should just be each on their own lines without a leading or trailing semicolon.

Link to comment
Share on other sites

I've been using Windows hate.1 since the start of the year which is all good but I've not got around to setting up the palette in Altirra as I previously had it (which I was happy with). I have an image of my previous os, is it possible to retrieve my colour palette settings for Altirra from the old registry?



Link to comment
Share on other sites

FYI, I've taken 50fps videos from Altirra, scaled them up 4X in VirtualDub and then uploaded them to Youtube. This appears to force Youtube to offer them in 720p50 HD. You can see an example here.


For scaling in VirtualDub I choose Video -> Filters -> Add -> resize. I select Relative 400% x 400%, Filter Mode: Nearest neighbor. Then I go to Video -> Compression and choose Microsoft Video 1. Other options like Zipped Motion Block Video don't seem to work. Finally, I go to File -> Save as AVI.

Edited by Xuel
  • Like 3
Link to comment
Share on other sites




Couple of additions to the profiler. It now handles high DPI better, and has support for setting triggers for denoting frame or main loop tick boundaries. This makes it easier to profile closely around temporary slowdowns and hitches. The frames are shown in a graph that allows selecting single frames or a range of frames by dragging.




Function mode now also collects instruction data so that the detailed view shows instruction samples instead of function samples. At some point the plan is to merge function and instruction modes and just have different views for the same run.


  • Like 5
Link to comment
Share on other sites

and what does the graph tell me? If I profile my voxel routine... the frame graphs are all same height. which is obvious as the VBL only processes music while main calculations running in main loop.


so is that usefull to detect if my VBL is too long? fex. when using RMT this can happen when special instruments in a song increase the cpu load?

Link to comment
Share on other sites

The graph serves two purposes. Its height tells you the length of a profiled frame or tick, and it's the way you select frame(s) for viewing in the lower pane. Therefore, even if the graph is all the same height, it still serves as a selector.


Now, you're correct that in vertical blank mode the graph will be of uniform height, because all profiled frames will be the same length. I have some ideas on how to allow scopes like interrupt time or individual functions to show up, but they haven't been implemented yet. The PC triggering mode can give variable length frames, although in the case of a VBI routine it won't help. In the case of Star Raiders I was timing the main loop, where only one PC trigger was enough.


Specifically for the VBI routine, it's probably better to use conditional breakpoints to trap when the VBI routine goes too long. For instance, if you want to stop when the VBI routine goes past line 8, set a breakpoint at the end of the VBI with the condition "@vpos >= 8 and @vpos < 248."

  • Like 2
Link to comment
Share on other sites





Finished up this round of work on the profiler. It now has some documentation in the help file, fixed a bug that caused instruction counts to be wrong in multi-frame profiles, and expanded the PC triggering modes. You can now set an end PC address as well as a start PC address, or just have the profiler end the frame when the current function exits. For instance, you can profile the VBI handler by using a start PC address expression of "dw vvblki" and stopping after the function. Frames can also be triggered via .profile_start/endframe commands in the debugger.


The help file also has documentation on how to set up networking for DragonCart emulation. I've attached the page in case any Linux gurus could chime in about the VXLAN tunnel setup instructions, or just have a laugh at how bad the instructions are. There's still a lot of devices undocumented, but documentation is so much work....


ATBasic has been updated to 1.47. I added a guard patch in case AFP decides to return a bogus number (yay), and moved the point where the runtime stack is fixed/pinned from start of execution to first NEXT/RETURN. This should fix the case that StefanD hit where immediate mode statements couldn't be run because the interpreter kept throwing GOSUB-gone errors.




  • Like 8
Link to comment
Share on other sites





Fixes a regression in the H: handler that prevented the lock/unlock commands from working, and tweaks the way that firmware paths are generated. Now, if the program is running in portable mode, it will generate relative paths for upward links on the same drive prefix. This should help with the issues with portable installations and ROM images higher than the program. Non-portable (registry-based) execution still uses full paths for paths higher up.


Avery, yesterday I found someone stole you icon! :-D


Plain ANTIC E with no mid-screen color changes. Weak. :P

  • Like 5
Link to comment
Share on other sites

Hardly a major issue, but I noticed that display filtration (test38) had completely vanished after an OS wake-up (Windows 10), giving the effect of View->Filter Mode->Point when the setting was in fact Sharp Bilinear. Emulator restart fixed it, of course.


This happens if the emulator fails to reinitialize Direct3D and has to fall back to GDI for display, and then doesn't get an appropriate signal when the graphics driver's back up. I need to try to reproduce this to see exactly what events are happening... it gets tricky if the GPU is up but the display is not when the system emerges from sleep. You don't need to restart the emulator -- glitching the screen with Ctrl+Alt+Del or closing and reopening the display pane is enough to cause the emulator to reinitialize the display with the highest available display mode.


When fiddling with accelerated CPU and custom 65C816 OS-es (like mine here http://drac030.krap.pl/pl-pliki.php) please keep "CPU Options->Shadow ROMs in Fast RAM" off, enabling it causes weird problems, like SysInfo not reading keyboard input.


I tracked down what's triggering this in the emulator and should be able to fix it, but it looks like there is also a race condition in the 65C816 OS that is ultimately causing the problem:

  3180:249: 35.1 | A=BA:FF X=80 Y=0C (N    C) | 00:FA09: CB                WAI
  3181:  8: 29.2 | A=BA:FF X=80 Y=0C (N    C) | 00:FA0A: 9C E8 03          STZ $03E8
  3181:  8: 29.6 | A=BA:FF X=80 Y=0C (N    C) | 00:FA0D: A5 2A             LDA ICAX1Z
  3181:  8: 29.9 | A=BA:04 X=80 Y=0C (     C) | 00:FA0F: 4A                LSR
  3181:  8: 29.11 | A=BA:02 X=80 Y=0C (      ) | 00:FA10: B0 31             BCS $FA43
  3181:  8: 30.1 | A=BA:02 X=80 Y=0C (      ) | 00:FA12: A9 80             LDA #$80
  3181:  8: 30.3 | A=BA:80 X=80 Y=0C (N     ) | 00:FA14: A6 11             LDX BRKKEY
  3181:  8: 30.6 | A=BA:80 X=80 Y=0C (N     ) | 00:FA16: F0 2D             BEQ $FA45
  3181:  8: 30.8 | A=BA:80 X=80 Y=0C (N     ) | 00:FA18: AD FC 02          LDA CH
+ IRQ interrupt
  3181:  8: 76.9 | A=BA:FF X=80 Y=0C (N     ) | 00:FA1B: C9 FF             CMP #$FF
  3181:  8: 76.11 | A=BA:FF X=80 Y=0C (    ZC) | 00:FA1D: D0 28             BNE $FA47
  3181:  8: 77.1 | A=BA:FF X=80 Y=0C (    ZC) | 00:FA1F: A4 20             LDY ICHIDZ
  3181:  8: 77.4 | A=BA:FF X=80 Y=0C (     C) | 00:FA21: C0 1F             CPY #$1F
  3181:  8: 77.6 | A=BA:FF X=80 Y=0C (N     ) | 00:FA23: B0 DF             BCS $FA04
  3181:  8: 77.8 | A=BA:FF X=80 Y=0C (N     ) | 00:FA25: B9 1A 03          LDA HATABS,Y ;$00:0326
  3181:  8: 78.0 | A=BA:4B X=80 Y=0C (      ) | 00:FA28: C9 4B             CMP #$4B
  3181:  8: 78.2 | A=BA:4B X=80 Y=0C (    ZC) | 00:FA2A: D0 D8             BNE $FA04
  3181:  8: 78.4 | A=BA:4B X=80 Y=0C (    ZC) | 00:FA2C: A5 22             LDA ICCOMZ
  3181:  8: 78.7 | A=BA:07 X=80 Y=0C (     C) | 00:FA2E: C9 05             CMP #$05
  3181:  8: 78.9 | A=BA:07 X=80 Y=0C (     C) | 00:FA30: F0 04             BEQ $FA36
  3181:  8: 78.11 | A=BA:07 X=80 Y=0C (     C) | 00:FA32: C9 07             CMP #$07
  3181:  8: 79.1 | A=BA:07 X=80 Y=0C (    ZC) | 00:FA34: D0 CE             BNE $FA04
  3181:  8: 79.3 | A=BA:07 X=80 Y=0C (    ZC) | 00:FA36: A5 2B             LDA ICAX2Z
  3181:  8: 79.6 | A=BA:00 X=80 Y=0C (    ZC) | 00:FA38: 29 01             AND #$01
  3181:  8: 79.8 | A=BA:00 X=80 Y=0C (    ZC) | 00:FA3A: F0 C8             BEQ $FA04
  3181:  8: 79.11 | A=BA:00 X=80 Y=0C (    ZC) | 00:FA04: A9 FF             LDA #$FF
  3181:  8: 80.1 | A=BA:FF X=80 Y=0C (N    C) | 00:FA06: 8D FC 02          STA CH
  3181:  8: 81.1 | A=BA:FF X=80 Y=0C (N    C) | 00:FA09: CB                WAI

The issue on the emulation side is that the CPU core is ending the WAI instruction too early in high-speed mode, causing a delay between when WAI exits and when the IRQ handler executes. That I can fix, but the reason for the hang is that at 21MHz the IRQ just happens to fire when the keyboard handler code is checking for a new key (read CH). This causes the key to be dropped because CH is updated in between the time that CH is checked and it is cleared. While the loop is aligned with WAI so that most interrupts will occur right afterward, the loop is executed with IRQs unmasked, so this timing should be possible on real hardware. This looks like a legitimate bug, and it seems to me that the 65C816 OS either needs to check and clear CH with IRQs masked or suppress the write to CH if no key is detected.

  • Like 2
Link to comment
Share on other sites

Hmm, I see. The code simply expects that the WAI instruction is completed when the CPU receives an interrupt signal, and that the IRQ handler will fire immediately after the WAI instruction is completed, just according to this statement from the 65C816 data sheet:




NMIB, IRQB or RESB will terminate the WAI condition and transfer control to the interrupt handler routine.


and not at random some 22 clock cycles later. Of course, the WAI instruction is terminated by any interrupt (including VBL), so the keyboard IRQ may still *sometimes* occur at a wrong place. Also, the stock XL/XE OS contains a busy loop there, so it seems to me at first glance that the race condition you are speaking about can also occur there. In either case, however, it looks like it should cause only some keypresses (with not so great probability) to be lost, and not all of them.


In any case, thanks for pointing this out, I will take a look at the source code again.

Link to comment
Share on other sites





Fixes WAI glitch in high-speed mode, fixes debugger expression parsing ambiguity that broke != operator at times (vpos!= was interpreted as a module prefix followed by =, instead of the vpos operator followed by !=), and tweaks formatting on the history view in >=17MHz mode so columns line up.


The race condition would indeed be rare on actual hardware, since it would require the keyboard IRQ to occur very close to a VBI/DLI or other IRQ. I don't believe this race condition exists in the standard XL/XE OS, however. This is the keyboard wait loop in that OS:

F2F8: A9 FF             LDA #$FF
F2FA: 8D FC 02          STA CH
F2FD: A9 00     LF2FD   LDA #$00
F2FF: 8D E8 03          STA $03E8
F302: A5 2A             LDA ICAX1Z
F304: 4A                LSR
F305: B0 6F             BCS $F376
F307: A9 80             LDA #$80
F309: A6 11             LDX BRKKEY
F30B: F0 65             BEQ $F372
F30D: AD FC 02          LDA CH
F310: C9 FF             CMP #$FF
F312: F0 E9             BEQ $F2FD
F314: 85 7C             STA $7C
F316: A2 FF             LDX #$FF
F318: 8E FC 02          STX CH

The polling loop only sets CH=$FF if a key is detected, so IRQ timing will never affect detection of an isolated key. Instead, a race condition can only occur between the time that the key is detected and CH is cleared on exit from the loop. This means that the race can only occur when a second keyboard IRQ occurs almost immediately after the first. Even that case may be practically impossible, though, because on real hardware a keyboard IRQ can only be generated every 193 scanlines -- it takes at more than three full scans of the keyboard matrix to completely cycle around POKEY's keyboard state machine to where the keyboard IRQ can be triggered again. That could only occur within the above code with a crazy amount of interrupt or DMA traffic.


  • Like 3
Link to comment
Share on other sites

Hey guys - when you are posting up chunks of assembler would you mind annotating them a little?


It doesn't have to be every line obviously, but enough so we can see not just what the snippet is supposed to do, but actually how it does it? That would be a fantastic help to the learners among us here.


At its core assembler is ultimately simple - you are 'just' moving data around after performing operations on it, often based on the numerical or logical results of those operations. However looking at a column of code like that can be a real mind-twister to digest if you are still a novice like me at least! The more people who have a good handle on ASM the more who can help out with these types of projects, suggest solutions to group problems or start our own. The scene can only go from strength to strength that way!

Link to comment
Share on other sites

Hey guys - when you are posting up chunks of assembler would you mind annotating them a little?


What, you want this thread to be longer than it already is? :!:


The dumps you see above are literally just copy-and-pasted out of the debugger, so I don't have more details. Also, not sure how others feel, but IMO having such explanations here would probably muddy up the thread more than it already is.. given how much that Altirra attempts to emulate, and therefore attracts discussion on. We do seem to have a lack "learn 6502 assembly" threads in the programming forum, though. I'd be happy to explain the above fragments in such a place, but I'd need to dissect them myself first.

  • Like 4
Link to comment
Share on other sites

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.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...