Wednesday, 26 February 2020

Week - 7 Lecture (Lab 5)

This week there was no lab due to Family day's holiday so the Lab 5 was supposed to be worked on in the lecture period. This were the required steps for Lab 5:

Here is a basic loop in AArch64 assembler - this loops from 0 to 9, using r19 as the index (loop control) counter:
.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:

    mov     x19, min

loop:

    /* ... body of the loop ... do something useful here ... */

    add     x19, x19, 1
    cmp     x19, max
    b.ne    loop

    mov     x0, 0           /* status -> 0 */
    mov     x8, 93          /* exit is syscall #93 */
    svc     0               /* invoke syscall */
This code doesn't actually do anything while looping, because the body of the loop is empty. On an AArch64 machine, combine this code with code from the "Hello World" assembley-language example, so that it prints a word each time it loops:
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Then modify the message so that it includes the loop index values, showing each digit from 0 to 9 like this:
Loop: 0
Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9

Now we had a list of servers we could choose from so we decided to go with aarchie.
Then after taking reference from both the loop example given and the hello world program we were able to print the iterations of loop without numbers. Here is the code:

.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:

    mov     x19, min

loop:

        mov     x0, 1           /* file descriptor: 1 is stdout */
adr     x1, msg    /* message location (memory address) */
mov     x2, len    /* message length (bytes) */

mov     x8, 64      /* write is syscall #64 */
svc     0          /* invoke syscall */


    add     x19, x19, 1
    cmp     x19, max
    b.ne    loop

    mov     x0, 0           /* status -> 0 */
    mov     x8, 93          /* exit is syscall #93 */
    svc     0               /* invoke syscall */

.data
msg: .ascii      "loop \n"
len= . - msg

the text is stored in the msg label and .ascii acts as a dcb. then _start. declares the start of the program and the loop label uses the message and its length to do a syscall to print it to the screen and one gets added to the register used for iteration and this keeps on going until the loop is finished i.e. comparison between max and register value. Well we were trying different ways on how to get the number printed besides the loop but could only managed to go this far until the lecture was over and we were told this lab would be continued until the lab period after study week so we had a lot of time to think over this.
Though the syntax looks a bit scary for now for this architecture it is just a matter of time before we get used to these instructions and then everything should be fine.

Saturday, 22 February 2020

Week 6 - Lab 4 continued and Lecture

This week's lab also we were supposed to work on Lab 4 and I will talk about the second task that were supposed to work on, in this blog. Now in case you guys did not check out last post this was our task:

Option 2: Data Input Form[edit]

  1. Create a subroutine which enables the user to enter a string of up to 40 characters. Decide how the data will be returned from the subroutine. The user should be able to use the left/right cursor keys and backspace to edit the text, and the cursor location should be visible to the user.
  2. Write a program which uses this subroutine to collect the user's name, address, city, province, and postal code, and then display this information formatted as a shipping address (for example, as shown below).


Your order will be delivered to: J. Doe 1750 Finch Ave E Toronto ON M2J 2X5

Now the approach used was to store each of the inputs was that each iteration would give a message (stored as constant byte) followed by the user input (stored as empty dcb's of required lengths). Then each of the empty constant bytes will be replaced by user input accordingly and displayed in the last iteration with the help of labels. Now there was a very important concept about logical operations we were taught in week 5 which was XOR or EOR which stands for exclusive OR. Anything EOR with 0 would keep the original value and EOR with 1 would give a flipped value. So basically we used it to flip the bits.
Here is code for lab 4 task 2:

define        SCINIT        $ff81 ; initialize/clear screen
define        CHRIN        $ffcf ; input character from keyboard
define        CHROUT        $ffd2 ; output character to screen
define        SCREEN        $ffed ; get screen size
define        PLOT        $fff0 ; get/set cursor coordinates
define    POINTER        $10    ; ptr: start of row
define    POINTER_H    $11
define    SPOINTER    $12    ; ptr: start of screen
define    SPOINTER_H    $13
define MAX_INPUT    $14


    lda #$f0
    sta SPOINTER_H
    lda #40
    sta MAX_INPUT
   
          jsr SCINIT

; Name
          ldx #<label1    ; loading X with a pointer to the string to be printed
          ldy #>label1    ; loading Y with a pointer to the string to be printed
      jsr prtstr    ;  print string

          ldx #<name    ; loading X with a pointer to the string to be read and store
          ldy #>name
          lda #len1 ; length of string

          jsr getstr    ; go get user input

          jsr SCINIT

;Address

          ldx #<label2
          ldy #>label2
          jsr prtstr

          ldx #<address    ; loading X with a pointer to the string to be read and stored
          ldy #>address    ; loading X with a pointer to the string to be read and stored
          lda #len2 ; length of string

          jsr getstr    ;  get user input

          jsr SCINIT

;City

          ldx #<label3
          ldy #>label3
          jsr prtstr

          ldx #<city    ; loading X with a pointer to the string to be read and stored
          ldy #>city    ; loading Y with a pointer to the string to be read and stored
          lda #len3 ; length of string

          jsr getstr    ; go get user input

          jsr SCINIT

; Printing final message and captured details

          ldx #<label4    ; load XY with a pointer to the string to be printed
          ldy #>label4
      jsr prtstr    ; go print string

          ldx #<name    ; load XY with a pointer to the string to be printed
          ldy #>name
      jsr prtstr    ; go print string

      jsr prtcrlf

          ldx #<address    ; load XY with a pointer to the string to be printed
          ldy #>address
      jsr prtstr    ; go print string

      jsr prtcrlf

          ldx #<city    ; load XY with a pointer to the string to be printed
          ldy #>city
      jsr prtstr    ; go print string

      jsr prtcrlf
         
          brk

prtcrlf:               ;this subroutine moves the code to a newline
      ldx #<crlf    ; there is only one parameter 
      ldy #>crlf    ;prints a newline carriage return character
      jsr prtstr


prtstr:                                  ; this subroutine prints a NULL terminated string
          stx POINTER           ; there is only one parameter
          sty POINTER_H      ;    registers XY point to the string to be printed

          ldy #$00         

prtchar:    
          lda (POINTER),y
          beq prtstrdone

          jsr CHROUT

          iny
          bne prtchar

prtstrdone:
          rts


getstr:                       ;this subroutine takes care of the typing and checking of keys
 stx POINTER           ; there is 2 parameters the pointer and length of string
         sty POINTER_H
    sta SPOINTER
    ldy    #$00
   
check2:
idle:     inx
          cpx #$10
          bne check
          lda (SPOINTER),y
          eor #$80
          sta (SPOINTER),y
check:    lda $ff
          beq idle

          ldx #$00
          stx $ff

          cmp #$08
          bne print

          lda (SPOINTER),y
          and #$7f
          sta (SPOINTER),y

          dey
          jmp next

print: 
    cpy MAX_INPUT
    beq maxed

     cmp #$0D    ; check for Enter key
     beq done

     cmp #$83    ; check for Left arrow key  
     beq go_left

     cmp #$81    ; check for Right arrow key
     beq go_right

    sta (SPOINTER),y
    sta (POINTER),y
          iny

maxed: 
          jmp check2

go_left:
;brk
    dey
    cpy #$ff
    bne not_at_left

    iny

not_at_left:
    jmp idle

go_right:
;brk
    lda (POINTER),y
    cmp #$00
;brk
    beq not_at_right

    iny

not_at_right:
    jmp idle

done: 
 rts

label1:
dcb "p","l","e","a","s","e",32,"e","n","t","e","r",32,"y","o","u","r",32,"n","a","m","e",":",00
define len1 24

label2:
dcb "p","l","e","a","s","e",32,"e","n","t","e","r",32,"y","o","u","r",32,"a","d","d","r","e","s","s",":",00
define len2 27

label3:
dcb "p","l","e","a","s","e",32,"e","n","t","e","r",32,"y","o","u","r",32,"c","i","t","y",32,"a","n","d",32,"p","o","s","t","a","l",32,"c","o","d","e",":",00
define len3 40

label4:
dcb "Y","o","u","r",32,"o","r","d","e","r",32,"w","i","l","l",32,"b","e",32,"d","e","l","i","v","e","r","e","d",32,"t","o",":",$0d,$0d,00

name:
dcb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$0d

address:
dcb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$0d

city:
dcb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$0d

crlf:
dcb $0d,0

So by incorporating previous task's knowledge about working with character display and some additional information we were able to finish this lab.

Lecture:
This week's lecture started with a quiz and it was all about differences between the architecture we already finished learning and the architectures we were in process of learning i.e. 6502, AArch 64 and X86 64. And after the quiz the prof. gave us a summary about the 3.
6502: 8 bit processor, 16 bit address, 3 registers.
X86 64: 64 bit processor, 64 bit address, 16 registers.
AArch 64: 64 bit processor, 64 bit address, 31 registers.

Then we got an insight on how both architectures started from different approaches i.e. RISC (have tiny instructions but small and fast), and CISC (complex instructions) and ended up curving in a way to come on similar grounds. 

Then we were shown a sample hello world program that had some weird looking syntax at first but then made sense once we got to understand it.
Overall we knew we were taking a step forward into the this assembly language and had to be ready for it.

Wednesday, 12 February 2020

Week 5 - Lab 4 and Lecture

This week started with us getting another lab that we had to complete as a group. So we had about 4 tasks to choose from. out of which we had to complete 2. Here are the options we had:

Option 1: Adding Calculator[edit]

  1. Create a subroutine which enables the user to enter two numbers of up to two digits. Indicate where the cursor is, and allow the user to use the digit keys (0-9), backspace, and enter keys. Return the user's input value in the accumulator (A) register.
  2. Using this subroutine, write a program which add the two numbers (each of which is in the range 0-99) and print the result.
  • Optional challenge: extend to more than 2 digits and add a running total capability with a clear key.

Option 2: Data Input Form[edit]

  1. Create a subroutine which enables the user to enter a string of up to 40 characters. Decide how the data will be returned from the subroutine. The user should be able to use the left/right cursor keys and backspace to edit the text, and the cursor location should be visible to the user.
  2. Write a program which uses this subroutine to collect the user's name, address, city, province, and postal code, and then display this information formatted as a shipping address (for example, as shown below).
Your order will be delivered to:

  J. Doe
  1750 Finch Ave E
  Toronto ON  M2J 2X5
  • Optional challenge: validate the province/territory and the postal code format.

Option 3: Hexdump[edit]

  1. Create a subroutine which enables the user to enter a 4-digit hexadecimal value. Allow the use of the backspace key for editing, and show the user the cursor location. Decide how the data will be returned by this subroutine.
  2. Using this subroutine, ask the user for a starting address and a length (in bytes), and then output a hexdump of the specified memory locations, formatted to show address and data information in some layout. If the output is longer than the screen, pause for user input (e.g., "Press ENTER to continue" or something similar) every 20 lines.
  • Optional challenge: add a display of ASCII data on the right-hand side, similar to the output of the linux command od -A x -t xz -v filename

Option 4: Screen Colour Selector[edit]

  1. Create a subroutine which displays on the character display a list of colours available on the bitmapped display, one colour per line, with one of the colours names highlighted in reverse video (white on black). The user may use the up/down arrow keys to change the highlighted row. Return the user's selection as a number in the accumulator (A) register when they press Enter.
  2. Using this subroutine, get a colour from the user, then fill the bitmap display with this colour, and allow the user to select a different colour.
  • Optional challenge: update the colour on the bitmapped display as the user scrolls through the colour-selector list.

So out of these options our group decided to go for options 2 and 4 which were data input form and screen colour selector. We decided to work on the screen color selector first. 

Now as we were working on the lab the professor gave us 2 commands that would be useful for the lab which were pha and pla which stand for PUSH Accumulator and PULL accumulator respectively. Pha simply copies whatever is in the accumulator and stores it on the stack while Pha doing the opposite takes 1 byte from the stack and stores it in the accumulator. 

Now we started by displaying the names of the colors by declaring them as constant bytes and then printing them on character display but soon we figured out the old way of displaying things by starting displaying from the character display's start address would not prove very useful and we would have to use ROM routines in order to work on this lab. Now ROM routines are pre defined subroutines in the memory that we can access and use for basic functionalities. Here is a list of them:
; ROM routines
define  SCINIT  $ff81 ; initialize/clear screen
define  CHRIN  $ffcf ; input character from keyboard
define  CHROUT  $ffd2 ; output character to screen
define  SCREEN  $ffed ; get screen size
define  PLOT  $fff0 ; get/set cursor coordinates


Well, after getting to display the names, the next task was to get the cursor moving up and down that list and displaying the color based on the position of cursor. While we had limited time in lab we could only manage to go so far and decided to complete the lab afterwards.

Lecture:
Well this week's lecture introduced us to 2 architectures which were fairly new to us though we use them a lot, x86 64 and AArch 64. We were given a background on both those architectures and how those 2 emerged from being small in memory chips to being so huge memory and powerful now.
Then we got to know the registers on both the architectures. While AArch 64 had 0-30 registers and a register 31 that could be used as zero register or stack pointer based on its functionality. More on these registers and some related instruction set can be found on: 

While on the other hand X86 64 had 16 registers, more of which could be found on:
It was interesting to know how both the architectures had registers that could be used for 64 bit or 32 bit wide access. 

Now going back to the lab, we took from the code from the previous lab on how to scroll using input from the keyboard and we went further to store the color, address cur_pos held inside and we manipulated the cursor to store different color's code according to the input from the keyboard, as they ranged from 0-F. So after managing to change the color code based on keyboard up or down key and making it print the stored code using the filling the bitmapped display's code we were able to come up with the following code:

; ROM routines
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; input character from keyboard
define CHROUT $ffd2 ; output character to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates

define      cur_pos     $10

          jsr SCINIT
          ldy #$00
          
          ldx #$00
          stx cur_pos

char:     lda color_list,y
          beq main
          
          jsr CHROUT
          iny
          bne char
          
main:
lda $ff          ; get a keystroke
    beq main             ; fix freezing on max speed
    
  ldx #$00          ; clear out the key buffer
  stx $ff

cmp #$82          ;  arrow down for increment (going down)
beq incr

cmp #$80          ; arrow up for decrement (going up)
beq decr

jmp main           ; if no key pressed loop forever
    
clear_cursor:
    lda #$2d             ; character -
    jsr print_cursor
    rts
    
incr:
    jsr clear_cursor
    
    inc cur_pos
    lda cur_pos
    cmp #$10
    beq incr_reset
    
    bne incr_decr
    
incr_reset:
    lda #$00
    sta cur_pos
    jmp incr_decr
        
decr:
    jsr clear_cursor
    
    dec cur_pos
    lda cur_pos
    cmp #$FF
    beq decr_reset
    
    bne incr_decr
    
decr_reset:
    lda #$0F
    sta cur_pos
    jmp incr_decr

incr_decr:
    lda #$93             ; character black box
    jsr print_cursor
jmp paint
    
print_cursor:
    clc                  ; select the SET function for PLOT
    ldx #$00
    ldy cur_pos          ; increment this one
    pha                  ; save the value of A into the stack
    jsr PLOT             ; set the cursor position
    pla                  ; restore the value of A from the stack
    jsr CHROUT           ; print the char
    rts
    
paint:
      ldx #$06           ; max value for $11
      ldy #$00           ; index
      
      lda #$00           ; set pointer at $10 to $0200
      sta $11
      lda #$02
      sta $12
      
      lda cur_pos        ; set the color
      jmp paint_loop
      
paint_loop: 
      sta ($11),y        ; store colour
      iny                ; increment index
      bne paint_loop     ; branch until page done
      
      inc $12            ; increment high byte of pointer
      cpx $12            ; compare with max value
      bne paint_loop     ; continue if not done 
      
      jmp main           ; done - return to main

color_list:
    dcb $93,"B","l","a","c","k",13
    dcb "-","W","h","i","t","e",13
    dcb "-","R","e","d",13
    dcb "-","C","y","a","n",13
    dcb "-","P","u","r","p","l","e",13
    dcb "-","G","r","e","e","n",13
    dcb "-","B","l","u","e",13
    dcb "-","Y","e","l","l","o","w",13
    dcb "-","O","r","a","n","g","e",13
    dcb "-","B","r","o","w","n",13
    dcb "-","L","i","g","h","t",32,"r","e","d",13
    dcb "-","D","a","r","k",32,"g","r","e","y",13
    dcb "-","G","r","e","y",13
    dcb "-","L","i","g","h","t",32,"g","r","e","e","n",13
    dcb "-","L","i","g","h","t",32,"b","l","u","e",13
    dcb "-","L","i","g","h","t",32,"g","r","e","y",00

As you can see we used ROM routines CHROUT and PLOT to print the characters to the display and setting the position of the cursor in the memory respectively. 
Though we managed to pull of this first task we still had one more to go.

Friday, 31 January 2020

Week 4 - Lecture

This week's lecture started with how we can display text on the 6502 emulator. I found it fairly easy.
Here is a sample code:

define SCREEN $f000
           ldy #$00
 
 char:     lda text,y
           beq done
           sta SCREEN,y
           iny
           bne char
 
 done:     brk
 
 text:
 dcb "S","P","0","6","0","0",32,"i","s",32,"a","w","e","s","o","m","e",".",00

This was accomplished by having a text as dcb and looping it to load and store it in accumulator.
Spaces were put using number 32 and all characters were put in double quotes.

Next we talked about compiling the code. We compiled a simple C program inside linux and saw its executable was larger than its original file. We also learnt about dynamic and static linking and how each of them have their own pros and cons. While static being larger in size and dynamic was relatively smaller. Then we learnt about different compatibility modes it had to offer and how it could range from O0 (almost no optimizations) to O3 (most optimized) and we were also shown how many flags for optimized content was set to active and how we could manipulate it. Og was used to optimize for debugging. We almost looked upon certain commands like make which could be used to make partial builds inside of whole when small changed are made to source files.

This week's lecture ended with us touching upon something new and we were also told text was the last thing we learnt on 6502 and we wont be working with it anymore.

Thursday, 30 January 2020

Week 4 - Lab 3 continued

This week's lab started with us giving a quiz. We were all a bit surprised as we did not expect it but it turned out to be just fine in the end since it was just matching and there were no short or long questions to answer. Rest of the lab was given to us to figure out more about lab 3 and work on it.
We still did not have much to end the lab with so we decided and talked to professor a bit more about it and understanding it in more detail.
After much discussions finally we were able to incorporate everything we know and combined declare constant byte's knowledge to get rid of multiplication, used delay loop that would keep counting as necessary to give us necessary delay to give an effect of moving, incremented rows and columns accordingly to direct the graphic and finally filled the display with black color where the graphic is no longer there. Here is the full code for this lab:

; zero-page variable locations
 define ROW        $20    ; current row
 define    COL        $21    ; current column
 define    POINTER        $10    ; ptr: start of row - upper left corner of object
 define    POINTER_H    $11
 define    WPOINTER    $12    ; ptr: start of row - write pointer
 define    WPOINTER_H    $13
 define BOUNCE_X    $14
 define BOUNCE_Y    $15
 define ROW_COUNT    $16
 define TIMER        $17    ; ptr: delay timer
 define TIMER_H        $18 
 define TIMER_CONTROL    $19 ; contains the base of the high bit of the timer

; constants
define WIDTH         7     ; width of graphic
define HEIGHT         7     ; height of graphic
define GREEN        $05    ; GREEN
define BLUE        $03    ; BLUE
define BLACK        $00    ; BLACK
define RIGHT        $19    ;  defining where the graphic must change direction accounting for its size
define    LEFT        $00    ;
define TOP        $00    ;
define BOTTOM        $19    ;

        lda #$0         ; initialize delay loop counter
        sta TIMER   
        sta TIMER_H
        lda #$40      ; setting the initial speed of the timer
        sta TIMER_CONTROL
        lda #$01        ; assume that the object is moving across the screen
        sta BOUNCE_Y ; contain the rate motion of the box along the Y axis
        lda #$01
        sta BOUNCE_X ; contain the rate motion of the box along the X axis
        lda #$03     ;setting were object starts on screen
        sta ROW
        lda #$06
        sta COL

loop:
    clc
    ldy ROW            ; load POINTER with start-of-row
    lda table_low,y
    adc COL
    sta WPOINTER
    lda table_high,y
    sta WPOINTER_H
    lda #$00            ; number of rows we've drawn
    sta ROW_COUNT         
    ldx #$00            ; index for data
    ldy #$00            ; index for screen column

draw:   ; draws graphic
    lda data,x   ; set up where graphic starts on sreen
    sta (WPOINTER),y
    inx
    iny
    cpy #WIDTH
    bne draw
    inc ROW_COUNT            ; increment row counter
    lda #HEIGHT            ; end of graphic by height
    cmp ROW_COUNT
    beq done            ; exit
    lda WPOINTER           ; load pointer
    clc
    adc #$20            ; add 32 to drop one row
    sta WPOINTER
    lda WPOINTER_H        ; carry to high byte if needed
    adc #$00
    sta WPOINTER_H
    ldy #$00
    beq draw

done:
    lda TIMER_CONTROL ; initialize timer with current speed
    sta TIMER_H

delay:  dec TIMER ; wait
        bne delay
        dec TIMER_H
        bne delay

        clc
        ldy ROW            ; load POINTER with start-of-row
        lda table_low,y
        adc COL
        sta WPOINTER
        lda table_high,y
        sta WPOINTER_H
        lda #$00            ; number of rows we've drawn
        sta ROW_COUNT         
        ldx #$00            ; index for data
        ldy #$00            ; index for screen column

wdraw:   ; remove graphic were it has been draw
    lda #BLACK
    sta (WPOINTER),y
    inx
    iny
    cpy #WIDTH
    bne wdraw

    inc ROW_COUNT            ; increment row counter
    lda #HEIGHT         
    cmp ROW_COUNT
    beq wdone            ; exit

    lda WPOINTER           ; load pointer
    clc
    adc #$20            ; add 32 to drop one row
    sta WPOINTER
    lda WPOINTER_H        ; carry to high byte if needed
    adc #$00
    sta WPOINTER_H
    ldy #$00
    beq wdraw

wdone:  ; check graphic if hitting a sides and if so change direction
    clc
    lda COL
    adc BOUNCE_X
    sta COL
    cmp #RIGHT
    bne no_bounce

    pha
    lda #$ff   ; using the fact that the register overflows adding ff is the same as subtracting 1
    sta BOUNCE_X
    pla
 
no_bounce:
    cmp #LEFT
    bne no_bounce1

    lda #$01
    sta BOUNCE_X

no_bounce1:
    clc
    lda ROW 
    adc BOUNCE_Y
    sta ROW
    cmp #BOTTOM
    bne no_bounce2

    pha
    lda #$ff
    sta BOUNCE_Y
    pla
 
no_bounce2:
    cmp #TOP
    bne no_bounce3

    lda #$01
    sta BOUNCE_Y

no_bounce3:

getkey: 
    lda $ff        ; get a keystroke
    ldx #$00    ; clear out the key buffer
    stx $ff
    cmp #$2d    ; is it a minus
    bne check

    clc   ; slow down timer
    lda TIMER_CONTROL
    adc #$01 ; changing speed of timer by adding to the timer
    bcs ignore

    sta TIMER_CONTROL

ignore:
    jmp move_it

check:
     cmp #$2b    ; is it a plus
     bne check0

    sec  ; speed up timer
    lda TIMER_CONTROL
    sbc #$01 ; changing speed of timer by subtracting from the timer
    beq ignore

    sta TIMER_CONTROL
    jmp move_it

check0:
    cmp #$80    ; check key == up
     bne check1

    sec
    lda ROW        ; ... if yes, decrement ROW
    sbc #$01
    beq ignore

    sta ROW
    jmp move_it

 check1:
    cmp #$81    ; check key == right
     bne check2

    lda COL        ; ... if yes, increment COL
    adc #$01
    cmp #RIGHT
    beq ignore

    sta COL
    jmp move_it

 check2:
    cmp #$82    ; check if key == down
    bne check3

    lda ROW        ; ... if yes, increment ROW
    adc #$01
    cmp #BOTTOM
    beq ignore

    sta ROW
    jmp move_it

 check3:
    cmp #$83    ; check if key == left
    bne move_it

    sec
    lda COL        ; ... if yes, decrement COL
    sbc #$01
    beq ignore
 
    sta COL
    bcc move_it

move_it: 
    jmp loop

data:  ; for the graphic
dcb 00,03,03,03,03,03,00
dcb 03,02,03,03,03,02,03
dcb 03,03,03,03,03,03,03
dcb 03,03,03,03,03,03,03
dcb 03,02,03,03,03,02,03
dcb 03,03,02,02,02,03,03
dcb 00,03,03,03,03,03,00

 ; these two tables contain the high and low bytes
 ; of the addresses of the start of each row

 table_high:
 dcb $02,$02,$02,$02,$02,$02,$02,$02
 dcb $03,$03,$03,$03,$03,$03,$03,$03
 dcb $04,$04,$04,$04,$04,$04,$04,$04
 dcb $05,$05,$05,$05,$05,$05,$05,$05,

 table_low:
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0



Tuesday, 28 January 2020

Week 3 - Lecture

Like last week, I was expecting the professor to give us the code for lab 3 as we were not able to make much improvements in our code, but it did not happen. Anyhow he gave us some very important logic on how each of the problem could be approached. You can view all of them here:
https://wiki.cdot.senecacollege.ca/wiki/6502_Assembly_Language_Math_Lab
So for our problem he told us we could approach it in a way where we could use deltaX and deltaY to manipulate rows and columns and he also showed us different techniques on how multiplication could be performed otherwise since there is no instruction for multiplication in assembly. He also suggested we could use dcb logic used in Etch-a-Sketch Style Drawing code on page:
https://wiki.cdot.senecacollege.ca/wiki/6502_Emulator_Example_Code.

Although I did not get what I wanted, I still got an insight of what I was looking for and I had more to think of. After this he proceeded to tell us about different addressing modes that were there and explained utility for each of them. There were a total of 13 of them.
You can find the list and more about each of those modes under:
https://wiki.cdot.senecacollege.ca/wiki/6502_Addressing_Modes

Then he also talked a little bit about possible projects that we could be working on and how to find one of them in future.
Some key points I collected from the possibilities were:
1. It should be an open source package.
2. Should be CPU intensive: could be

  • codec
  • compress
  • images
  • crypto
  • math
  • large data sets
The class ended and next target I had in mind was to work on and finish lab 3.

Sunday, 26 January 2020

Week 3 - Lab 3

This week's lab started with professor asking us to discuss lab 2 if anyone in the group had any doubts about which I blogged about last week. Once we were done with it we were given a bunch of options to choose from for our lab 3 challenge. After plenty of discussions our group decided to go for a moving graphic across the screen. Full Challenge:

Option I: Bouncing Graphic
Create a simple graphic in a square that is 5x5 or 7x7 pixels in size. Use the colours available in the emulator's bitmapped display. The graphic could be a ball, a happy face, a logo, an emoji, or anything else (appropriate!) that you want to use.
Encode that graphic in bytes using DCB (declare constant byte) instructions.
Write code to make the graphic bounce around the screen, reflecting off the edges when it hits. Note: for simplicity, it is OK if the object always bounces at 45-degree angles.
Make the speed keyboard-adjustable (faster/slower) and perturb the object's path once in a while.
Challenge: randomize the starting position, and make the object bounce at angles other than 45 degrees.

Rather than getting it all at once. We decided to take a step by step approach to it. So we started by one person working on the face using declare constant byte instructions and other were trying to figure out how we could get to move a pixel in one direction first, then at an angle, then figuring out the edges and how it would bounce from it, and finally moving the whole smiley face.

While there was very limited time left when we started to work on this lab. By the end of this lab we were only able to figure out the smiley face which was pretty straight forward and creatively done by our groupmate.The following dcb instructions were used by our groupmate:

dcb 00,03,03,03,03,03,00
dcb 03,02,03,03,03,02,03
dcb 03,03,03,03,03,03,03
dcb 03,03,03,03,03,03,03
dcb 03,02,03,03,03,02,03
dcb 03,03,02,02,02,03,03
dcb 00,03,03,03,03,03,00