If the machine code compiled by the C compiler has to do any pointer arithmetic or 16 bit comparisons, both of those will often involve the Carry flag in the 65C02 processor, so the state of the carry flag can be harder to infer in an assembled routine embedded in C code than if you are writing in pure assembly code.
Streaming PCM Audio from SD Card?
Re: Streaming PCM Audio from SD Card?
Re: Streaming PCM Audio from SD Card?
It's a commonly used processor status flag. It's used in addition and subtraction, so it's 1, it's 0... it's all over the place, whatever it happened to be the last time it was used. In THIS particular instance, it's used as a flag to denote an input condition. In the X16's defense? It's actually documented in the github documentation for macptr. But it's the rare bird in that the OTHER calls (That were in existence in the C64 days) are not given that same treatment.
Re: Streaming PCM Audio from SD Card?
I should add this for clarity:
The carry flag is also used for the "error" flag in a lot of the KERNAL calls, and then also used as an error flag in the FAT32 addition. FAT32 uses C=0 as the error, and KERNAL usually used C=1 as the error. In all cases of both of those, the flag is set to the non-error condition at the start of the called routine, so it's not normally needed to enforce it when the routine is called.
But here, it's used as an input condition, so it has to be asserted to the condition you need.
I should have caught that. Sorry.
Edited to change the error status of FAT32 and KERNAL... FAT32 calls use C=1 to indicate success. The KERNAL calls that use carry for that denote C=1 to indicate error. It's actually quite confusing. But this is what happens when you band aid a FAT32 implementation onto a 40 plus year old code monolith with the design condition of "The monolith must be intact!" Heh.
The carry flag is also used for the "error" flag in a lot of the KERNAL calls, and then also used as an error flag in the FAT32 addition. FAT32 uses C=0 as the error, and KERNAL usually used C=1 as the error. In all cases of both of those, the flag is set to the non-error condition at the start of the called routine, so it's not normally needed to enforce it when the routine is called.
But here, it's used as an input condition, so it has to be asserted to the condition you need.
I should have caught that. Sorry.
Edited to change the error status of FAT32 and KERNAL... FAT32 calls use C=1 to indicate success. The KERNAL calls that use carry for that denote C=1 to indicate error. It's actually quite confusing. But this is what happens when you band aid a FAT32 implementation onto a 40 plus year old code monolith with the design condition of "The monolith must be intact!" Heh.
Last edited by Daedalus on Sun Aug 27, 2023 9:19 pm, edited 1 time in total.
Re: Streaming PCM Audio from SD Card?
I was aware of the flag being used as an input from the GitHub documentation and used it for writing to the FIFO, but like I said, I think I assumed it would be '0' unless set to '1'.
But I'm still confused as to how it would only become a problem once and only in some conditions.
With the flag being used for simple things like add and subtract I would have thought the problem to occur something like 50% of the time?
But I'm still confused as to how it would only become a problem once and only in some conditions.
With the flag being used for simple things like add and subtract I would have thought the problem to occur something like 50% of the time?
Re: Streaming PCM Audio from SD Card?
To answer that, I think it's because the carry flag is USUALLY 0. It's set in an ADC instruction when a carry occurs, it's reset in a SBC instruction when a borrow occurs, and it's set by what rotates during ROR and ASL instructions... I think the "heavy lifter" to set it zero there is the ADC, when it's just set to 0 at the start.
The exception is when you do a lot of file activity, as FAT32 operations leave carry at 1.
What happens right at the beginning of a program? file activity.
It's a theory.
The exception is when you do a lot of file activity, as FAT32 operations leave carry at 1.
What happens right at the beginning of a program? file activity.
It's a theory.
Re: Streaming PCM Audio from SD Card?
Here's my guess:
Here's an example from some code I wrote for the NES almost a decade ago:
This is pretty nice when coding only in assembly. When mixing C and assembly, you don't have any guarantee to what the C code has compiled (and optimized!) to, so it's impossible to know whether the carry flag is set or clear, even if it may sometimes look like it's usually clear.
- The memory holding the audio buffer starts out initialized to all-zeroes, probably by the emulator.
- The program loads PCM data.
- The first part of the routine resets the FIFO, then uses MACPTR to fill it, and it works just fine (and was always going to because of the "SEC").
- The second part of the routine calls MACPTR with carry in an undefined state, which happened to be "clear".
- MACPTR fills the audio buffer with 4080 bytes just fine, completely by luck.
- The third part of the routine calls MACPTR with carry in an undefined sate, and unluckily is "set", which is incorrect.
- MACPTR writes to the 4081th byte in the buffer 16 times, leaving the last 15 bytes of the buffer untouched.
- The very first time PCM plays in the program, the untouched bytes are all zeroes, leading to a pop.
- The routine responsible for refilling the audio buffer correctly refills it (probably by chance again, make sure to add CLCs there too), so the last 15 bytes now contain valid audio data.
- When a new PCM file plays, this process happens again, with the same problem where the last 15 bytes in the buffer are not correctly filled, but because these last 15 bytes contain leftover audio data, there may be a subtle audio glitch, but no loud pop like before.
Here's an example from some code I wrote for the NES almost a decade ago:
Code: Select all
; Fill a nametable with the tile in A, and the attribute in X [Affects Y]
; Set PPU address before calling.
; Call ppumanager_fill_attribute to fill only the attribute (set PPU address to the attribute table)
; and put attribute in A
ppumanager_fill
ldy #$78 ;Fill $78 * $8 = $3C0 bytes
sec ;The carry bit is unaffected by all of this code, so let's use it to determine
;which part of the loop we're in (tile filling vs. attribute filling)
ppumanager_fill_loop
sta $2007
sta $2007
sta $2007
sta $2007
sta $2007
sta $2007
sta $2007
sta $2007
dey
bne ppumanager_fill_loop
bcc ppumanager_fill_end
txa ;Get the attribute byte
ppumanager_fill_attribute
ldy #$08 ;Fill $8 * $8 = $40 bytes
clc ;Clear the carry so the above branch succeeds next time
bcc ppumanager_fill_loop
ppumanager_fill_end
rts
Re: Streaming PCM Audio from SD Card?
Step 6:
"The third part of the routine calls MACPTR with carry in an undefined sate, and unluckily is "set", which is incorrect."
Except that it JUST used several of the FAT32 routines over and over to do the first block of data, so the C flag is 1 (C=1 is success)
So there probably wasn't much luck involved.
Yeah, I think your analysis is spot on.
"The third part of the routine calls MACPTR with carry in an undefined sate, and unluckily is "set", which is incorrect."
Except that it JUST used several of the FAT32 routines over and over to do the first block of data, so the C flag is 1 (C=1 is success)
So there probably wasn't much luck involved.
Yeah, I think your analysis is spot on.
Re: Streaming PCM Audio from SD Card?
Followed a hunch...
During the VSYNC interrupt every 1/60 second, ps/2 mouse scan clears the carry flag as a normal part of getting no data... So it would be normal for carry to be generally 0 after startup.
During the VSYNC interrupt every 1/60 second, ps/2 mouse scan clears the carry flag as a normal part of getting no data... So it would be normal for carry to be generally 0 after startup.
Re: Streaming PCM Audio from SD Card?
All this talk about 6502 assembly has made me start to warm up to the idea of re-writing at least some of the more processor expensive code in assembly. Most of my physics and collision code uses 16bit int multiplication and division.
Is it possible to create a sort of asm macro for 16bit operations?
I have written small proc's in 6502 asm, but only with 8bit math.
If I could re-write my physics and collision code in asm my hope would be that the game would run with 4 players.
Is it possible to create a sort of asm macro for 16bit operations?
I have written small proc's in 6502 asm, but only with 8bit math.
If I could re-write my physics and collision code in asm my hope would be that the game would run with 4 players.
-
- Posts: 508
- Joined: Sat Jul 11, 2020 3:30 pm
Re: Streaming PCM Audio from SD Card?
There's 16 bit multiplication in the new VERA, along with some Mode 7 type graphics.