6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 8:11 pm

All times are UTC




Post new topic Reply to topic  [ 65 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
PostPosted: Wed Oct 16, 2019 10:02 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Yep, one way or another, X must be zero.


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 16, 2019 10:06 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
BigEd wrote:
Yep, one way or another, X must be zero.

Welp, that seems to have worked!

Code:
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


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 4:58 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
drogon wrote:
Tackling the original scenario, break it down, so the increment:

Code:
; 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!


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 5:05 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
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.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 5:13 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
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?


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 5:44 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
EvilSandwich wrote:
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

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 6:22 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
EvilSandwich wrote:
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.)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 19, 2019 6:56 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
GARTHWILSON wrote:
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?!"


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 20, 2019 8:22 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
EvilSandwich wrote:
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 27, 2019 9:25 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
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:
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! :D


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 27, 2019 10:28 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
Well, here's another baker's routine to fill a memory area from $0200 - $05FF with a byte value:

Code:
; 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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 28, 2019 6:40 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 28, 2019 7:00 pm 
Offline

Joined: Sun Oct 13, 2019 6:20 am
Posts: 36
Location: Pennsylvania, USA
floobydust wrote:
Well, here's another baker's routine to fill a memory area from $0200 - $05FF with a byte value:

Code:
; 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.

BigEd wrote:
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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 28, 2019 10:43 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 28, 2019 10:55 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
BigEd wrote:
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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 65 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 41 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: