Hello,

I've been having some fun adding new features to glitchNES and customizing the .asm code.   However, I have run out of buttons.   Is there an easy way to have it support the multitap/four score adapter and plug it into the code, so that I have more options to play with?

I'm hoping it's as simple as the code for controllers 1 and 2 are, but somehow I have my doubts and fears about such simplicity.

Also, since it's easy enough to swap button functions for controller 1 and 2, what should I assign the turbo buttons on the nes advantage to for maximum carnage?

Any ideas/thoughts on this?

Yeah, it's quite simple:

http://wiki.nesdev.com/w/index.php/Four_Score

Just a bunch of reads from $4016 and $4017. That page even shows you how to build your own Four Score hardware.

In this case, you'd need to do something similar to this:

        LDX #$00
ReadCon1:
    LDA $4016
    LSR
    ROR con1Buttons
        INX
        CPX #$08
        bne ReadCon1

        LDX #$00
ReadCon3:
    LDA $4016
    LSR
    ROR con3Buttons
        INX
        CPX #$08
        bne ReadCon3

        LDX #$00
ReadCon2:
    LDA $4017
    LSR
    ROR con2Buttons
        INX
        CPX #$08
        bne ReadCon4

        LDX #$00
ReadCon4:
    LDA $4017
    LSR
    ROR con4Buttons
        INX
        CPX #$08
        bne ReadCon4

Last edited by jefftheworld (Dec 14, 2015 9:01 pm)

The thing is, No Carrier's code is pretty straightforward here, and I can understand what it's doing.   I'm not sure how to make #3 and #4 this simple.

;       ---------------------------------------------------- controller #2

CheckSelect2:
    LDA #%00000100
    AND JustPressed2
    BEQ CheckStart2

        lda flash               ; toggles flashing background color #0
        eor #$01
        sta flash

CheckStart2:
    LDA #%00001000
    AND NewButtons2         ; notice this is NewButtons2
        BEQ NoPause

        lda #1                  ; if start is held, pause everything
        sta pause
        jmp CheckLeft2

NoPause:
        lda #0
        sta pause

CheckLeft2:
    LDA #%01000000
    AND JustPressed2
    BEQ CheckRight2

        ; DO SOMETHING HERE

CheckRight2:
    LDA #%10000000
    AND JustPressed2
    BEQ CheckDown2

        ; DO SOMETHING HERE, TOO

CheckDown2:
    LDA #%00100000          ; changes the screen / NAM & CHR bank
    AND JustPressed2
    BEQ CheckUp2

    DEC ScreenNumber        ; decrement screen number here
        LDA ScreenNumber
        BPL CheckUp2
    LDA #7                    ; equal to total # of screens, starting from 0
    STA ScreenNumber

CheckUp2:
    LDA #%00010000          ; changes the screen / NAM & CHR bank
    AND JustPressed2
    BEQ CheckB2

    INC ScreenNumber        ; increment screen number here
        LDA ScreenNumber
    CMP #8                    ; equal to total # of screens +1, starting from 0
    BNE CheckB2
    LDA #0
    STA ScreenNumber

Don't worry, it'll be just as easy. Each controller has three bytes of memory defined as labels; NewButtons, OldButtons & JustPressed for controller 1 and NewButtons2, OldButtons2 & JustPressed2 for controller 2. Each controller is done the same way, however, so I'll explain it for a single controller first.

NewButtons = $41
OldButtons = $42
JustPressed = $43
NewButtons2 = $46
OldButtons2 = $47
JustPressed2 = $48

The very first thing he does in the controller_test routine is to copy NewButtons over to OldButtons. This happens each time at the very start of the routine - before polling for new values from the controller - because OldButtons represents the buttons pressed last time the routine was checked.

controller_test:

        LDA NewButtons
    STA OldButtons

Next, he polls the first controller 8 times to get each serial bit and stores all 8 bits as a single byte in NewButtons. He does the same for the second controller and calls it "NewButtons2". (This is what my example above shows; I poll each controller 8 times and store those values in memory locations labeled con1Buttons, con2Buttons, con3Buttons, and con4Buttons.)

ConLoop:
    LDA $4016
    LSR
    ROR NewButtons
        INX
        CPX #$08
        bne ConLoop

He then takes the values from OldButtons, inverts them, and does a logical AND operation with NewButtons. This produces a value - stored at JustPressed - that shows only buttons that have been pressed since the last time the routine was run.

    LDA OldButtons
    EOR #$FF
    AND NewButtons
    STA JustPressed

Finally, it applies a bitmask to this JustPressed  value and checks each bit individually to see if the corresponding button has been pressed. If it has been pressed then execution will fall through to the "do stuff here" area, otherwise it will jump to the next check.

CheckRight:
    LDA #%10000000
    AND JustPressed
    BEQ CheckDown

           ; Do stuff here

CheckDown;

