Lab 01 - Experiments, Calculating Performance and Modifying Code

LAB 01 - Experiments, Calculating Performance and Modifying Code


Hi there! Thank you for taking the time to check out my page. This blog post will contain some insights derived from experiments and performance calculation outlined in our Software Portability and Optimization course. 

Take Note...

Just before we dig deep into the experiments and calculations here are the following definitions of the instructions used all throughout the experiment:

  • lda (Load Accumulator with Memory): transfer data into the accumulator from memory
  • sta (Store Accumulator in Memory): stores data from accumulator to memory
  • ldy (Load Index Register Y From Memory): loads the index register Y from memory
  • iny (Increment Index Register Y By One): adds 1 to current content in register Y
  • bne loop (Branch on Result Not Zero): conditional branch that tests Z flag and loops if Z flag is not on.
  • inc (Increment Memory By One): this adds 1 to content in the memory location
  • ldx (Load Index Register X From Memory): loads the index register X from memory
  • cpx (Compare Index Register X To Memory): compares value in register X to addressed memory
  • tya (Transfer Index Y To Accumulator): moves content in index Y to accumulator 
  • lsr (Logical Shift Right): shifts 1 bit to right and the higher bit always set to 0
  • asl (Arithmetic Shift Left): shifts 1 bit to the left with the bit 0 always set to 0
16 colours from a preset palette:
  • $0: Black
  • $1: White
  • $2: Red
  • $3: Cyan
  • $4: Purple
  • $5: Green
  • $6: Blue
  • $7: Yellow
  • $8: Orange
  • $9: Brown
  • $a: Light red
  • $b: Dark grey
  • $c: Grey
  • $d: Light green
  • $e: Light blue
  • $f: Light grey

Below is a bitmap code that fills the emulator's display with the colour yellow:

       lda #$00                   ; set a pointer in memory location $40 to point to $0200

  sta $40                   ; ... low byte ($00) goes in address $40

  lda #$02

  sta $41                   ; ... high byte ($02) goes into address $41

  lda #$07                 ; colour number

  ldy #$00                ; set index to 0

 loop: sta ($40),y     ; set pixel colour at the address (pointer)+Y

  iny                ; increment index

  bne loop                ; continue until done the page (256 pixels)

  inc $41                   ; increment the page

  ldx $41                   ; get the current page number

  cpx #$06                ; compare with 6

  bne loop                ; continue until done all pages


Result:


Performance Calculation 





Modifying Code

Modified Code #1

Find one or more ways to decrease the time taken to fill the screen with a solid colour.

In the code below, checks happen inside the loop every iteration as compared to the original version which is slower as it compares zero and content in register Y is being compared after each increment. Having more instruction does not necessarily mean it is slower, in this case, it just performs an extra step within the loop to lessen the time spent after every incrementation. You can check out this modified code that decreases time spent to display with a solid colour: 

  lda #$00       

  sta $40         

  lda #$02        

  sta $41         

  lda #$07        

  ldy #$00        

page_loop:

  sta ($40),y      

  iny              

  cpy #$00         

bne page_loop   

  inc $41         

  ldx $41          

  cpx #$06         

  bne page_loop  

 

Modified Code #2

Change the code to fill the display with light blue instead of yellow.

This modification simply changed the content stored in register A which was #$07 to #$0e to change colour from yellow to light blue.

lda #$00

sta $40

lda #$02

sta $41

lda #$e

ldy #$00

loop:

sta ($40),y

iny

bne loop

inc $41

ldx $41

cpx #$06

bne loop


Result:


Modified Code #3

Change the code to fill the display with a different colour on each page. 

Code below will display the colours yellow, cyan, purple and green. This code fills each 256-pixel (page) with a single colour and uses the instruction to increment the memory page after filling it. The use of cpx#$04 instruction, allows the colour to change after every iteration. 

 lda #$00          

 sta $40            

 lda #$02           

 sta $41             

 lda #$07          

 ldy #$00    

loop:  

 sta ($40),y      

 iny               

 bne loop          

 inc $41             

 lda $41          

 cpx #$08           

 bne loop           

 inc $42

 lda #$e           

 cpx #$04           

 bne loop

Result:


Modified Code #4

