Shop OBEX P1 Docs P2 Docs Learn Events
Console Emulation - Page 69 — Parallax Forums

Console Emulation

16465666769

Comments

  • RaymanRayman Posts: 15,035

    Nice work @Wuerfel_21 !

  • Here in germany, we have a mythical creature called the Schweinehund ("pig dog") that is said to inspire procrastination.
    Some days you just have to go out and punch those buggers in the snout.

  • roglohrogloh Posts: 5,886
    edited 2025-02-17 05:29

    @Wuerfel_21 , was your Z80 emulator stuff for NeoYume etc always 100% cycle accurate? I've recently ported, (rather translated C into PASM2 assembly) the core of a Z80 emulator codebase I found online (below) for my Microbee emulator project and am emulating the Z80 at 3.375MHz (P2 @270MHz) but then realized you also had done a Z80 emulator for some audio control.

    https://github.com/psychotimmy/picomz-80k/tree/main/zazu80

    This zazu80 codebase nicely tracks the cycle counts and I can then use a compensating getct and waitx etc to pad each instruction out to the exact Z80 execution time values, as the PASM2 code is (always?) faster than a real Z80 at that ratio (I need to prove this out for every single 4 cycle instruction which can get tight, but it appears to be the case so far). All other slower instructions are a breeze for the P2 even when running a lot in HUBEXEC.

    It now passes the zexall/zexdoc tests which are meant to be very thorough and can test those pesky X/Y flag bits and hidden memptr, although I found that the JR instruction was not accurately being tested as I had a bug that was not caught so maybe they're not a perfect test.

    Now it's done and all working I guess I will keep it but was wondering if your code was cycle accurate in all cases. If it wasn't I won't feel as bad doing all this extra Z80 work if I could not have made use of yours instead. Although I did learn a lot in the process. I also emulate a FDC/HDD/CRTC and part of a PIO (sound squawker) which is now enough to boot a system and play some old games I had and doesn't seem to crash. See grabs below. The later Microbee systems also had an optional SN76489 chip which I can probably emulate with a P2 port of SNECOG. Although no games I have ever used it which was a pity. They just had a single toggling bit (like the PC). I'd have to write something for that.

    Code is running on a P2-EVAL with VGA, USB kbd and a custom full size SD card breakout (temporary until I sector copy my old system files onto a micro SD from the full size SD).

    I'll probably post this Microbee emulator project online at some point once it's all done, but I can't supply the original BOOT ROM (although I think there may be some non-copyrighted ones online for the uBee512 project). It also runs CP/M.

  • @rogloh Yes my Z80 tracks cycles, though I wouldn't guarantee the counts are 100% correct in all cases. It also only half-heartedly implements XY flags (Do they have any use to actual software?). Though I think for almost all regular instructions they're correct.

    I think the P2 SNEcog port already exists, too.

    You can probably also include the system ROMs. Likelyhood of someone coming after you is zero. Most home computer emulators include the relevant ROMs IME.

  • Found another bug in MisoYume that was preventing sprites from rendering in Donkey Kong Country. The funny thing here is that the game never writes OAMADD during gameplay and relies on an obscure (read: I didn't know of it before) hardware quirk that automatically resets OAMADD to the last written value on VBlank. I.e. there's actually two OAMADDs. One that holds the current address and auto-increments (and also ostensibly gets trashed by active rendering) and another one that holds just the values written to the register. The latter is latched into the former on multiple conditions.

    Game is still quite broken, but at least DK now bothers to show up. Change is only on dev branch on github for now.

  • evanhevanh Posts: 16,345
    edited 2025-02-17 14:33

    Chip talks a lot about that sort of behaviour with the smartpins. Chip names it as "capturing" of X, Y or Z registers. It doesn't come across very intuitive at all. Myself, I'd just call it copying, duplicating or moving.

  • There we go, fully fixed up! Had a bug in 65816's WAI instruction that was delaying the NMI all the way to line 12 (causing the black bar). Then the HDMA doing the sky gradient would interfere with loading the rest of the color palette into CGRAM and cause corrupted colors.

  • Merged both of these fixes (OAMADD reset and WAI bug) into master branch to make MisoYume beta07. Rejoice!

  • evanhevanh Posts: 16,345

    Those colours do look better. :D

  • TonyB_TonyB_ Posts: 2,204

    @rogloh said:
    This zazu80 codebase nicely tracks the cycle counts and I can then use a compensating getct and waitx etc to pad each instruction out to the exact Z80 execution time values, as the PASM2 code is (always?) faster than a real Z80 at that ratio (I need to prove this out for every single 4 cycle instruction which can get tight, but it appears to be the case so far). All other slower instructions are a breeze for the P2 even when running a lot in HUBEXEC.

    It now passes the zexall/zexdoc tests which are meant to be very thorough and can test those pesky X/Y flag bits and hidden memptr, although I found that the JR instruction was not accurately being tested as I had a bug that was not caught so maybe they're not a perfect test.

    Fixed:

    It now passes the zexall/zexdoc tests which are meant to be very thorough and can test those pesky X/Y flag bits and hidden WZ, although I found that the JR instruction was not accurately being tested as I had a bug that was not caught so maybe they're not a perfect test.

    I don't want to seem pedantic but it does annoy me when WZ is not called WZ, which is the official name first used by Intel for the 8080. WZ[13:0] can be read on the Z80 and the code to do this is fascinating.

  • MisoYume beta08 is upon us. (already? beta07 was yesterday or something...) I added the new video driver with HDMI audio and multiple aspect ratio support. I thought I'd have to do some code changes, but this was not really the case. Though I did find a bug that caused the rendering cogs to have issues syncing with it.

    I set it up to support a few different resolutions. SNES (lowres mode) pixels are slightly wider than they are tall. Luckily, most HDMI displays will stretch whatever resolution you give them to their own aspect ratio (if they're being nice they'll give you a 4:3 pillarbox mode, too). So by choosing an oddball resolution, the pixel aspect ratio can be corrected.

    • 560x480 is for 4:3 displays
    • 672x480 is for 16:10 displays
    • 700x480 is for 5:3 displays (eg. the common 800x480)
    • 748x480 is for 16:9 displays
    • standard 640x480 (with too narrow pixels) is also here for completeness sake
  • roglohrogloh Posts: 5,886
    edited 2025-02-18 23:04

    @TonyB_ said:
    I don't want to seem pedantic but it does annoy me when WZ is not called WZ, which is the official name first used by Intel for the 8080. WZ[13:0] can be read on the Z80 and the code to do this is fascinating.

    Being undocumented I guess not everyone called it the same thing. I first read about it here where it was called MEMPTR, ( https://gist.github.com/drhelius/8497817 ) although I did see somewhere else it being referred to as WZ as well. Calling it WZ probably made more sense given all the other 16 bit registers have two letter abbreviations. It's certainly a strange register and would be useful to know the history as to why it wasn't officially documented to users but given the way it behaves I know it would have been quite difficult to explain its actual use. Perhaps it was intended to be some hidden internal register they used to debug parts of the chip although the only way parts of it seems to be exposed is via those XF/YF bits which doesn't appear to make it all that accessible anyway IMO. As for XF and YF flags, getting bits 3,5 of the result of some ALU op, well, accessing bit 3 of a register could be handy perhaps when you are working with nibbles given bit 7 of the upper nibble is already readily accessible via SF, but reading bit 5 of something isn't really that interesting, and in a few other cases it returns bit 1 instead of bit 5. It's just weird.

  • TonyB_TonyB_ Posts: 2,204

    @rogloh said:

    @TonyB_ said:
    I don't want to seem pedantic but it does annoy me when WZ is not called WZ, which is the official name first used by Intel for the 8080. WZ[13:0] can be read on the Z80 and the code to do this is fascinating.

    Being undocumented I guess not everyone called it the same thing. I first read about it here where it was called MEMPTR, ( https://gist.github.com/drhelius/8497817 ) although I did see somewhere else it being referred to as WZ as well. Calling it WZ probably made more sense given all the other 16 bit registers have two letter abbreviations. It's certainly a strange register and would be useful to know the history as to why it wasn't officially documented to users but given the way it behaves I know it would have been quite difficult to explain its actual use. Perhaps it was intended to be some hidden internal register they used to debug parts of the chip although the only way parts of it seems to be exposed is via those XF/YF bits which doesn't appear to make it all that accessible anyway IMO. As for XF and YF flags, getting bits 3,5 of the result of some ALU op, well, accessing bit 3 of a register could be handy perhaps when you are working with nibbles given bit 7 of the upper nibble is already readily accessible via SF, but reading bit 5 of something isn't really that interesting, and in a few other cases it returns bit 1 instead of bit 5. It's just weird.

    Firstly, CPU emulation is an important part of console emulation so this is on-topic.

    WZ is vital for storing immediate addresses on the 8080 & Z80 and for calculating IX+d or IY+d on the Z80. It would be impossible to branch to or read or write an immediate address without WZ. The register pair WZ and W & Z individually are mentioned in the "Intel 8080 Microcomputer Systems User's Manual" (September 1975) and I've attached copies of pages 2-16 to 2-20. I've also attached a Z80_Instruction_Bytes_M-cycles_T-states_WZ.txt file I created listing how each instruction affects WZ.

    The Z80 F register is a full 8-bit register (unlike the 8080) and the Z80 designers had to choose what to do with the two spare flag bits 5 & 3, usually called YF and XF, respectively. Often these are bits 5 & 3 of the ALU result, however for the BIT b,(HL) instructions YF = WZ[13] and XF = WZ[11] so that WZ can be tested. CPD/CPI decrements/increments WZ , again for testing WZ. The value of WZ[13:0] can be read (albeit slowly) by using both BIT b,(HL) and CPD (or CPI) as shown in my WZread.txt file.

    1720 x 1152 - 683K
    1848 x 1162 - 793K
    904 x 928 - 277K
  • evanhevanh Posts: 16,345

    Pipelining really changed the structure of a processor. The pipeline stages became the holding registers. Instruction sets evolved to suit.

  • ColeyColey Posts: 1,128
    edited 2025-02-21 12:25

    Hi Ada,

    I've tried as best I can but I cannot get MegaYume to compile.
    I'm not that familiar with Linux but I set up WSL witha Debian install, cloned the spin2cpp and megayume repositories.
    Built spin2cpp, faffed around for what seemed an age to get it working as an executable anywhere on the filesystem then tried to build MegaYume.

    then I get this error:

    graham@Coley-PC:~/MegaYume$ ./build.sh
    rm: cannot remove 'megayume_lower.binary': No such file or directory
    Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2025 Total Spectrum Software Inc. and contributors
    Version 7.1.0-beta-v7.0.4-4-g1ef00b56 Compiled on: Feb 21 2025
    megayume_upper.spin2
    |-MegaVGA.spin2
    |-MegaVGA.spin2
    |-usbnew.spin2
    |-padmap_parser.spin2
    megayume_upper.spin2:49: error: Unable to open file `libc': No such file or directory

    Can you help?

  • Wuerfel_21Wuerfel_21 Posts: 5,272
    edited 2025-02-21 12:38

    @Coley
    That means flexspin can't find its library files. It looks for them relative to the executable at ../include. I.e. the include folder needs to be one level up from where the flexspin/flexcc exes are.
    Note that you don't need a real Linux/Unix system to build, it's just the build script that's Unix-style, which should also work with the windows port of bash (which is usually installed as "Git Bash" alongside git-for-windows). One can of course also run the same build commands in a regular windows command prompt (possibly also powershell, but friends don't let friends use powershell)

  • ColeyColey Posts: 1,128

    Git Bash is the way, worked first time! Thanks.

    Now to get some roms on it ;)

  • ColeyColey Posts: 1,128

    Hi Ada,
    I've donloaded the BadApple binary and put that in a folder called MEGYUME on the uSD card. Ive also set the config so that this is loaded automatically.
    I get a grey screen showing that the rom file is being loaded then once that's completed I just get a magenta coloured screen.
    Do you have any theories?

  • @Coley said:
    Hi Ada,
    I've donloaded the BadApple binary and put that in a folder called MEGYUME on the uSD card. Ive also set the config so that this is loaded automatically.
    I get a grey screen showing that the rom file is being loaded then once that's completed I just get a magenta coloured screen.
    Do you have any theories?

    Bad PSRAM setting

  • Wuerfel_21Wuerfel_21 Posts: 5,272
    edited 2025-02-21 15:18

    Oh no, I think flexspin somehow broke again, try downgrading to a version from a few weeks ago v7.0.3 while I bisect it and proceed to get whimsically angry at @ersmith

  • Other solution is to edit build.sh and add peek-args to the optimization list, so it reads -O1,extrasmall,inline-single,peek-args

    I'll have chase @ersmith around with a comically large rubber mallet for disabling-by-default an optimization that is also apparently load bearing (at 23c932f63f4b4b3bd2d8048fef5578a2f58b55c0)
    Annoyingly this results in a huge code diff and I need to go out, so I'll have to debug it later.

  • ColeyColey Posts: 1,128

    No worries, I have many other things to be getting on with, there is no rush. Thank you.

  • ColeyColey Posts: 1,128

    Ada, adding peek-args fixed it so I can test what I need for now.

  • Wuerfel_21Wuerfel_21 Posts: 5,272
    edited 2025-02-21 19:35

    I figured out the bug:

    • Leaf functions all get the same set of pre-rename _tmpXXX_ registers
    • First pass of inline expansion grabs a leaf function with such a temp register, which is thoughtfully renamed to _inline__tmpXXX_
    • Register reuse pass re-uses the temp register across another such leaf function call
    • Second pass of inline expansion expands this call
    • whatever register-reuse placed into the temp register is clobbered by the expanded inline IR

    I'll go figure out a fix that doesn't explode everything...

  • ColeyColey Posts: 1,128
    edited 2025-02-21 20:06

    Hi Ada,

    This is brilliant work and the video looks superb on the iPad LCD screen I have.

    Is there meant to be a top and bottom border? Is it because the native game resolution is 320x224?

    I tried this LCD first with the old HDMI Spiral demo that comes with Pnut and that fills the screen completely.

    See images bolow and excuse the fuzzy pictures...




  • Wuerfel_21Wuerfel_21 Posts: 5,272
    edited 2025-02-21 20:12

    @Coley Yes, the border is meant to be there. Old consoles only generate 224 active video lines, not 240, so borders are needed to get to standard resolutions.
    Also please turn down the sharpening on that monitor, that looks horrendous.

  • ersmithersmith Posts: 6,147

    @Wuerfel_21 said:
    Other solution is to edit build.sh and add peek-args to the optimization list, so it reads -O1,extrasmall,inline-single,peek-args

    I'll have chase @ersmith around with a comically large rubber mallet for disabling-by-default an optimization that is also apparently load bearing (at 23c932f63f4b4b3bd2d8048fef5578a2f58b55c0)
    Annoyingly this results in a huge code diff and I need to go out, so I'll have to debug it later.

    That optimization broke some other programs in interesting and exciting ways, and it should never have been part of -O1. If you really need maximum optimization, use -O2.

  • Wuerfel_21Wuerfel_21 Posts: 5,272
    edited 2025-02-21 20:35

    @ersmith said:
    That optimization broke some other programs in interesting and exciting ways

    Where? Do we have samples of that? If you're talking about the throw thing, that's just an oversight specific to that function (because it creates arg register use without marking as non-leaf or setting maxInlineArg), so that can be fixed better (also the has_throw check in ExpandInlines is pointless and only exists to pessimize functions that used to have a throw that's been eliminated in a dead code pass). If there's other issues I'd rather fix them than disable something really useful that's been in there since 2022. I do not like the idea of the same user code getting worse results over time.

  • ColeyColey Posts: 1,128
    edited 2025-02-21 20:49

    @Wuerfel_21 said:
    @Coley Yes, the border is meant to be there. Old consoles only generate 224 active video lines, not 240, so borders are needed to get to standard resolutions.
    Also please turn down the sharpening on that monitor, that looks horrendous.

    haha I knew you'd notice, there, is that a bit better?

  • @Coley said:
    haha I knew you'd notice, there, is that a bit better?

    Yes, but the saturation is also too high, the blues all clip into each other.
    It's supposed to look like this, remember

    Of course you may also have your PC monitor that you view the forum on set up poorly, etc, etc. (I use an allegely sRGB-calibrated ASUS monitor and even that doesn't match my also allegedly sRGB-calibrated Huion drawing tablet -> colors are hard)

Sign In or Register to comment.