If you look at the code and compare the code for the first and second controllers you'll realize it's identical. So, to adding polling for 2 more controllers you just need to duplicate all that twice more. Obviously, you'll need to define 6 more bytes in memory, for example:

NewButtons3 = $58
OldButtons3 = $58
JustPressed3 = $5a
NewButtons4 = $5b
OldButtons4 = $5c
JustPressed4 = $5d

And you'll need to initialize each OldButtonX at the start of the controller_test routine:

controller_test:

        LDA NewButtons
    STA OldButtons

        LDA NewButtons2
    STA OldButtons2

        LDA NewButtons3
    STA OldButtons3

        LDA NewButtons4
    STA OldButtons4

Etc, etc.

Here's a new one - whenever I try to change the name of any nametable in the glitchnes.asm (or put a different palette name in, for that matter), I get this error upon compiling:

Let's take this:

pic0:
        .INCBIN "order.nam"
pic1:
        .INCBIN "order.nam"
pic2:
        .INCBIN "order.nam"
pic3:
        .INCBIN "order.nam"
pic4:
        .INCBIN "order.nam"
pic5:
        .INCBIN "order.nam"
pic6:
        .INCBIN "order.nam"
pic7:
        .INCBIN "icon.nam"


This will compile fine.   However, say I change it to:

pic0:
        .INCBIN "order.nam"
pic1:
        .INCBIN "order.nam"
pic2:
        .INCBIN "order.nam"
pic3:
        .INCBIN "order.nam"
pic4:
        .INCBIN "order.nam"
pic5:
        .INCBIN "order.nam"
pic6:
        .INCBIN “icon.nam"
pic7:
        .INCBIN "icon.nam"


Upon compiling, I get an error on the line number saying "can't open file".    I got around this with palettes by coding them directly into the ASM, but what's going on here?   I'm trying to import custom nametables and this is breaking all my shit.

slowflood wrote:

Here's a new one - whenever I try to change the name of any nametable in the glitchnes.asm (or put a different palette name in, for that matter), I get this error upon compiling:

*snip*

Upon compiling, I get an error on the line number saying "can't open file".    I got around this with palettes by coding them directly into the ASM, but what's going on here?   I'm trying to import custom nametables and this is breaking all my shit.

I'm sorry, I can't reproduce that issue. It compiles for me even when I change it. If you send me your modified sources I can take a look.

I would say the problem is the quote character.  if you look closely the first quote is 'curved' on PIC 6, while all the other quotes are 'straight'.

pic6:
        .INCBIN “icon.nam"
pic7:
        .INCBIN "icon.nam"

The compiler might not like the curved quotes. I could be wrong but hope this helps!

Editing my code in something that does RTF rather than TXT natively may be the second sick joke of ASM.    I think you're right.

This is sort of like how I spent 45 minutes of my life figuring out that a semicolon in ASM is for commenting out lines, not ending them.

slowflood wrote:

Editing my code in something that does RTF rather than TXT natively may be the second sick joke of ASM.    I think you're right.

This is sort of like how I spent 45 minutes of my life figuring out that a semicolon in ASM is for commenting out lines, not ending them.

What OS are you on? If you're using Windows, Notepad++ is a good, light editor.

Heavy W8 bit, you are literally the wind beneath my wings.

I use OSX and I found something with a flower icon that works fine.   I spent hours of my life trying to figure out why that wouldn't compile.   
Used a different text editor and works like a charm (I run the .bat file through wine)

We like to do custom glitchnes sets for our shows, but this is the first time we've gone beyond .chr editing and adding palettes on the empty left and right buttons on controller 2.    Also, I changed the rate of color blinking and the colors that get changed, although I don't really know what i'm doing.   The changes I made leave a neat "screen tearing" effect though.   The .chr (or pal0.pal) being greyscale is really important to things not looking like shit when the original glitchnes color flasher runs.

Next step is to add mutlitap support (we run this thing patched off a retron 5, so we've got 4 controllers + ready to go) so that I have more buttons to use.  I'd like to implement some of the effects from cmcwavy and possibly some more color palettes.

The thing about changing palettes in the code when assigned to a button is you have to do it all longform with reads/writes to 2006/2007 rather than doing it .byte (palette data) or .INCBIN "palette.pal" or else it'll freeze the code.    Is there a way to do that with nametables also?

What I mean with palettes is:

    lda #$3f
    sta $2006
    lda #$00
    sta $2006
    ldx #$15
    stx $2007
    lda #$01
    sta $2007
    lda #$3a
    sta $2007
    lda #$30
    sta $2007
    stx $2007
(etc. etc.)  - you can assign this to a button in glitchnes and it'll change the palette, which is a good recovery when your glitches have sent your entire color scheme to absolute hell, or even just one big grey blob or something.

Is there a similar notation that can be used for a nametable?

Last edited by slowflood (Dec 16, 2015 3:07 pm)