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

Console Emulation

1303133353654

Comments

  • evanhevanh Posts: 15,192

    That resistor could be bridged on the Eval Boards too.

    IDK, we're going to extreme amounts of RAM here. Is 64+ MB of RAM really going to be used seriously? The current load speed is fine for smaller amounts. The EC32MB is a good amount and its layout is solid too.

    Everything changes from SPI to SD mode, the driver needs a careful going over to transition to 4-bit mode. It'll be a while for me to work on it, I've somewhat committed to using the Prop1 on a paid project and still haven't written anything for it.

  • @rogloh said:
    Makes you realize just how slow SD is, doesn't it. For your 8-bit setup and P2 clock speed, that 96MB of PSRAM itself could be loaded in about 0.6 seconds by my driver with block copies if you had it in HUB RAM, but it takes another 24s or so to read it in and process it before writing to the PSRAM.

    You might want to consider inlining some of the per long processing work in this code using asm or org blocks if that is contributing anything to the slowdown vs the SD transfer. I was able to speed up some of my own graphics code quite a lot with that approach in flexspin. Given this is done in a loop I'd go for asm block vs org block as org uses FCACHE and you don't want to suck in the inlined code zillions of times.

    Decided to try doing inline ASM for CROM load (since that's the big one). Also, since the transform isn't in-place, the PSRAM write is now asynchronous. It's a little bit faster, but not really noticeably.

        LOAD_CROM:
          c.fread(MKRAM_BASE+$0000,1,$4000,f1)
          c.fread(MKRAM_BASE+$4000,1,$4000,f2)
          exmem_sync()
          org
              wrfast #0,##MKRAM_BASE+$8000
              loc ptrb,#\MKRAM_BASE
              mov tmp,#256
          .loop1
              rep @.loop2,#8
              rdlong i,ptrb[$00/4]
              rdlong j,ptrb[$20/4]
              bitnot ptrb,#encod $4000
              rdlong k,ptrb[$00/4]
              rdlong l,ptrb[$20/4]
    
              getword tmp2,l,#0
              rolword tmp2,j,#0
              mergeb tmp2
              wflong tmp2
    
              getword tmp2,k,#0
              rolword tmp2,i,#0
              mergeb tmp2
              wflong tmp2
    
              getword tmp2,l,#1
              rolword tmp2,j,#1
              mergeb tmp2
              wflong tmp2
    
              getword tmp2,k,#1
              rolword tmp2,i,#1
              mergeb tmp2
              wflong tmp2
    
              sub ptrb,##$4000 - 4
          .loop2
              add ptrb,#$20
              djnz tmp,#.loop1
          end
          exmem_write(target+pos,MKRAM_BASE+$8000,$8000,true)
          pushed:=$8000
    
  • Ok, was probably worth a shot anyway. I also tried today to add some DEBUG time printing to this SD block read code to see where the bottlenecks were but hit build issues when debug mode was enabled for this file.

  • @evanh said:
    Is 64+ MB of RAM really going to be used seriously?

    What counts as serious in your book?

    I do take responsibility for NeoYume starting the proliferation of oversized memory expansions.

  • hinvhinv Posts: 1,252

    @rogloh said:

    @evanh said:
    Or 8-bit DDR (sysclock/1). :D

    Will it ever be reliable enough though? Can anyone make a board that has fine enough clock control for delay tuning and use it with P2-EVAL? We couldn't really achieve it reliably over the full frequency range with HyperRAM and P2-EVAL as I recall. Maybe on a dedicated P2 board with really short wiring it's feasible but the P2 EVAL itself introduced some timing skew etc and some header positions were better than others. We'd need a way to change the phase of the clock that ideally has several more steps that what we can coarsely achieve with registered/unregistered clock and data pins, and some process to track errors and adjust it over time. That complicates the board design. In comparison 16 bit PSRAM at sysclk/2 is much easier to manage vs DDR 8 bit with the same bandwidth but less IO pins.

    What is the current max bandwidth on a P2-EC32MB?

  • Wuerfel_21Wuerfel_21 Posts: 4,511
    edited 2022-07-07 23:55

    @hinv said:
    What is the current max bandwidth on a P2-EC32MB?

    Transfers are 1 byte / clock cycle. Not sure what frequency it stops working at, but is reliable at 338 MHz, so 338 MByte/s theoretical. In practice it is a bit lower since there is maximum transfer length and each new transfer needs to send a couple bytes worth of setup.

  • hinvhinv Posts: 1,252

    @Wuerfel_21 said:

    @evanh said:
    Is 64+ MB of RAM really going to be used seriously?

    What counts as serious in your book?

    I do take responsibility for NeoYume starting the proliferation of oversized memory expansions.

    The bigger, the better, IMHO. This opens up possibilities for better development environments right on the P2, and so will faster microSD drivers.

    I just watched the forum video last night, and I am really impressed! I recently got the P2-EC32MB and a Johnny Mac, but I can't seem to find my prop plug anywhere. So, while I am ordering, what other accessories do I need to get this running? Will VGA work, or do I need hdmi? What USB controllers are there that should work and are readily available? I vote for an Amiga Emulator as your next project. I know it's not the same as running ROMs, but even if half of the boards memory is disabled to get better granularity on the writes (rather than read-modify-write), there aren't a lot of Amiga games that use more than 16MB. Most use less than 2MB! Would you like to borrow a PiStorm outfitted Amiga to help the process along?

  • hinvhinv Posts: 1,252

    Actually, a C64 or C128 emulator would be awesome too, but you're closer to an Amiga emulator it seems. The sticky thing about the C64 & C128 (aside from CP/M mode) is that many of the games count on exact processor cycle speed. The Amiga was the first commodore where you could upgrade the CPU and games remain mainly compatible.

  • hinvhinv Posts: 1,252

    If you want to step it up a notch, implement an Amiga emulator with a PiSTORM emulating the CPU! Now THAT would be a challenge! Could you handle it? Games would load at over 20MB/sec, memory bandwidth for fastRAM is NOT a problem, Chip RAM connected to the P2 would only need to be 2MB, and 150MB/s is overkill for that.

  • hinvhinv Posts: 1,252

    Now that I think of it, the PiSTORM could be emulated also to avoid the double level shifting and the CPLD would likely add needless latency.

  • @hinv said:
    So, while I am ordering, what other accessories do I need to get this running? Will VGA work, or do I need hdmi? What USB controllers are there that should work and are readily available?

    VGA, HDMI, composite, S-Video and YPbPr all work.

    USB controllers supported currently:
    - Keyboard
    - Anything using the XBox360 XInput protocol
    - Retro Bit SEGA 6 button controller
    - Neo-Geo mini controller (warning: uses Type C plug, get an adapter)

    The latter is obviously quite ideal. Matching button labels and the weird thumb slider is great for inputting circle moves for fighting games, which make up some 50% of neogeo games.

    You can edit the code to support basically anything though.

    I vote for an Amiga Emulator as your next project.

    Well, as said, I don't plan on making another one soon. And I'd probably go for another game console. They don't have headscratchers like disc drives to worry about. Also, can't have keyboard+joystick with the USB driver only supporting one device.

  • hinvhinv Posts: 1,252

    @Wuerfel_21 said:

    @hinv said:
    So, while I am ordering, what other accessories do I need to get this running? Will VGA work, or do I need hdmi? What USB controllers are there that should work and are readily available?

    VGA, HDMI, composite, S-Video and YPbPr all work.

    USB controllers supported currently:
    - Keyboard
    - Anything using the XBox360 XInput protocol
    - Retro Bit SEGA 6 button controller
    - Neo-Geo mini controller (warning: uses Type C plug, get an adapter)

    The latter is obviously quite ideal. Matching button labels and the weird thumb slider is great for inputting circle moves for fighting games, which make up some 50% of neogeo games.

    I think I'll go with the Retro Bit SEGA 6 button controller. I am no interested in the fighting games anyways, but that Metal Slug series sure looks fun!

    @Wuerfel_21 said:

    @hinv said:
    I vote for an Amiga Emulator as your next project.

    Well, as said, I don't plan on making another one soon. And I'd probably go for another game console. They don't have headscratchers like disc drives to worry about. Also, can't have keyboard+joystick with the USB driver only supporting one device.

    If you are up to a PiSTORM challenge, the hard drive and floppy drive emulation is already handled by the [https://github.com/captain-amygdala/pistorm](PiStorm code).
    For Keyboard, PS/2 is better anyways (good old quality mechanical keyboards and lower latency), and the AMIGA only does 5 contacts that can be emulated with a single pin and some resistors if pins are short. The mouse uses the same DB9 port, but I am unsure of the protocol.

    I understand you need a break though. It is amazing what you have done in a short time with MegaYume and NeoYume.

  • hinvhinv Posts: 1,252

    ...but if you really want to do a "Console", have you checked into the CD32? (wink)

  • Wuerfel_21Wuerfel_21 Posts: 4,511
    edited 2022-07-08 01:33

    Unrelatedly,

    after making my head go waku waku against the desk for a few hours, I have infact debugged why Waku Waku 7 crashes on startup. It was indeed the remaining 68000 bug of legend. It turns out to be this: When loading a WORD into a data register, the high bits are untouched. When loading a WORD into an address register, the value is sign-extended and the entire register is changed. I apparently overlooked this distinction in the code for MOVEM.
    This is apparently a rare (because kinda pointless) enough operation that most programs work out just fine with the bug.

    So what happens is this:

    • some registers are loaded from a structure, among them A1, using the buggy MOVEM.W instruction. This means the upper half of A1 is still its previous value. (For the first failed run, the intended value is $0000_07FC, but it gets $0003_07FC)

    • quite a bit further down, an offset (pointer into high ROM) is added to A1, the pointer is dereferenced into A0 and the whole thing stores back into the structure. Because A1 is bad, A0 is loaded with bogus values.

    • At some point, this stored value is loaded back and used for an indirect function call (thanks for nothing, Ghidra. Didn't even think this was executable at first)

    • That eventually reads a word from A0, which crashes if the address isn't aligned (this actually only happens after a couple of iterations where the bug either doesn't manifest because bits 16..23 of A1 were already zero before MOVEM or the bogus value happens to be even)

    Fixing this does infact make Waku Waku 7 work on NeoYume (though with some minor graphical oddities).

    But this really is the 68000 bug of legend, so of course it caused the single longest-standing bug: The broken shadows in Panorama Cotton (remember, one of the first games that worked semi-right in MegaYume). I gave up on debugging that particular game when I realized that it uses some sort of dynamic heap allocator for VRAM and that it actually doesn't use DMA at all.

    Before:

    After:


    ...

    It is 3 AM and i will go to be now. Thanks. (Change will push tomorrow)

  • pik33pik33 Posts: 2,350
    edited 2022-07-08 07:21

    @hinv said:
    Actually, a C64 or C128 emulator would be awesome too, but you're closer to an Amiga emulator it seems. The sticky thing about the C64 & C128 (aside from CP/M mode) is that many of the games count on exact processor cycle speed. The Amiga was the first commodore where you could upgrade the CPU and games remain mainly compatible.

    We have a 6502 made by macca. We have a SID, either original one by Ahle2 or my variation on it - the best for a C64 should be the Ahle's original version with several optimizations I made (unrolled MULs, combined waves in LUT) which improve the speed and don't change the sound (my further changes do change the sound and that's why they should be not used in the C64 emulator). These optimizations allow SIDCog to run at 1/2 of C64 speed instead of 1/4

    What we not have is the VIC

    The 6502 can be made cycle exact: it implements a wait in its main loop so so the emulated 6502 can run exactly at 1:1 speed. We need a C64 owner (or a former owner) nostalgic enough to do this. I didn't have any C64 in my life: I was in the Atari club (and there were of course these "computer wars" - Commodore vs Atari) So I have an Atari 8-bit emulation in mind, but its custom chips (it is a "baby Amiga" and this is another story) are complex. GTIA will be not the easier things to write, its collision registers and sprite priority machine needs a lot of processing power and an FPGA is much better platform to implement this.


    The NeoYume input is in the reality a long at $60. If not using USB, there is a free cog for whatever input you want, so I fit my RPi Zero input interface to it and it works. (then there was a problem, the interface implements a keyboard repeat which I have to remove from there, it makes playing not possible). The craziest idea I have now is to attach a music MIDI keyboard to the NeoYume, it has 61 keys, is big enough for 2 players to sit at and it is designed to withstand hard pressing and beating these keys :) As my input module implements MIDI already, all I need to do is to process it and put the result to $60. Maybe I will try to do this :)


    Well, as said, I don't plan on making another one soon. And I'd probably go for another game console. They don't have headscratchers like disc drives to worry about. Also, can't have keyboard+joystick with the USB driver only supporting one device.

    Do not emulate a disk drive, use the real one instead: https://github.com/adafruit/Adafruit_Floppy
    The Amiga compatible joysticks and mice are still made for the Amiga community. They use DB9 connector.

  • roglohrogloh Posts: 5,171
    edited 2022-07-08 07:31

    @pik33 said:
    The craziest idea I have now is to attach a music MIDI keyboard to the NeoYume, it has 61 keys, is big enough for 2 players to sit at and it is designed to withstand hard pressing and beating these keys :) As my input module implements MIDI already, all I need to do is to process it and put the result to $60. Maybe I will try to do this :)

    Midi keyboard to play Metal Slug. LOL. I could try that one out too, it's too hilarious. :D I have a USB+regular midi synth here, maybe I can hack its USB report format - actually I think it's just serial so probably not. But it could be done with a custom COG as you say and an optocoupler input or something.

  • hinvhinv Posts: 1,252

    @pik33 said:
    The craziest idea I have now is to attach a music MIDI keyboard to the NeoYume, it has 61 keys, is big enough for 2 players to sit at and it is designed to withstand hard pressing and beating these keys :) As my input module implements MIDI already, all I need to do is to process it and put the result to $60. Maybe I will try to do this :)

    That is funny. What is the latency over MIDI? I'm guessing that it is significant.

  • pik33pik33 Posts: 2,350
    edited 2022-07-08 09:45

    @hinv said:

    @pik33 said:
    The craziest idea I have now is to attach a music MIDI keyboard to the NeoYume, it has 61 keys, is big enough for 2 players to sit at and it is designed to withstand hard pressing and beating these keys :) As my input module implements MIDI already, all I need to do is to process it and put the result to $60. Maybe I will try to do this :)

    That is funny. What is the latency over MIDI? I'm guessing that it is significant.

    Why? Midi is in reality a serial at 31250 bps. Key on and key off are 3 bytes messages so the transmission time is about a milisecond. It is impossible to play music with a big latency. I tried to play MIDI keyboard connected to the RPi with audio output via HDMI. This is simply not possible, the 50 ms or something like this audio latency makes your brain suffer. The same RPi, the same program, but audio output via i2s with 3 ms latency = good experience.

    Now, I am experimenting with synthesizer stuff ( the code is available at my P2-Retromachine repo). The stuff is now simple, experimental (=how to use CORDIC fast enough) but I can actually hear the latency difference between a P2 and a RPi with i2s audio. P2 is better, simply because there are no buffers in the driver at all. It receives a MIDI command "note on", it passes the command to the driver and the driver starts to play at the next sample, so only lag in this environment is the keyboard itself and MIDI transmission time. I have a Novation Impulse, they say they sample the keyboard at 10 kHz. This means what is left is the serial transfer lag. One milisecond.

    The best "real" computer for a MIDI is still an Atari ST. It has native midi ports serviced directly by a CPU via serial controller chip and interrupts the chip can generate, so the ST can react immediately when the command arrives. That is important for a good music experience

    USB MIDI is not a serial port. https://www.usb.org/sites/default/files/midi10.pdf

    The simpler thing is create an optocoupler or even connect it directly using resistors and a 3v3 Zener diode. The simplest way is to buy a breakout board and that's what I did (and I still had to solder it but at least I got a ready board and a set of parts)

  • pik33pik33 Posts: 2,350
    edited 2022-07-08 10:11

    A midi cog code. A readmidi() method provides a midi record as a long. If zero, no MIDI received. For the convenience, as the long is always 4 bytes, the bytes in the long returned are sent in the order like this:

    • byte #3 is always the command
    • byte #2 is a value only for Novation Impulse sysex workaround (it sends 6-bytes SYSEXs for the transport buttons instead of standard MIDI controller/value), for the rest of commands it is always 0
    • byte #1 is controller or note
    • byte #0 is controller value or velocity
    ' A midi cog
    ' The purpose: to read and process data from a Midi Shield
    ' v. 0.01 pik33@o2.pl
    '
    con
    
    midiin=29
    midiout=30
    mbaudrate=31250
    
    var
    
    long midifront,miditail
    long midibuf[128]
    long serialstack[64]
    
    '--------------------------------------------------------------
    pub dummy()
    
    repeat
    'this is the object and not a program
    
    '--------------------------------------------------------------
    
    pub start() :cog
    debug(udec(1))
    cog:=cogspin(16,serialcog(),@serialstack)
    return cog
    
    '--------------------------------------------------------------
    
    pub readmidi:midi |result
    
    if midifront<>miditail
      result:=midibuf[miditail]
      miditail++
      miditail:= miditail // 128
    else
      result:=0  
    return result
    
    '--------------------------------------------------------------
    
    pub serialcog()| rr, mrr, srr, b, mb, midireport
    
    'start midi
    
    serial_start(midiin,midiout,mbaudrate)
    mb:=(-1)
    b:=(-1)
    midifront:=0
    miditail:=0
    
    repeat
      mrr:=rxcheck(midiin)
    
    ' midi. Must be >= $80 for a command
    '$80-$8F - 3 bytes note off. note, velocity
    '$90-$9F - 3 bytes note on, note, velocity
    '$A0-$AF - 3 bytes poly aftertouch. note, value
    '$B0-$BF - 3 bytes control change, controller-value, 
    '$C0-$CF - 2 bytes program change
    '$D0-$DF - 2 bytes mono aftertouch
    '$E0-$EF - 3 bytes pitch bend, $2000 - center
    '$F0-$FF - 1 byte
    
    
      if ((mrr>=$80) && (mrr<=$BF)) || ((mrr>=$E0) && (mrr<=$EF)) 
        mb:=2
        midireport:=mrr<<24
    
      if (mrr>=$C0) && (mrr<=$DF)
        mb:=1
        midireport:=mrr<<24
    
      if (mrr>=$F0) 'TODO: do something with SYSEX, now a workaround for Novation Impulse
        mb:=4
        midireport:=mrr<<24  
    
      if (mrr<$80) && (mb>0) && (mrr>=0)
        mb--
        if mb<3
          midireport+=mrr<<(mb<<3)
    
      if mb==0
        if midifront<>((miditail-1) //128)
          midibuf[midifront]:=midireport
          midifront+=1
          midifront:=midifront // 128
        mb:=(-1)
    
    ''---------------------- Serial functions from jm_serial.spin2, modified
    
    pub serial_start(rxpin, txpin, baud) | bitmode
    
    bitmode := muldiv64(clkfreq, $1_0000, baud) & $FFFFFC00       ' set bit timing
    bitmode |= 7                                                  ' set bits (8)
    pinstart(rxpin,P_HIGH_15K|P_ASYNC_RX,bitmode,0)
    pinstart(txpin,P_ASYNC_TX|P_OE,bitmode,0)
    pinhigh(rxpin)
    
    pub rxcheck(pin) : rxbyte | check
    
    '' Check for serial input
    '' -- returns -1 if nothing available
    
      rxbyte := -1
      check := pinr(pin)
      if (check)
        rxbyte := rdpin(pin) >> 24
    
    pub tx(pin,b)
    
    '' Emit byte
    
      wypin(pin, b)
      txflush(pin)
    
    pub txflush(pin) | check
    
    '' Wait until last byte has finished
    
      repeat
        check := pinr(pin)
      while (check == 0)
    
  • @pik33 said:

    @hinv said:
    Actually, a C64 or C128 emulator would be awesome too, but you're closer to an Amiga emulator it seems. The sticky thing about the C64 & C128 (aside from CP/M mode) is that many of the games count on exact processor cycle speed. The Amiga was the first commodore where you could upgrade the CPU and games remain mainly compatible.

    We have a 6502 made by macca. We have a SID, either original one by Ahle2 or my variation on it - the best for a C64 should be the Ahle's original version with several optimizations I made (unrolled MULs, combined waves in LUT) which improve the speed and don't change the sound (my further changes do change the sound and that's why they should be not used in the C64 emulator). These optimizations allow SIDCog to run at 1/2 of C64 speed instead of 1/4

    What we not have is the VIC

    The 6502 can be made cycle exact: it implements a wait in its main loop so so the emulated 6502 can run exactly at 1:1 speed. We need a C64 owner (or a former owner) nostalgic enough to do this. I didn't have any C64 in my life: I was in the Atari club (and there were of course these "computer wars" - Commodore vs Atari) So I have an Atari 8-bit emulation in mind, but its custom chips (it is a "baby Amiga" and this is another story) are complex. GTIA will be not the easier things to write, its collision registers and sprite priority machine needs a lot of processing power and an FPGA is much better platform to implement this.


    The issue is less the CPU running at the right speed, it is the precision of interaction between CPU and VIC2. VIC2 is unusual in that it has a lot of internal state. Most video chips do not carry any state between lines. So for example addresses for characters/attributes are computed from current X/Y position on the fly. Whereas on VIC, it's actually a counter that resets every frame and counts up whenever new data is read (which it unusually only does every 8 lines using DMA and then reuses for the next 7 lines - more state!). The sprites are also a state machine each, with their own little 6 bit address counters. And all of these can be glitched with precise timing for interesting effect. And they are, even late era commercial games do it (see Mayhem in Monsterland).

    The Atari chipset is odd in that it is waaay overengineered for what it actually does. Like, does it really need to be this complex when you have to mush together all (well, excluding the missiles) the sprites to create one (1) 16px wide 3 color object (that can't move vertically, lol)? Could probably do the GTIA processing in one cog, though it'd have to be some slightly odd structure to account for the sillyness.

  • pik33pik33 Posts: 2,350
    edited 2022-07-08 12:33

    PM graphics itself is simpler to implement than real sprites and that's why it is done this way. You don't need to control Y sprite, add offsets, etc, while moving the sprite vertically can be done by CPU in VBLANK. This is 1979 hardware! C64 is 3 years younger.
    But then, in GTIA, (near) all can collide with all other and the collision registers have 64 bits to set

    However, several new Atari8 games use PM graphic to make multicolor hires modes:

    Or to make transparency effects:

  • @pik33 said:
    PM graphics itself is simpler to implement than real sprites and that's why it is done this way. You don't need to control Y sprite, add offsets, etc, while moving the sprite vertically can be done by CPU in VBLANK. This is 1979 hardware! C64 is 3 years younger.
    But then, in GTIA, (near) all can collide with all other and the collision registers have 64 bits to set

    That's what I meant though. If they dropped some of the weird features, they could have given it more "raw power". Perhaps less interesting to mess around with 40 years after the fact, but would've been better at the time.

    The pixel collisions being discrete enough to be actually useful is pretty unique. Though general game design wisdom says that in most cases, you don't actually want pixel collision (Like, if your guy wears a hat, you probably don't want that to be part of the collider shape), but I think that took some time to be discovered.

    In practice, I'm not aware of a single video chipset that doesn't have some stupid-in-hindsight design choices. Well, I've actually found the NeoGeo chipset to be rather well designed, but I feel that's just because it is really focused on doing the one thing that it does. You couldn't just build a general computer out of it, it'd totally suck. I guess the inability to stretch (i.e. enlarge) sprites vertically is really silly (would literally just need to make use of high half of L0 ROM). Though maybe that's intentional - maybe the designers thought stretched graphics look bad and intentionally didn't make it available.

    The stupidest chipset I'm aware of might actually be the SNES PPUs. Full of pointless features and oversights. Like, there's a (basically never used) bit that will set the 8bpp layer to use direct RGB332, bypassing the palette RAM, but zero is still transparent so you can't have black and instead of filling the lower bits by replication, they actually come from the tile palette bits. And even then, you can't actually get true white. Cool. But then you have silly hardcoded stuff. sprites with palettes 4..7 can never have color math enabled. Like, they could have made a register to control it per-palette. And of course each sprite can either be "small" or "large". You can configure what these sizes mean, but only from preset pairs. Also the layout of this attribute in OAM is just the worst thing to be trying to manipulate with a 6502-derived CPU. And then there's the classic banger where writing to VRAM outside of blanking just doesn't do anything. You could also argue that mode 0 (4 2bpp layers) is rather pointless and that the entire BG4 logic could have been eliminated to make room for something better.

  • Unrelatedly, it has been discovered that the MOVEM issue was also responsible for the crashing in Contra Hard Corps.

  • Wait a second is that right?

    MOVEM is always sign-extending?

  • Yep, does seem like it - fixes the weird sprite issues in Waku Waku 7

  • It turns out that thanks to Last Blade's practice mode, I now have a somewhat easy to reproduce test case for this obnoxious issue where a repeating sample doesn't stop properly. Something something sample end register?

  • It turns out there was something wrong. Triggering a new sample should infact not clear the EOS flag. But when I removed that, the run sound just retriggers constantly (electrofart). Turns out the register that can clear the EOS flag never actually gets written because of a typo.

    Fixing that just brings back the original problem though...

  • Ok, was a really stupid oversight: When an ADPCM channel is disabled, I still have it run most of the update code (so that the cycles used don't fluctuate too much). Since ADPCM-A only uses the bottom 20 bits to compare the end address, a disabled channel would set the end flag every (2^20 * 2 * 144 * 3) / 8Mhz == 133 seconds?. Anyways, since the run sound is canceled prematurely, its end flag is set when the sample would have naturally ended.

    Solution is obvious, only set EOS when sample is actually playing. Owie ouch.

  • Wuerfel_21Wuerfel_21 Posts: 4,511
    edited 2022-07-09 16:57

    Wait, it seems that just gave way to even more bugs. More obnoxious bugs even. Completely wrong sounds playing. As if it just ignores the sample end point and plays through the entire ROM.

    EDIT: Seems to be a "magic NOP" type issue. Fixing the EOS stuff deleted two instructions, adding one NOP somewhere way further down does infact fix it again (for the one test case I am using, anyways). Also found another logical bug: ADPCM-A was always playing 2 samples too much and it was only using 19 bits of the end register. Might get rid of some clicks or smth.

    EDIT 2: now I can't reproduce it anymore. I guess that counts as fixed.

    EDIT 3: Ack, now it did happen again. Screw it, I'm just leaving them NOPs there.

    EDIT 4: AAAA IT HAPPENS WITH NOPS NOW
    Ok, it is not a "magic NOP" issue, it is a "Smile this Smile" issue.

  • Wuerfel_21Wuerfel_21 Posts: 4,511
    edited 2022-07-09 17:04

    Huh, the forum software censors Smile? Well that's new.

    code block safe?

    Smile
    Smile
    

    Smile?

Sign In or Register to comment.