6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Jun 29, 2024 12:33 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: 6502 Assembly question
PostPosted: Sun Jul 05, 2020 3:46 pm 
Offline

Joined: Sun Jul 05, 2020 3:36 pm
Posts: 2
I need to state that I am very new to assembly programming.

I am reviewing some code and I am confused as to how it is functioning and looking for someone to explain.

The lines of code that I am confused about are:

lda ScreenRAMRowStartLow,Y ; load low address byte
sta ZeroPageLow

lda ScreenRAMRowStartHigh,Y ; load high address byte
sta ZeroPageHigh

My question is when LDA is performed what exactly is going on. What part does they Y play and how does the ScreenRAMRowStartLow used.

Below is the ScreenRAMRowStartLow definition.

ScreenRAMRowStartLow ; SCREENRAM + 40*0, 40*1, 40*2 ... 40*24
byte <SCREENRAM, <SCREENRAM+40, <SCREENRAM+80
byte <SCREENRAM+120, <SCREENRAM+160, <SCREENRAM+200
byte <SCREENRAM+240, <SCREENRAM+280, <SCREENRAM+320
byte <SCREENRAM+360, <SCREENRAM+400, <SCREENRAM+440
byte <SCREENRAM+480, <SCREENRAM+520, <SCREENRAM+560
byte <SCREENRAM+600, <SCREENRAM+640, <SCREENRAM+680
byte <SCREENRAM+720, <SCREENRAM+760, <SCREENRAM+800
byte <SCREENRAM+840, <SCREENRAM+880, <SCREENRAM+920
byte <SCREENRAM+960

ScreenRAMRowStartHigh ; SCREENRAM + 40*0, 40*1, 40*2 ... 40*24
byte >SCREENRAM, >SCREENRAM+40, >SCREENRAM+80
byte >SCREENRAM+120, >SCREENRAM+160, >SCREENRAM+200
byte >SCREENRAM+240, >SCREENRAM+280, >SCREENRAM+320
byte >SCREENRAM+360, >SCREENRAM+400, >SCREENRAM+440
byte >SCREENRAM+480, >SCREENRAM+520, >SCREENRAM+560
byte >SCREENRAM+600, >SCREENRAM+640, >SCREENRAM+680
byte >SCREENRAM+720, >SCREENRAM+760, >SCREENRAM+800
byte >SCREENRAM+840, >SCREENRAM+880, >SCREENRAM+920
byte >SCREENRAM+960

Secondary question is what do the > and < do in the definition of the byte?

Really looking to figure this out and would appriciate anyone taking the time to explain. If I did not explain the question right just so and I will try to rephrase.

Thanks
Mark


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 4:02 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10837
Location: England
Welcome!

The addressing mode base,Y will access memory at a base address plus the content of the Y register. The two-byte address 'base' from the program will have Y added to it to make the effective address. That is, 'base' can be thought of as an array, and accessing base,Y is like accessing base[y] in another language.

In this case you have two base addresses, so in effect you have two arrays of bytes.

I'll rewrite your code snippet with different variable names:

Code:
lda ScreenRAMRowStartLow,Y ; load low address byte
sta ZeroPageLow

lda ScreenRAMRowStartHigh,Y ; load high address byte
sta ZeroPageHigh


as
Code:
lda lowbytes,Y ; load low address byte
sta pointerlow

lda highbytes,Y ; load high address byte
sta pointerhigh


So we load the Yth byte from the first array and store it in zero page, then the Yth byte from the second array and store in zero page. We can think of these two arrays as a single array of two-byte values.

In all likelihood these two zero page locations are adjacent: we've just constructed a pointer in zero page, as one of N possible pointers from our array.

Having got an address (or a pointer) into zero page, it's now possible to access memory that's pointed to by that pointer, typically with a new index value but once again placed in the Y register:
LDA (zp),Y

Most likely the idea here is that the array contains pointers to start of each line, so Y in the first two accesses gets a pointer to screen memory at some line of the screen, and then the subsequent access (with a new value for Y) can be used to read or write the character in that position along the line.

Now you know the intended meaning of the two arrays, it should be relatively easy to puzzle out why (and how) it's being filled with the values relating to the location of screen memory.

Hope this helps.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 4:04 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
The lines of code get the start address for a line of characters in 40x25 video RAM area using lookup tables and store in two zero page locations (to create a pointer).

If you have a '<' character in from of an expression the assembler will calculate the low 8 bits of the value (e.g. value MOD 256). Similarly a '>' character calculate the high 8 bits of a value (e.g. value / 256).

The two tables have applied < and > to the same addresses so that the high bytes are in one and the low bytes are in the other.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 5:16 pm 
Offline

Joined: Sun Jul 05, 2020 3:36 pm
Posts: 2
BigEd and BitWise,

Thank you so much for the quick response.

Both of your answers have been very helpful and I think I understand how this working now.

Mark


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 7:42 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 390
Location: Minnesota
Note that there are some design decisions in this arrangement that could be made otherwise. Splitting the high and low bytes of a 16-bit address into two separate tables means all you have to do is load the Y-register with the screen row you're interested in - you can use that directly as an index into the two tables to get the address of that row.

But that's not the only way to do it. You could decide to have only one table, like so:
Code:
word screenAddr, screenAddr+40, screenAddr+40*2, screenAddr_40*3, [etc]


Then you would have to do something like:

Code:
lda currRow
asl
tay


to double the current row in order to get the proper index into the table. The advantage is it's a lot easier to write this form in source code and less prone to mistakes, since in the split form you have to be very careful that the two tables match up. The disadvantage is that this form takes a little more code (two bytes) and little more time (four cycles) to access.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 7:59 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3366
Location: Ontario, Canada
teamtempest wrote:
The disadvantage is that this form takes a little more code (two bytes) and little more time (four cycles) to access.
It also maxes out with only 128 workable values for Y (whereas the other scheme would allow up to 256). But yeah, it's easier (and less error prone) setting up one table than two. :|

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 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: