Lab03

Description

This post is about Lab 03 assignment for SPO600 course at Seneca College.

In this lab, studetns are required to build a program with assembly language that works on 6502 simulator

The detailed instruction is as follows:

  1. Your program must work in the 6502 Emulator
  2. You must output to the character screen as well as the graphics (bitmapped) screen.
  3. You must accept user input from the keyboard in some form.
  4. You must use some arithmetic/math instructions (to add, subtract, do bitwise operations, or rotate/shift)
Work Progress
I was brainstorming to think of interesting program, probably a simple game. Then, I decided to make a game similar to pac man that I played when I was a kid with really old video game player that connects to TV. I haven't thought about the name of the game. Maybe, pac-woman?


How to play
This game interacts with AWSD key on keyboard since I couldn't get arrow key input with ascii code.
A: Move Left your ball
W: Move Up
S: Move Down
D: Move Right

Code; How it is written
The code for printing welcome messages are burrowed from the codes that were provided by Prof on spo600 wiki

  1. I draw the orange-colored dots on the bit map on random locations per page
  2. I draw the ball(the user's ball) on the first pixel on the bit map($0200)
  3. I implemented the logic of GETCHAR, which get inputs from the user.
  4. I implemented the logic of moving the ball according to the user's input.
  5. When the user's ball hit or overlap the orange dot and move away, the organge dot disappear.
  6. The red colored comment describes the detail logic of what each assembly instruction is for.

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

  JSR SCINIT
 
            ldy #$00      ; index value (character we're currently processing)
  char:     lda text,y    ; get a character from address (text + Y)
            beq done      ; if the character is NULL, branch to done
            sta SCREEN,y  ; store character at (SCREEN + Y)
            iny           ; increment Y (go to next character)
            bne char      ; repeat loop
  done: ; Done for Printing TEXT
 lda #$02
 sta $21 

 ldy #$00
 ldx #$02
LOOP:  ; Generate two dots on random locations on the screen per page
 stx $21 
 lda $fe ; random number for low byte of the pointer to bit map
 sta $20 
 lda #$08
 sta ($20),y
 lda $fe
 sta $20
 lda #$08
 sta ($20),y
 lda $fe
 sta $20
 lda #$08
 sta ($20),y
 
 inx
 CPX #$06   ; This LOOP repeats 5 times for $02xx, $03xx, $04xx, $05xx
 BNE LOOP 

  lda #$05  ; Starting location of your green ball
  sta $0200

  lda #$00  ; low byte for pointer to ball position
  sta $20
  lda #$02  ; high byte for pointer to ball position
  sta $21

GETMOVE:    ; Get user input
 JSR CHRIN
 CMP #$00      
 BEQ GETMOVE
 CMP #$64    ; Check If the input is one of AWSD
 BEQ RIGHT
 CMP #$61
 BEQ LEFT
 CMP #$77
 BEQ UP
 CMP #$73
 BEQ DOWN

BRK

RIGHT:
 ldy #$00      ; Dummy for accessing pointer(this is for using `sta($nn), y`)
 lda #$00      ; Remove Previous Move(the green ball) With Black Color
 sta ($20), y  ;
 ldx $20       ; Move the Pointer toward right
 inx
 beq RIGHTFLOW
 stx $20
 lda #$05
 sta ($20), y
 JMP GETMOVE

LEFT:
 ldy #$00      ; Dummy for accessing pointer
 lda #$00      ; Remove Previous Move With Black Color
 sta ($20), y  ;
 ldx $20       ; Move the Pointer toward left
 dex           ;
 beq LEFTFLOW  ; If low byte of the pointer is zero, handle the overflow
 stx $20
 lda #$05
 sta ($20), y
 JMP GETMOVE

UP:
 ldy #$00
 lda #$00
 sta ($20), y ; Delete Previous Dot
;; low byte is less than 32. If the ball is on the first row of a page on bitmap
 lda $20      ; It should change the page(section)
 cmp #$20
 bcc changeHighByte 
 
;; Otherwise just -32 to the low byte of bit map pointer
 sec
 lda $20
 sbc #$20
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

DOWN:
 ldy #$00
 lda #$00
 sta ($20), y ; Delete Previous Dot

;; low byte is bigger than 224
 lda $20          ; If the ball is on the last row of a page(section on bitmap)
 cmp #$E0         ; It should change the page(the high byte)
 bcs changeHBdown
 
;; Otherwise just +32 to X memory value
 lda $20
 clc 
 adc #$20
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

RIGHTFLOW:
 lda #$00
 sta $20

 lda $21        ;If the ball is on the last pixel of the bit map,
 cmp #$05       ;It goes the first pixel of the bit map
 beq gotoBegin 

 ldx $21
 inx
 stx $21

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

LEFTFLOW:
 lda #$ff
 sta $20

 lda $21
 cmp #$02        ;If the ball is on the first pixel of the bit map
 beq gotoEnd     ;It goes to the last pixel.

 ldx $21
 dex
 stx $21
 JMP GETMOVE 
 
changeHighByte:
 lda $21
 cmp #$02
 beq gotoBottom
 
 ldx $21   ; page up(e.g. $03xx -> $02xx)
 dex
 stx $21

 lda $20
 clc 
 adc #$e0
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE 

gotoBottom:
 lda #$05   ; Change the Page Num to bottom Page
 sta $21

;;;; set the row to the bottom (by adding 224)
 lda $20
 clc 
 adc #$e0
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE 

changeHBdown:
 lda $21
 cmp #$05
 beq gotoTop
 
 ldx $21   ; page down(e.g. $02xx -> $03xx)
 inx
 stx $21

 sec
 lda $20
 sbc #$e0
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

gotoTop:
 lda #$02   ; Change the Page Num to bottom Page
 sta $21

;;;; set the row to the bottom (by adding 224)
 sec
 lda $20
 sbc #$e0
 sta $20

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE 

gotoBegin:
 lda #$02
 sta $21

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

gotoEnd:
 lda #$05
 sta $21

 ldy #$00
 lda #$05
 sta ($20), y
 JMP GETMOVE

text:       ; this is the Welcoming message
  dcb "H","e","l","l","o", ".", 32,"E","A","T", 32,"U","P", 32,"T","H","E", 32, "D","O","T","S", "!", 32, "M", "O", "V", "E", 32, "W", "I", "T", "H", 32, "A", 32, "W", 32, "S", 32, "D", 00

  
Reflection
I think there may still be some bugs. It's impossible that my code has no bug and work perfectly. However, it seems to work okay. Every time I do the lab, I find it extremely difficult and think like "it cannot get more difficult", but actually every week, it gets more and more difficult. This lab was extremely challenging. It took me 8 hours to build. It's rewarding in a sense that I made it and I didn't give up.
I would like to talk about the things that made it feel more difficult. There are quite a lot of information about 6502 instructions. However, there are not a lot of detailed examples or usuage. Therefore, when I was doing subtraction, my logic was correct but syntax was wrong, and i didn't know the syntax was wrong so I tried to solve where my logic went wrong, so I wasted quite a long time. Anthoer difficult thing is handling conditions, if it requires 2 nested conditions. For example, first check the ball is on the first row of A page, then check if the is the first page; in this case I need to make embedded Branch. This really makes things much more complicated. And the lack of register makes things difficult. I usually code with high level programming language and I can just easily make as many variables as I want and store the values any time easily. However, with this 6502, I had to use memory, and bring them in, and I can get only 2~3 at a time. The last thing that's challenging is that since I need a lot of branches, I had to name them properly so that later I don't get confused by the name.
To sum up, it was challening but rewarding. I kind of feel like I raised my IQ a few points by doing this lab. NONETHELESS, I really hope the labs will not get more difficult...

Comments

popular posts in this blog

Project Stage 2 - part 2 : Clone-Pruning Analysis Pass

Project Stage 2 part 4 - Testing clone-test-core.c file with Modified GCC file and making further modification

Project Stage 2 part 3 - Compile a program with revised GCC