Lab 2 - Challenges

 Lab 2 - Challenges

I was able to complete one of the challenges: Change the graphic image or colour each time it bounces.

I have highlighted the changes.

;
; draw-image-subroutine.6502
;
; This is a routine that can place an arbitrary 
; rectangular image on to the screen at given
; coordinates.
;
; Chris Tyler 2024-09-17
; Licensed under GPLv2+
;

;
; The subroutine is below starting at the 
; label "DRAW:"
;

; Test code for our subroutine
; Moves an image diagonally across the screen

; Zero-page variables
define XPOS $20
define YPOS $21
define XDIR $22
define YDIR $23
define IMAGECHANGE $24

START:

; Set up the width and height elements of the data structure
  LDA #$05
  STA $12       ; IMAGE WIDTH
  STA $13       ; IMAGE HEIGHT

; Set initial position X=Y=0
  LDA #$11
  STA XPOS
  LDA #$00
  STA YPOS

; Set initial direction X+1=X, Y+1=Y
  LDA #$01
  STA XDIR
  STA YDIR

; Set IMAGECHANGE=0
  LDA #$00
  STA IMAGECHANGE

; Main loop for diagonal animation
MAINLOOP:

  ; Set pointer to the image
  ; Use G_O or G_X as desired
  ; The syntax #<LABEL returns the low byte of LABEL
  ; The syntax #>LABEL returns the high byte of LABEL
  LDA IMAGECHANGE
  BEQ LOADO
  BNE LOADX
  
LOADO:
  LDA #<G_O
  STA $10
  LDA #>G_O
  STA $11
  JMP MAIN
LOADX:
  LDA #<G_X
  STA $10
  LDA #>G_X
  STA $11
  JMP MAIN

MAIN:
  ; Place the image on the screen
  LDA #$10  ; Address in zeropage of the data structure
  LDX XPOS  ; X position
  LDY YPOS  ; Y position
  JSR DRAW  ; Call the subroutine

  ; Delay to show the image
  LDY #$00
  LDX #$50
DELAY:
  DEY
  BNE DELAY
  DEX
  BNE DELAY

  ; Set pointer to the blank graphic
  LDA #<G_BLANK
  STA $10
  LDA #>G_BLANK
  STA $11

  ; Draw the blank graphic to clear the old image
  LDA #$10 ; LOCATION OF DATA STRUCTURE
  LDX XPOS
  LDY YPOS
  JSR DRAW

  ; Increment the position
  LDA XPOS
  CLC
  ADC XDIR
  STA XPOS

  LDA YPOS
  CLC
  ADC YDIR
  STA YPOS
  
  ; Edge Checks
  ; Left and Right edge check
  LDA XPOS
  ; Check if XPOS reach left edge, compare with #$00
  BEQ REACHL
  ; Check if XPOS reach right edge, compare with #$1b
  CMP #$1b
  BCS REACHR

  ; Top and Bottom edge check
  LDA YPOS
  ; Check if YPOS reach top edge, compare with #$00
  BEQ REACHT
  ; Check if YPOST reach bottom edge, compare with #$1b
  CMP #$1b
  BCS REACHB

  BNE MAINLOOP

  ; Change direction
REACHR:
  LDA #$FF
  STA XDIR
  JMP CHANGEIMAGE
REACHL:
  LDA #$01
  STA XDIR
  JMP CHANGEIMAGE
REACHT:
  LDA #$01
  STA YDIR
  JMP CHANGEIMAGE
REACHB:
  LDA #$FF
  STA YDIR
  JMP CHANGEIMAGE

CHANGEIMAGE:
  LDA IMAGECHANGE
  BEQ CHANGETOO
  BNE CHNAGETOX
CHNAGETOX:
  INC IMAGECHANGE

  ; Change graphic color
  LDA #<G_X
  STA $10
  LDA #>G_X
  STA $11
  LDA $fe
  LDY #$00
  STA ($10), Y
  LDY #$04
  STA ($10), Y
  LDY #$06
  STA ($10), Y
  LDY #$08
  STA ($10), Y
  LDY #$0C
  STA ($10), Y
  LDY #$10
  STA ($10), Y
  LDY #$12
  STA ($10), Y
  LDY #$14
  STA ($10), Y
  LDY #$18
  STA ($10), Y

  JMP MAINLOOP
CHANGETOO:
  DEC IMAGECHANGE

  ; Change graphic color
  LDA #<G_O
  STA $10
  LDA #>G_O
  STA $11
  LDA $fe
  LDY #$01
  STA ($10), Y
  INY
  STA ($10), Y
  INY
  STA ($10), Y
  LDY #$05
  STA ($10), Y
  LDY #$09
  STA ($10), Y
  INY
  STA ($10), Y
  LDY #$0E
  STA ($10), Y
  INY
  STA ($10), Y
  LDY #$13
  STA ($10), Y
  LDY #$15
  STA ($10), Y
  INY
  STA ($10), Y
  INY
  STA ($10), Y

  JMP MAINLOOP

