I plan to post code occasionally to see if i can get feedback on what to do better, what won't work, if you can spot any bug, or remarks about better practices. They might as well be collected into one thread.
So here it goes, first function:
A function to interface with a custom peripheral. It uses 4 daisy-chained serial-to-parallel 8bit registers, which in turn feeds 8 BCD to decimal converters, in turn relaying 8x10 nixie tube cathodes.
Now, the hardware side of the NES is always a bit hard to wrap my head around.. so let's check if all my assumptions are OK, and if my code actually corresponds well enough to those assumptions. What do you think?
note:
the shift register i'm using:
http://www.ti.com/lit/ds/symlink/cd4094b.pdf
What do you think? Anything i should work on improving?
Edit: added in "and #7" after posting
Edit 2: I suppose that jmp at the bottom is replacable with bne.
So here it goes, first function:
A function to interface with a custom peripheral. It uses 4 daisy-chained serial-to-parallel 8bit registers, which in turn feeds 8 BCD to decimal converters, in turn relaying 8x10 nixie tube cathodes.
Now, the hardware side of the NES is always a bit hard to wrap my head around.. so let's check if all my assumptions are OK, and if my code actually corresponds well enough to those assumptions. What do you think?
Code:
;assumptions:
;-port 2 clk can be used to clock the shift registers (rising edge type).
;-port 2 data 1 is used to feed serial data to shift registers (in turn feeding bcd to decimal decoders)
;-port 2 data 2 is used to enable input on shift registers
;-port 2 data 0 is unused as to not strobe controller 1. maybe pedantic.
;-instead, we may tie data 0 to "output enable", ie. results are not shown on shift register outs until controller is strobed once per frame as an automated quantizer to reduce update rate on the nixie tubes.
;-this means we might be able to update score at any point in the loop; results are still updated on the displau itself on a per frame basis.
;which could save us the "displayPending" var.
;-we're only storing one BCD per array entry. We could bitpack one in each nybble, but i don't care to at this time.
;-cable is known to have all three data lines.
;======
lda displayPending ;might not be warranted to keep a pending var.
beq skipDisplay
dec displayPending ;is now 0 again
ldx #0
ldy #0
displayBigLoop:
lda myScore,y ;y can be 0-7; asserted in loop. each value holds just 0-9 in the lower nybble.
sta temp ;now holds our score buffer
displaySmallLoop:
lda temp
and #1
asl ;moves from bit 0 to bit 1; which we use to feed the shift register with data.
ora #%00000100 ;we use data 2 as input enable on the shift registers.
sta $2016 ; doesn't affect controller 1, and reversely, controller 1 strobes don't affect nixie display
lda #0
sta $2016 ; input enable goes low.
lsr temp
inx
cpx #32 ;done with all 8 digits (4 bits * 8 places) in our binary coded decimal?
beq skipDisplay:
txa ;used to check for absence of modulo.
and #7
tay ;preparatory for fetching the next myScore,y
and #3 ;check for absence of modulo - if there is none; we're done with one binary coded decimal.
beq displayBigLoop
jmp displaySmallLoop
skipDisplay:
;i might tie data 0 to "output enable" on the shift registers so that score changes only switch at max once per frame, each time controller code strobes the ports.
;else, output enable is meant to be tied high.
rts
;-port 2 clk can be used to clock the shift registers (rising edge type).
;-port 2 data 1 is used to feed serial data to shift registers (in turn feeding bcd to decimal decoders)
;-port 2 data 2 is used to enable input on shift registers
;-port 2 data 0 is unused as to not strobe controller 1. maybe pedantic.
;-instead, we may tie data 0 to "output enable", ie. results are not shown on shift register outs until controller is strobed once per frame as an automated quantizer to reduce update rate on the nixie tubes.
;-this means we might be able to update score at any point in the loop; results are still updated on the displau itself on a per frame basis.
;which could save us the "displayPending" var.
;-we're only storing one BCD per array entry. We could bitpack one in each nybble, but i don't care to at this time.
;-cable is known to have all three data lines.
;======
lda displayPending ;might not be warranted to keep a pending var.
beq skipDisplay
dec displayPending ;is now 0 again
ldx #0
ldy #0
displayBigLoop:
lda myScore,y ;y can be 0-7; asserted in loop. each value holds just 0-9 in the lower nybble.
sta temp ;now holds our score buffer
displaySmallLoop:
lda temp
and #1
asl ;moves from bit 0 to bit 1; which we use to feed the shift register with data.
ora #%00000100 ;we use data 2 as input enable on the shift registers.
sta $2016 ; doesn't affect controller 1, and reversely, controller 1 strobes don't affect nixie display
lda #0
sta $2016 ; input enable goes low.
lsr temp
inx
cpx #32 ;done with all 8 digits (4 bits * 8 places) in our binary coded decimal?
beq skipDisplay:
txa ;used to check for absence of modulo.
and #7
tay ;preparatory for fetching the next myScore,y
and #3 ;check for absence of modulo - if there is none; we're done with one binary coded decimal.
beq displayBigLoop
jmp displaySmallLoop
skipDisplay:
;i might tie data 0 to "output enable" on the shift registers so that score changes only switch at max once per frame, each time controller code strobes the ports.
;else, output enable is meant to be tied high.
rts
note:
the shift register i'm using:
http://www.ti.com/lit/ds/symlink/cd4094b.pdf
What do you think? Anything i should work on improving?
Edit: added in "and #7" after posting
Edit 2: I suppose that jmp at the bottom is replacable with bne.