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,$00There 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
Post a Comment