Jump to content


  • Posts

  • Joined

  • Last visited

Posts posted by StinkerB06

  1. On 5/25/2021 at 2:48 PM, ZeroByte said:

    LDX #0
    LDA eal
    STA (eal),X

    LDA eah
    STA (eal),X

    1. (zp),X isn't a valid addressing mode. You have (zp),Y and (zp) without indexing on 65C02.
    2. You never INX (or really, INY) between each STA instruction, resulting in (eal)+0 to be written with eah instead of eal, and (eal)+1 won't be written at all.

    Here's my version (compatible with all 65xx systems):

    LDY #0
    LDA eal
    STA (eal),Y

    LDA eah
    STA (eal),Y

    • Like 1
  2. 8 hours ago, Ender said:

    One thing to note, the upper 4 bits of the value you pass for the bank is used as the increment value for the VERA.  So the upper 4 bits can be any value 0-15, and the only valid value for the lower 4 bits are 0 and 1.

    Don't forget that bit 3 (value $08) is used to make the address stride decrement instead of increment.

    • Like 1
  3. On 10/19/2020 at 1:18 AM, kliepatsch said:

    Looking at them, I think they would rather benefit the keyboard polling code than the actual sound generation, unfortunately.

    You can optimize an LDr #0 / STr pair into an STZ instruction, as long as the addressing mode for the store instruction is ZP, ZP,X, ABS, or ABS,X. If you're using the zero loaded in the register r as a value to pass to a subroutine (e.g. LDA #0; STA address; JSR subroutineThatTakesOnA), you could omit the STZ optimization for easier porting to an NMOS 6502 system.

    X and Y can now be pushed or pulled. On an NMOS, this requires the X or Y register to be transferred to the accumulator before pushing, and transferred back after pulling.

    You can branch relative unconditionally with the BRA instruction in the same way as any conditional branch, like what you used accidentally.

    You can increment or decrement the accumulator, while an NMOS can only increment/decrement X, Y, or memory contents. Slithy pointed out that CA65 just takes plain INC/DEC without an operand specified, but some other assemblers accept A as the operand, and others use the mnemonics INA and DEA.

    The 65C02 also adds #IMM, ZP,X and ABS,X modes to BIT. On an NMOS, testing with a immediate requires the byte to be stored in a literal pool in memory, or the AND instruction to be used at the cost of destroying the value in the accumulator.

    AND'ing or OR'ing directly on memory can be done with the TRB and TSB instructions. Just discard the Z flag (the result of BIT) and back up the accumulator whenever needed. Remember that TRB takes the inverse of the value in the accumulator, but TSB doesn't.

    There's also a (ZP) mode added to all instructions that have (ZP,X) and (ZP),Y. This prevents the need of setting X or Y to zero. For example, I can write a MEMCPY implementation (basically emulates LDIR in Z80) with the source and destination pointers in zero-page, and a 16-bit loop counter in X and Y. If this were an NMOS, I need to put one (or even both) halves of the loop counter in the zero-page.

    There's also a JMP (ABS,X) instruction added, which is very handy for jump tables.

    There's also zero-page-only bit test+branch (BBR, BBS) and manipulation (RMB, SMB) instructions. These were initially only on Rockwell models before they were merged into the WDC design. You won't find these on a 65816, even though it has all other 65C02 instructions. These can't be found on 65C02's from any other manufacturers.

    WDC models also have the WAI and STP instructions that set the processor to a low-power state. The former stops execution until any interrupt occurs, and the latter stops the processor only until a reset occurs. No other 65C02's have these.

    The 65C02 also fixes well-known NMOS bugs such as the infamous JMP ($xxFF) bug and the decimal mode flags bug. Some cycle counts were also changed.

    Is this information helpful for you? Because I still see you LDA #0 before STA and such.

    • Like 1
    • Thanks 1
  4. You don't necessarily have to store all of your sprites in VRAM at once. If you only have one sprite on-screen that uses those 17 frames of animation in the screenshot you posted, just keep one of those animation frames in VRAM at a time and copy the next one from RAM to VRAM when needed. However, this will impact performance.

  5. 4 hours ago, BruceMcF said:

    So the YM2512 is more like the 2612, but fewer channels, but AFAIU, wthout the low frequency sine wave oscillator or the simple PCM channel.

    The YM2151 has more channels (8 versus 6). The YM2612 has only 6 channels and not 7, as the DAC shuts off the 6th FM channel. Both of these have 4 sine-wave operators per channel, and include 8 different ways of combining these operators together.

    The YM3812 is a 2-operator chip that supports 3 more waveforms, and 9 channels. The chip could be switched into a mode which replaces the last 3 FM channels with 5 channels of unique percussion sounds controlled with the FM channels' patch registers. This means the chip can produce up to 11 channels of sound at once.

    • Like 1
  6. 1 hour ago, m00dawg said:

    From what I understand, we won't be getting LFSR support on the VERA, at least currently. The emulator DOES have noise though - I use it in my (bad) Bad Apple cover tune for Command Tracker (a tracker I'm working on loosely based on Impulse Tracker). The noise is...well it's the noise we got if not the noise we want 🙂

    But @Frank van den Hoef did confirm in another thread here that an LFSR is used in the hardware HDL. He didn't give any specifics though, like the LFSR's width and what taps it uses, or if it's shared or per-channel.

  7. Using BNE instead of BRA or JMP is a way to automatically terminate printing if the string ever goes above 256 characters.

    Once X contains $FF (index of the 256th character), and the INX is executed, the value in the register will wrap back to $00. The Z flag in the processor status register is set to indicate a result of zero. Since BNE branches only if Z is cleared, the branch never sends the program back to "Loop" to repeat for any more characters, and falls down to the RTS.

    If you didn't use BNE, then printing a string that's 256 or more characters long will cause the loop to never end, repeatedly outputting the first 256 characters over and over. Unless the interrupt handler somehow modifies the string so that a terminator ($00) is present, you have to reset the machine.

    • Like 1
  8. On 1/16/2021 at 12:40 PM, Johan Kårlin said:

    I do exactly this in my new game project where I use 64 Kb tilemaps. Just change the tilebase address for layer 0 in RAM address $9f2f and copy the character set to the new location.

    I thought I heard the X16 command prompt uses layer 1 and not 0?

  9. The VERA has PSG registers located from $1F9C0 to $1F9FF. I think the best solution is to have the PETSCII character set moved to $1F000, so that bank 0 now holds enough capacity for 64 KB worth of tiles.

    $1F9C0 onwards has no longer been general-purpose video memory ever since the VERA 0.9 changes got put in place. Palette and sprite registers used to be in separate bins, but now they hog the very end of VRAM.

    • Like 1
  10. 1 hour ago, kktos said:

    As a dev, I'm a tad displeased by the change for Bank Switching to ZP $00/$01.....
    Not coherent with all the other system switches (mem location wise, I mean).
    Taking 2 addresses on the tiny and already packed ZP.
    Am I the only one ?

    2 out of 256 bytes? Doesn't sound like very much to me! Those are the same addresses as the 6510's I/O direction and data registers, itself is used in the C64.

    Oh, if I remember, ZP locations $02 to $7F are allowed to be used by the user, locations $80 to $FF are used by the kernel. $02 to $21 supposedly are designed to be sixteen virtual 16-bit registers (or 32 8-bit registers, since changing values in memory must be done on a byte-by-byte basis). You can see these defined within @SlithyMatt's assembly code.

    • Like 2
  • Create New...

Important Information

Please review our Terms of Use