Page 3 of 5
Re: Need help with an incrementing 16-bit pointer
Posted: Wed Oct 16, 2019 10:02 pm
by BigEd
Yep, one way or another, X must be zero.
Re: Need help with an incrementing 16-bit pointer
Posted: Wed Oct 16, 2019 10:06 pm
by EvilSandwich
Yep, one way or another, X must be zero.
Welp, that seems to have worked!
Code: Select all
LDA #$01 ;Initial values
LDX #$ff
LDY #$01
STX $01 ;low byte
STY $02 ;high byte
mainloop: ;placeholder program loop
JSR counter ;increment pointer
LDX #$00
LDA #$01 ;define floor color
STA ($01,X) ;sweep pixel
LDY $02 ;checking high byte
CPY #$05
BNE mainloop ;loop again
LDX $01 ;checking low byte
CPX #$ff
BNE mainloop ;loop again
BRK ;when value is 05ff, end
counter: ;incrementing subroutine
l_up: ;increment low byte
LDX $01
INC $01
CPX #$ff ;check if high byte needs to be incremented
BEQ h_up
RTS ;if not, return to main loop
h_up: ;increment high byte and return to main loop
INC $02
RTS
I still think I should get that book that Garth recommended. Because if this exercise has proven anything, it's that I REALLY need to brush up on how addressing modes work. If only so I'll stop trying to use addressing modes that don't exist. lol
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 4:58 pm
by EvilSandwich
Tackling the original scenario, break it down, so the increment:
Code: Select all
; inc16:
; Add 1 to a 16-bit pointer in zero page
inc16:
inc ptr
bne :+
inc ptr+1
: rts
So what you're saying here is that BNE and BEQ also have a kind of dual function as hypothetical Branch if Zero Flag Clear and Branch If Zero Flag Set opcodes if I ever need that?
Neat!
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 5:05 pm
by GARTHWILSON
That's exactly what they do. Some instructions have been given alias names, like BLT (branch if less than) for BMI, etc.. The programming manuals will tell you that BEQ's function is to branch if the Z flag is set, and BNE's is to branch if Z is clear. (If you do a comparison and the two things are equal, the subtraction will result in 0, setting the Z flag, even if the numerical result is not kept, as in CMP, CPX, and CPY.) An automatic compare-to-zero instruction is built into the following 65c02 instructions: LDA, LDX, LDY, INC, INX, INY, DEC, DEX, DEY, INA, DEA, AND, ORA, EOR, ASL, LSR, ROL, ROR, PLA, PLX, PLY, SBC, ADC, TAX, TXA, TAY, TYA, and TSX.
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 5:13 pm
by EvilSandwich
So really all the compare opcodes do is to kind of force a zero or non zero value to trip the Zero flag to go the way you want?
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 5:44 pm
by drogon
So really all the compare opcodes do is to kind of force a zero or non zero value to trip the Zero flag to go the way you want?
Think of compare like a subtract operation (for that's what is really is), but with the result thrown away.
It's more useful to compare with a value, then you can branch equal (zero flag), greater than or less than.
See here:
http://6502.org/tutorials/compare_instructions.html
-Gordon
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 6:22 pm
by GARTHWILSON
So really all the compare opcodes do is to kind of force a zero or non zero value to trip the Zero flag to go the way you want?
They affect the relevant flags, including N and C, not just Z. BIT also affects the V flag; so for example BIT <port> (like to test an input port), will make the V flag take on the value of bit 6 of the port, regardless of what was in the accumulator. Then there's TSB (test and set bit against accumulator) and TRB (test and reset bit against accumulator) which also affect Z. TRB and TSB are read-modify-write instructions. (It's all laid out very clearly in the programming manual recommended earlier.)
Re: Need help with an incrementing 16-bit pointer
Posted: Sat Oct 19, 2019 6:56 pm
by EvilSandwich
They affect the relevant flags, including N and C, not just Z. BIT also affects the V flag; so for example BIT <port> (like to test an input port), will make the V flag take on the value of bit 6 of the port, regardless of what was in the accumulator. Then there's TSB (test and set bit against accumulator) and TRB (test and reset bit against accumulator) which also affect Z. TRB and TSB are read-modify-write instructions. (It's all laid out very clearly in the programming manual recommended earlier.)
If you're referring to the Programming the 65816 book, I already have it ordered. From a excerpts I read, it looks like a stellar resource. Thanks for the recommendation.
I've also been reading through the primers you wrote in the meantime. They're clearing up a LOT of things. Until then, thanks for putting up with all the rookie questions.
I'm starting to feel like a three year old that's always asking "What's that do?!"
Re: Need help with an incrementing 16-bit pointer
Posted: Sun Oct 20, 2019 8:22 am
by BigEd
I'm starting to feel like a three year old that's always asking "What's that do?!"
Not directly relevant, but there's a
book and
website called "But how do it know?" about the workings of computers.
Re: Need help with an incrementing 16-bit pointer
Posted: Sun Oct 27, 2019 9:25 pm
by EvilSandwich
Okay. Based on all the helpful feedback here, I've tried to refine my screen fill program to be as small as possible while using as few clock cycles as possible. This is as tiny and fast as I can make it for now.
Code: Select all
LDA #$01
LDX #$ff
STX $01
LDX #$01
STX $02
count:
INC $01
BNE main
INC $02
main:
STA ($01),y
LDX $02
CPX #$05
BNE count
LDX $01
CPX #$ff
BNE count
I rearranged the code to remove the need for the JMP command and the only registers being used are the Accumulator and X, so I can take advantage of Y always equaling 0 and use Indirect Indexed Addressing instead to eliminate the need to load 0 into X every loop.
Whittled it down to 30 bytes and the second half of Main is only ever used after the high byte is equal to 05!