Change the code to fill the display with a different colour on each pixel. 

The code below is a result of each pixel being assigned a color which is incremented by 1 after each iteration. The initial index of #$00 which is the colour black is set to register Y and is stored in memory for each pixel, as it iterates, the content in the Y register gets added by 1, resulting in #$01, which in this case is now the colour white. This loop progresses and adds one colour to the value pixel after pixel. This whole process will continue until all pages are done.

    lda #$00       
    sta $40        
    lda #$02        
    sta $41        

    lda #$07       
    ldy #$00        

loop:
    sta ($40),y    
    eor #$3D        
    ror             
    iny             
    bne loop        

    inc $41        
    lda $41         
    cmp #$06        
    bne loop                 

Result:


Experiments

Experiment #1

The use of "tya" instruction

In the experiment, we added a tya instruction before the sta($40), y instruction which resulted in 16 different colours displayed which appeared twice that resulted in a total of 32 colours. Since this bitmap code is writing pixel colour to memory, the additional tya instruction moves the value that is in the Y register without interfering with the existing value stored in the said register; hence, displaying a different colour per column. The instruction sta($40), y sets a colour in Y register and since this instruction is within a loop, it is meant to execute until all pages are done. For each loop execution, the colour is expected to change per pixel and this was caused by the instruction iny which increments the content in register Y (index), starting at $0, producing the colour black and will produce a different colour per increment based on a preset palette. 

Result:



Experiment #2

The use of "lsr" instruction

After the instruction tya, an additional instruction lsr was added below tya which displayed 16 colours on screen. This change in visual was due to the instruction lsr that shifted memory location 1 bit to the right, taking the colour on the left, and then shifts out the low bit of the field which is now stored in the carry flag, and since the right bit falls off into the carry flag, which divided this by 2. In this case, the colour white is produced after the first colour on the left, which was also a result of the shift. This will continue until the loop ends and will only produce a total of 16 colours.

Result:



Experiment #3

The use of "lsr" instruction consecutively

Adding two lsr instructions in a row, divides this by 4 which produces 8 columns and shifts the 9th colour down to the row after. Following the same logic as adding more lsr instructions in a row can lead to dividing it by current number * 2, which will push the colour down to the leftmost in each row once it reaches the rightmost corner just above it. This process will repeat until all pages are done.  

Result of lsr instructions in a row:

  
two lsr instructions           three lsr instructions        four lsr instructions


Experiment #4

The use of "asl" instruction consecutively

Instead of the instruction lsr, the instruction asl has been applied to the code. This resulted in 8 colours, but with a total of 32 colours displayed. This was a result of this instruction shifting a bit to the left, pushing the leftmost to fall into the carry flag, having 0 set in the rightmost bit. If you notice, the index is doubled, allowing a skip by one in the preset palette. For instance, the colour after black ($0) should have been white ($01) but instead skips to the colour after $01, which was red ($02).


Experiment #5

The use of "asl" instruction consecutively

Adding two asl instructions in a row produces only 4 colours due to content in register being multiplied by 4. The more you use this instruction in a row, this shift produces a larger number as a result of this number being multiplied by double depending on current number of instructions used. If you notice down below, the colour also reduces in number as the content in the register increases. 

 
 two asl instructions        three asl instructions      four asl instructions


Experiment #6

The use of "iny" instruction consecutively

Using the iny instruction in a row adds the colour black. If used two or four times in a row, it produces the colours black and yellow and does not revert back to yellow, as compared to using it three or five times in a row where each page's pixels displays black and reverts back to yellow. This happens because incrementing the content in Y register by two or four, we are writing to every second or fourth pixel which could also displays black as the initial index in this register. On the other hand, odd numbers skip and create a cycle per page where it reverts back to loaded number which, in this case, yellow.


Conclusion

Performing these experiments allowed me to understand how storing contents to registers can produce a significant change to the bitmap display. In assembly language, it is essential to carefully understand what each instruction means and how it could affect the output of the bitmap code.



  w



Comments

Popular posts from this blog

BATCH 3 | Project Stage 2, Part 3 - Cloned Functions Comparison and Reflection

BATCH 3 | Project Stage 2, Part 1 - Clone-Pruning Analysis Pass