; ==========================================
;
; DRAW :: Subroutine to draw an image on 
;         the bitmapped display
;
; Entry conditions:
;    A - location in zero page of: 
;        a pointer to the image (2 bytes)
;        followed by the image width (1 byte)
;        followed by the image height (1 byte)
;    X - horizontal location to put the image
;    Y - vertical location to put the image
;
; Exit conditions:
;    All registers are undefined
;
; Zero-page memory locations
define IMGPTR    $A0
define IMGPTRH   $A1
define IMGWIDTH  $A2
define IMGHEIGHT $A3
define SCRPTR    $A4
define SCRPTRH   $A5
define SCRX      $A6
define SCRY      $A7

DRAW:
  ; SAVE THE X AND Y REG VALUES
  STY SCRY
  STX SCRX

  ; GET THE DATA STRUCTURE
  TAY
  LDA $0000,Y
  STA IMGPTR
  LDA $0001,Y
  STA IMGPTRH
  LDA $0002,Y
  STA IMGWIDTH
  LDA $0003,Y
  STA IMGHEIGHT

  ; CALCULATE THE START OF THE IMAGE ON
  ; SCREEN AND PLACE IN SCRPTRH
  ;
  ; THIS IS $0200 (START OF SCREEN) +
  ; SCRX + SCRY * 32
  ; 
  ; WE'LL DO THE MULTIPLICATION FIRST
  ; START BY PLACING SCRY INTO SCRPTR
  LDA #$00
  STA SCRPTRH
  LDA SCRY
  STA SCRPTR
  ; NOW DO 5 LEFT SHIFTS TO MULTIPLY BY 32
  LDY #$05     ; NUMBER OF SHIFTS
MULT:
  ASL SCRPTR   ; PERFORM 16-BIT LEFT SHIFT
  ROL SCRPTRH
  DEY
  BNE MULT

  ; NOW ADD THE X VALUE
  LDA SCRX
  CLC
  ADC SCRPTR
  STA SCRPTR
  LDA #$00
  ADC SCRPTRH
  STA SCRPTRH

  ; NOW ADD THE SCREEN BASE ADDRESS OF $0200
  ; SINCE THE LOW BYTE IS $00 WE CAN IGNORE IT
  LDA #$02
  CLC
  ADC SCRPTRH
  STA SCRPTRH
  ; NOTE WE COULD HAVE DONE TWO: INC SCRPTRH

  ; NOW WE HAVE A POINTER TO THE IMAGE IN MEM
  ; COPY A ROW OF IMAGE DATA
COPYROW:
  LDY #$00
ROWLOOP:
  LDA (IMGPTR),Y
  STA (SCRPTR),Y
  INY
  CPY IMGWIDTH
  BNE ROWLOOP

  ; NOW WE NEED TO ADVANCE TO THE NEXT ROW
  ; ADD IMGWIDTH TO THE IMGPTR
  LDA IMGWIDTH
  CLC
  ADC IMGPTR
  STA IMGPTR
  LDA #$00
  ADC IMGPTRH
  STA IMGPTRH
 
  ; ADD 32 TO THE SCRPTR
  LDA #32
  CLC
  ADC SCRPTR
  STA SCRPTR
  LDA #$00
  ADC SCRPTRH
  STA SCRPTRH

  ; DECREMENT THE LINE COUNT AND SEE IF WE'RE
  ; DONE
  DEC IMGHEIGHT
  BNE COPYROW

  RTS

; ==========================================

; 5x5 pixel images

; Image of a blue "O" on black background
G_O:
DCB $00,$0e,$0e,$0e,$00
DCB $0e,$00,$00,$00,$0e
DCB $0e,$00,$00,$00,$0e
DCB $0e,$00,$00,$00,$0e
DCB $00,$0e,$0e,$0e,$00

; Image of a yellow "X" on a black background
G_X:
DCB $07,$00,$00,$00,$07
DCB $00,$07,$00,$07,$00
DCB $00,$00,$07,$00,$00
DCB $00,$07,$00,$07,$00
DCB $07,$00,$00,$00,$07

; Image of a black square
G_BLANK:
DCB $00,$00,$00,$00,$00
DCB $00,$00,$00,$00,$00
DCB $00,$00,$00,$00,$00
DCB $00,$00,$00,$00,$00
DCB $00,$00,$00,$00,$00

There are only two graphics, X and O. So, I defined a variable, IMAGECHANGE, as a switch, 0 and 1. IMAGECHANGE will increase by 1 or decrease by 1 when the graphic bounces. When IMAGECHANGE is 0, an O graphic is printed; when it is 1, an X graphic is printed. Meanwhile, the color will change during each bouncing by changing the graphic pixels one by one.

The result is shown below:



Comments

Popular posts from this blog

Project - Stage 1: Create a Basic GCC Pass

Lab 4 - GCC Build