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:
- Your program must work in the 6502 Emulator
- You must output to the character screen as well as the graphics (bitmapped) screen.
- You must accept user input from the keyboard in some form.
- 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
- I draw the orange-colored dots on the bit map on random locations per page
- I draw the ball(the user's ball) on the first pixel on the bit map($0200)
- I implemented the logic of GETCHAR, which get inputs from the user.
- I implemented the logic of moving the ball according to the user's input.
- When the user's ball hit or overlap the orange dot and move away, the organge dot disappear.
- 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
Post a Comment