TUTORIAL #23 – HIGH side - indirect indexed addressing “Is used to define the HIGH side of the byte for mapping directly to the PAGE 1 screen memory”.
It’s not easy trying to explain the process of how to use indirect indexing to place shapes on the graphic screen so I will use the explanation from the a great assembly book – “Apple Graphics & Arcade Game Design” by Jeffrey Stanton. Below is Jeff’s explanation starting at Chapter 5 on page 111 – Bit Mapped Graphics.
“Drawing a bit-mapped shape table anywhere on the HI-RES screen can be a simple process once the basic concept is understood. The shape table is stored sequentially in memory, either by rows or by columns. The technique, therefore, is to load each of the bytes, one at a time, into the Accumulator, find the position in memory for the screen location where you want to plot the byte, then store it in that memory location.
The difficulty lies in finding a particular memory location, given an X, Y screen coordinate. Speed is the critical factor in doing arcade animation; therefore, a technique known as Table lookup is used to locate the starting address of any single line on the Hi-Res screen. Each of the 192 screen lines has a starting address for the first position (left most) or the 0th offset. The first line of line #0 is located in memory at location $2000. The second line is at $2400, etc… Each address takes two bytes. The first part is the hi-byte, which in the later case is $24. The second byte, $00 is the lo-byte. These can be separated into two tables, one containing the lower order address of each line (call it YVERTL) and the other containing the higher order address of each line, YVERTH. Each table is 192 bytes long (0-191). The effective address of the operand is computed by adding the contents of the Y register to the address in the instruction. That is:
EFFECTIVE ADDRESS = ABSOLUTE ADDRESS + Y REGISTER
If our YVERTH table was stored at $6800 and we wanted to find the starting address on line 1 (remember lines are numbered 0 to 191), we would index into the table one position and load that value into the Accumulator,
6800:20 24 28 2C 30 24 …………. YVERTH TABLE
So LDA YVERTH,Y where Y=$01 will fetch the value $24 from memory location $6800 + $01 = $6801, and place it in the Accumulator.
Similarly, if YVERTL was stored immediately after the first table, then:
68C0:00 00 00 00…………………….YVERTL TABLE
Y register = $01
LDA YVERTL,Y will take the value $00 stored in memory location $68C0 + $01 = $68C1, then place it in the Accumulator. Eventually, we will want to store the first byte from the shape table into memory location $2400. This can be done efficiently if the two byte address is stored sequentially in zero page. Let’s store the lo byte half of the address, HIRESL, at location $26, and the hi byte half, HIRESH, at location $27 in zero page.
LDY #$01 ; Y REGISTER CONTAIN LINE
LDA YVERTH,Y ; LOOKUP HI BYTE OF START
; OF ROW IN MEMORY
STA HIRESH ; STORE ZERO PAGE
LDA YVERTL,Y ; LOOKUP LO BYTE OF ROW IN
; MEMORY
STA HIRESL ; STORE ZERO PAGE
We can change a particular Hi-Res screen memory location using zero page by indirect indexed addressing in the form:
STA (HIRESL),Y Y Reg = $03
If the computer finds a $00 in location $26 (HIRESL) and a $24 in location $27 (HIRESH), then the base address is $2400. The Accumulator stores a value into memory location $2400 + $03, or location $2403.
The final addressing mode that we must consider is Indexed Indirect Addressing. It is of the form:
LDA (SHPL,X)
It is very similar to the indirect Indexed addressing mode except the index is added to the zero page base address before it retrieves the effective address. It is primarily used for indexing a table of effective addresses stored in zero page. But in the form we are going to use it, the X register is set to 0; thus, it simply finds a base address.
The reason we must use this second form of indirect addressing is a shortage of registers in the 6502 microprocessor. We are already using the Y register in the store operation and there isn’t an indirect addressing mode of the for LDA (SHPL),X. Thus, we must go to the alternative addressing mode LDA (SHPL,X).
What this all boils down to is that we want to load a byte from a shape table into the Accumulator and store it on the screen with the following instructions:
LDA (SHPL,X) ; STORE BYTE FROM SHAPE TABLE
STA (HIRESL),Y ; STORE BYTE ON HI-RES SCREEN
We can index into the shape by incrementing the low byte SHPL by one each time, then store that byte into the next screen position on a particular line by incrementing the Y register. This zero page method is faster than doing the equivalent code with absolute index addressing, because two byte addresses can be handled with fewer instructions, less memory space, and with fewer machine cycles.
Obviously, a generalized subroutine must be developed to find the screen memory address (HIRESL & HIRESH), given a line number and a horizontal displacement. We will call this subroutine GETADR, short for Get Address.
Each time a row of shape table bytes is transferred to successive memory locations on the Hi-Res screen, the program will call the subroutine GETADR. The line’s starting memory address is then offset by the horizontal location of the shape on the screen.
Memory address = Line # starting address + horizontal offset
GETADR LDA YVERTL,Y ; LOOK UP LO BYTE OF LINE
CLC
ADC HORIZ ; ADD DISPLACEMENT INTO LINE
STA HIRESL ; STORE ZERO PAGE
LDA YVERTH,Y ; LOOK UP HI BYTE OF LINE
STA HIRESH
RTS
Where the Y register has the vertical screen value (0-191).
So what this means is by using indirect index addressing you can quickly process each screen memory location by looping through the Hi and LOW byte of the screen memory and either place a zero value in the location and clear the byte or enter a HEX value and produce a graphic image on the screen. It would be time consuming as well as a waste of programming space to try and write to each screen memory location from $2000 to $3FFF through line 0 to 191. You can loop through data base that has each HI and LOW byte definition and save a huge amount of programming space.
Here is a breakdown of a line within the HI byte data definitions code:
See small sample image above
On line # 886 we have defined a set of HI byte data regions, which after the DFB define each of the HI side byte screen locations. So for example if you were to store a byte of information within the memory location $2100, you would first have to grab the HI byte $21 then loop through the LOW side byte in the LO database section to obtain the remaining byte to draw your shape on the screen.
Remember, screen memory location $2000 is the starting upper left corner of the screen that would store a byte of information to draw points on the screen. The $20 is the HI byte and $00 is the LOW byte.
As always, if you have any questions please email me at:
Joe “kingspud”
No comments:
Post a Comment