Jump to content

TylerBarnes

Member
  • Posts

    302
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by TylerBarnes

  1. On 12/19/2019 at 9:38 AM, chromableedstudios said:

    Pretty cool idea, are you on nesdev too? Seems like the kind of thing to folks over there might appreciate

    I do have an account over there. I should frequent over there more often. I mostly lurk and read; Not many posts by me. 
     

    19 hours ago, erockbrox said:

    So you could literally create a small game on here like pong or something.

    Yes, in theory, except it is not possible to add anything to the NMI routine in ROM. The code execution currently starts at $0500 So execution runs through from $0500-$07FF, But I could move the sprites from $0300 up to $0200, then move execution to start at $0300. Then one would have from $0300-$07FF free for machine code. The idea I had for it is not that big in scope though. 

  2. So I'm working on learning more about the NES and at the same time like talking about what I'm working on. In this case it's compression for a single screen.  Made this as a sort of 'get my thoughts in order' video to help myself learn. As well as, I hope someone else at the same sort of level of learning as I am could get some help from it. Furthermore, I am also hoping that by talking about what I am doing, I could get corrected by more experienced coders if I'm doing stuff poorly. I plan on making more regarding decoding uncompressed strings and special cases. 
     

     

    • Like 1
  3. So, this is something I'm trying to develop further into more of a game sort of thing, but I got the mechanic working and think it is fun enough to share. Machine code editing done natively on the NES. ^_^ 

    (The indexing bug was figured out. I was decrementing and using BNE to loop, so naturally when the index hit #$00, it escaped the loop and didn't write $0500 index 0.)
     

     

    • Like 1
  4. 2 hours ago, MrWunderful said:

    and my dude @TylerBarnes music release, Moonfall (outstanding btw)

    You are too kind. Thank you, sir! Collection looks great btw ^^ 

    Also, I have never seen that red bordered Blades of steel before. Had no idea that was even a thing. 

    • Like 1

  5. Thank you that makes a lot of sense. Instead of having an array length (Which can possibly be larger than $FF, so extra logic would have to be written), it is a better idea to just have an ending marker and detect it's value to end the stream. And a starting marker to tell if it is a compressed stream or uncompressed. 

    However,  the syntax you are using is confusing to me; This took me a few moments to realize what you meant.

    In ASM6 using "decompressFlag = $FF" would designate location $00FF in RAM as a variable, and then leave the value #$00 unless initialized in setup or in a routine before hand. It is not for value assignment.

    If the idea is to declare a constant for the decompression routine to detect, you would have to use decimal numbers like

    decompressFlag = 255    ; Assigned the label with value $FF

    or use EQU to equate the label to a string

    decompressFlag EQU $FF   ; ASM6 assembler replaces label with $FF


    However if the idea is to detect $FF as a flag, I do not feel declaring this a variable or constant is too necessary. I would just implement that $FF detection this way with a raw coded value; Set it and forget it. 
     

    	LDY #$00                         ; Set index into Level Data 
    DetectCompress:
    	LDA LevelData, y                 ; Load first item in array 
    	CMP $FF                          ; Compare with value $FF
    	BEQ Decompress                   ; If equal decompress
    Uncompressed:                            ; Otherwise load uncompressed
    	[Load data uncompressed] 
    	RTS
    Decompress: 
    	[Do decompression] 
    	RTS 
    
    LevelData: 
    	.db $FF,$11,$05,$07,$1F,$FE


    ---------------------------------------------------------
     

    5 hours ago, Orab Games said:

    However, now you can't store any tiles in $FE or $FF


    This is actually might not be true, at least the way I'm picturing it.

    So the routine has two main sections after detecting the compressed/uncompressed value, One is fetching the segment length, the other is fetching the tile number. You only need to detect flags for ending the decompression routine while it is attempting to fetch a segment length. Once a length is actually loaded in, it then just blindly loads the tile value and writes that tile N number of times (based on the segment length). This holds true because there is no reason to load a segment length without any tiles to follow. So the end will always be fetched as if it was a segment length and never a tile value. 

    So tiles $FF and $FE in CHR rom are perfectly fair game. It is just that those segment lengths would not be allowed. 

    So if I take my original simplistic RLE example that could look like:
     

    Fetch:
    	LDA (data), y          ; Fetch segmentLength
    	CMP #$FE               ; Detect if end of Array
    	BEQ EndDecompression   ; Exit if true
    	TAX                    ; Set as decrimentor 
    	INY                    ; Incriment Index
    	LDA (data), y          ; Fetch tile
    	.
    	.
    	.
    	.
    EndDecompression: 
    	RTS


    All these different factors makes me realize there would not be a one size fits all, and writing/modifying something tailor made is the way to go for this stuff. 
     

  6. 11 hours ago, Sumez said:

    CA65 is the only 6502/NES assembler I have experience with.

    I've kept using it because so far it's been able to do everything I ever need, and a whole lot more. It also builds for 65816 CPUs, which is a big bonus - no reason to learn new stuf for SNES programming.

    I don't know anything about ASM6, and the only impressions I have of NESASM are the occasional stories that I keep hearing (almost constantly tbh) about various issues with it. Having to manually specify Zero Page access in order to get any advantage from it every single time sounds like a bother.

    That said, my absolute #1 reason for sticking with CA65, however, is the very thorough output of debug symbols it produces when building its output. I'm sure the other assemblers have something similar, but with these one I know for certain that I can use them to make my own custom 6502 programming IDE extremely user friendly, in terms of how breakpoints, and watch values, etc. are assigned.

    EDwrSJWU8AIHC90?format=jpg&name=medium

    That debugger looks slick. 

  7. On 12/8/2019 at 11:58 AM, Sumez said:

    X/Y indexing is the bread and butter of the 6502 along with quick zeropage access 😄 

    It's not very C friendly, but it's very effective when your code and data structure is optimized towards it.

    Very true; Indexing makes many things soooo much easier. My favorite thing to do for code re usability is add pointer support to functions that could be used for multiple tables. Lets say you have different palettes for different levels. 
     

    ;---------------Variables-----------
    data = $C2
    dataH = $C3
    ;----------------Setup--------------
    
    LoadLevel1Palettes: 
    	LDA #<Lev1Pal               ; Load Level1 Palette's  
    	LDX #>Lev1Pal               ; location into a pointer.
    	STA data                    
    	STX dataH
    	JSR LoadPalette             ; Run the load palette routine
    	
    Forever:
    	JMP Forever
    
    ;---------------Subroutines----------
    
    LoadPalette: 
    	LDA #$3F                     ; Load PPU location to write
    	LDY #$00                     ; $3F00 is for Palettes
    	STA $2006                     
    	STY $2006                    
    PalLoop:              
    	LDA (data), y                ; Index into loacation in Pointer (data)
    	STA $2007                    ; Write Byte
    	INY                          ; Incriment Index
    	CPY #$20                     ; Takes 32 writes to complete 
    	BNE PalLoop                  ; Keeps looping till done
    	RTS
    ;----------------Data----------------
    
    Lev1Pal: 
    	.incbin "Level1.pal"

     

  8. 9 hours ago, treed said:

    Although I wonder why I haven't seen other people using BIT for this:

    Never thought to use BIT. Being able to BIT through multiple states in a row on the same button state without additional LDAs would be helpful. 

     

    7 hours ago, Sumez said:

    and of course "MaskLUT+3" doesn't make any sense

    You are right. Brain fart. Of course MaskLUT, y would be to index. I somehow understood deafcode's example and then proceeded to act like I didn't know how to index a table. lol. Thank you for the example. That definitely shows the advantage of a table vs using the bits for different states. 

     

  9. Ah, I see now. I was over thinking in that it was something more specific than that. I personally like the readability of declaring constants with labels. Seeing too many instances of MaskLUT+1, MaskLUT+3, etc in the code would throw me off in the context I am thinking of. Other contexts I'm sure would be great with the above. 

  10. 6 hours ago, RH said:

    What, exactly are you asking? 

    The main inquiry was are people bothering with the extra logic involved when using every bit for flags and masking all the time, or if it is more rare to want/need to use all bits of a byte for flags. 
     

    6 hours ago, RH said:

    but usually you do an AND mask of some form to check a bit, and then branch accordingly.

    Indeed. I forgot to include that sort of section in my example. 

    Jump: 
    	LDA PlayerState  ; Load Player Flags
    	AND #IsJumping   ; Examine Only Jump Flag
    	BNE Skip         ; Skip if flag is set 
    	LDA PlayerState  ; Load Player Flags
    	ORA #IsJumping   ; Set Jump Flag
    	STA PlayerState  ; Save Flags
    	[Do jump stuff] 
    Skip:
    	RTS



     

    5 hours ago, Sumez said:

    using an 8-byte LUT to get the correct mask value.

    Do you have a small digestible example of this lookup table setup? I don't think I can picture what you mean. 

  11. Not sure if it has already been discussed elsewhere, but was wondering....

    Simple projects on the NES are going certainly going to have plenty of slots in RAM to use for various flags, values, and buffer space. However, I could see certain cases where a project gets very large or large ram buffers are used. Anyone ever use a single byte in RAM for up to status 8 flags? 

    I was thinking about this in that having tons of bytes in RAM that only ever toggle from 0 to 1 all the time is wasteful. Also I could see it used as a sort of organisation system if one byte did many related flags. 

    Too convoluted or no? 

    Setting flags in this way could look like this (in my head at least): 
     

    PlayerState = $A0
    IsStunned   = 1
    IsJumping   = 2
    HasPowerUp  = 4 
    IsDead      = 8
    
    GameState   = $A1
    Paused      = 1
    GameOver    = 2
    Credits     = 4
    
    
    Jump: 
    	LDA PlayerState
    	ORA #IsJumping
    	STA PlayerState
    	[Do jump stuff] 
    	RTS
    
    Physics:
    	[Do gravity stuff] 
    	[Do floor detection] 
    	BEQ Landed
    	RTS
    Landed: 
    	LDA PlayerState
    	EOR #$FF
    	ORA #IsJumping
    	EOR #$FF 
    	STA PlayerState
    	RTS
    

     

×
×
  • Create New...