Re: Need help with an incrementing 16-bit pointer
Posted: Sun Oct 27, 2019 10:28 pm
by floobydust
Well, here's another baker's routine to fill a memory area from $0200 - $05FF with a byte value:
Code: Select all
; fill screen memory from $0200 - $05FF with a byte value
;
LDA #$02 ;Get start page of $02
STA $02 ;Store to high byte pointer
STZ $01 ;Zero low byte pointer ($0200 start)
LDX #$06 ;Get page limit of $06 ($0600)
;
LDA #$00 ;Load A reg with fill byte (or any other value)
;
LOOP
STA ($01) ;Store fill byte to fill area
INC $01 ;Increment low byte pointer
BNE LOOP ;Loop back until rollover to zero
INC $02 ;Increment high byte pointer
CPX $02 ;Compare against page limit of $06
BNE LOOP ;Loop back back and start next page fill
RTS ;Return to caller
;
23 bytes in all with an RTS, else 22 bytes without it, assuming inline code with something else. Note CMOS processor required.
Re: Need help with an incrementing 16-bit pointer
Posted: Mon Oct 28, 2019 6:40 am
by BigEd
Nice one EvilSandwich. Be sure to initialise Y!
I think there might be another notch of improvement available. As you are counting up, and filling whole pages, INY can probably be part of an inner loop.
You may well then also find that you can BNE or BEQ (as appropriate) without needing to compare against a constant: the Z flag will already be what you want, in the inner loop.
Re: Need help with an incrementing 16-bit pointer
Posted: Mon Oct 28, 2019 7:00 pm
by EvilSandwich
Well, here's another baker's routine to fill a memory area from $0200 - $05FF with a byte value:
Code: Select all
; fill screen memory from $0200 - $05FF with a byte value
;
LDA #$02 ;Get start page of $02
STA $02 ;Store to high byte pointer
STZ $01 ;Zero low byte pointer ($0200 start)
LDX #$06 ;Get page limit of $06 ($0600)
;
LDA #$00 ;Load A reg with fill byte (or any other value)
;
LOOP
STA ($01) ;Store fill byte to fill area
INC $01 ;Increment low byte pointer
BNE LOOP ;Loop back until rollover to zero
INC $02 ;Increment high byte pointer
CPX $02 ;Compare against page limit of $06
BNE LOOP ;Loop back back and start next page fill
RTS ;Return to caller
;
23 bytes in all with an RTS, else 22 bytes without it, assuming inline code with something else. Note CMOS processor required.
The more and more I see of the 65C02, the more I realize that I don't think there's much point in using the NMOS unless you really like using illegal opcodes. I would give my right arm to be about to set an address to 0 with a single opcode and being able to use indirect addressing for anything other than JMP opcodes lol
Its all so nice.
Nice one EvilSandwich. Be sure to initialise Y!
I think there might be another notch of improvement available. As you are counting up, and filling whole pages, INY can probably be part of an inner loop.
You may well then also find that you can BNE or BEQ (as appropriate) without needing to compare against a constant: the Z flag will already be what you want, in the inner loop.
I took your advice and got it all the way down to 26 bytes:
Code: Select all
LDA #$01
LDX #$01
LDY #$00
STX $02
STY $01
count:
INC $02
LDX $02
CPX #$06
BNE main
BRK
main:
STA ($01),y
INY
BNE main
BEQ count
I even shaved a little more off by initializing Y and using the 0 in Y for the indirect addressing AND setting the pointer's low byte at the same time.
Re: Need help with an incrementing 16-bit pointer
Posted: Mon Oct 28, 2019 10:43 pm
by BigEd
That's the spirit! The 65C02's extra opcodes are handy if you have them, but by no means necessary - and of course if you use only the originals, your code will run on either flavour.
Re: Need help with an incrementing 16-bit pointer
Posted: Mon Oct 28, 2019 10:55 pm
by floobydust
That's the spirit! The 65C02's extra opcodes are handy if you have them, but by no means necessary - and of course if you use only the originals, your code will run on either flavour.
A very true statement, however, I decided to use nothing but the CMOS version decades ago. I still have the pair of Rockwell R65C02P2 processors I purchased back in the 80's and the original datasheet. One of those chips is still in my original Vic-20 and the other in my original 1541 diskette drive. I haven't written any NMOS specific code since then. Now that you can still get Rockwell CMOS chips at fairly cheap prices (for older hardware replacements) and new WDC chips, I can't see any reason to use the older NMOS chips. That's just my personal view of course, so all of my code since then requires the CMOS processor.