(lab3)6502 Program Lab

 In this lab, you will write code with arithmetic/math and strings in 6502 assembly language, including text output, graphical output, and keyboard input, in preparation for learning more complex x86_64 and AArch64 assembly language.

Resources

Tips and Techniques

  • Keyboard
  • Random number generator
    • A random byte is available at memory location $FE.
  • Drawing a Line
    • To draw a line between two arbitrary points (X1,Y1)(X2,Y2) where X2-X1 > Y2-Y1 and all coordinates are positive, calculate the rise/run, then set Y=Y1 and iterate for X=X1>X2 incrementing Y by the rise/run each step.
    • Do something similar with run/rise where X2-X1 < Y2-Y1
    • Suggestion: Use fixed-point math for the rise/run (aka deltaY) value. 16-bit values with the radix point between the bytes is a good option.

Lab 3

Decide What to Write

For this lab, write a program that meets these criteria:

  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)

For example, you could write a simple game:

  • A drawing program
  • A maze
  • A number guessing game (try to guess a random number in the shortest number of tries, getting feedback of “too high” or “too low” for each wrong guess)
  • Or any other type of game…

Or a calculator/converter:

  • An adding or subtracting calculator
  • A decimal-to-binary or hexidecimal-to-decimal converter
  • A inches-and-feet to centimeter converter
  • resistor colour band calculator
  • A program to draw bar or line graphs based on user input
  • Or any other type of calculator or converter…

Or anything else that meets the criteria above

You can interact with the user using either display. For example:

  • The main interaction could be on the graphical display, and instructions could be printed on the text display (which keys to use to move, for example); or
  • The main interaction could be on the text display, and an appropriate pattern could be shown on the bitmap display (for example, a version of hangman could display the words on the text display and the victim on the bitmapped display, or a calculator could use the text display for input and show a binary representation or a colour code on the graphical display (such as green for positive numbers, yellow for negative numbers, red for bad input)).

Tip: Keep it really simple! Assembly language is hard. Start simple, you can always add features later.

This program initializes some memory locations and then calls generate_maze to fill a memory region (MAZE_START) with a randomly generated maze by using a random seed (RANDOM_SEED) to determine walls (#) and paths ( ). It then calls draw_maze, which iterates through the stored maze and prints each character to the screen using CHROUT. After printing, the program loops back to start, continuously regenerating and displaying new mazes indefinitely.

; A random Maze Generator and Printer define NEWLINE $0d ; ASCII code for newline character define RANDOM_SEED $fe ; Random number generator seed define MAZE_SIZE 255 ; adjustable size define MAZE_START $0200 ; Start memory address for maze storage define WALL_CHAR $23 ; ASCII code for '#' (wall) define PATH_CHAR $20 ; ASCII code for ' ' (path/space) start: LDA #$00 ; Load 0 into the accumulator STA $40 ; Store 0 at memory address $40 LDA #$02 ; Load 2 into the accumulator STA $41 ; Store 2 at memory address $41 LDA #$01 ; Load 1 into the accumulator STA $42 ; Store 1 at memory address $42 jsr generate_maze ; Jump to the generate_maze subroutine jsr draw_maze ; Jump to the draw_maze subroutine jmp start ; Infinite loop, restart the program ;--------------------------------- ; Generate Maze Subroutine ;--------------------------------- generate_maze: LDX #$00 ; Initialize X register to 0 (maze index) maze_loop: LDA RANDOM_SEED ; Load random seed value AND #$03 ; Perform bitwise AND with 3 (generates values 0-3) CMP #$02 ; Compare result with 2 BCC set_path ; If result < 2, set as a path LDA #WALL_CHAR ; Otherwise, load wall character ('#') JMP store_maze ; Jump to store_maze set_path: LDA #PATH_CHAR ; Load path character (' ') store_maze: STA MAZE_START,X ; Store the selected character at memory MAZE_START + X INX ; Increment X register (move to the next position) CPX #MAZE_SIZE ; Compare X with the maze size limit BNE maze_loop ; If X < MAZE_SIZE, continue the loop RTS ; Return from subroutine ;--------------------------------- ; Draw Maze Subroutine ;--------------------------------- draw_maze: LDY #$00 ; Initialize Y register to 0 (maze index) print_loop: LDA MAZE_START,Y ; Load character from maze memory at index Y BEQ maze_done ; If the value is zero, exit drawing JSR CHROUT ; Call CHROUT (prints the character on screen) INY ; Increment Y (move to the next character) JMP print_loop ; Repeat the loop maze_done: RTS ; Return from subroutine ; ROM routine for character output define CHROUT $ffd2 ; Kernel routine to output a character to the screen


run result:


My experience:

I worked with a lot assembly features in this lab, such as direct memory manipulation, random number usage, and infinite loops. It also demonstrates the importance of structured subroutines (JSR/RTS) and efficient branching for performance. Assembly language is more difficult than any other language I have ever learned, and I had to research a lot of materials to properly understand it.


Comments

Popular posts from this blog

(lab1)6502 Assembly Language Lab

(Lab4) GCC Build Lab

(lab2)6502 Math Lab