Lab 2 COMPLETE
This is the second part of lab number 2 where I had to develop assembly code to change the bouncing pattern to bounce between the corners of the screen.
Before I start writing the actual code, I'm going to speculate on what needs to be done in order to achieve this effect. We already have a way to change the incrementation of the x and y pos, as previously written about in my previous post. The next step will be to check x and y boundaries so that the program will know when to bounce back and change the x and y increments into a negative value.
This is the code for the x and y position increments:
define XPOS $20
define YPOS $21
define XINC $22
define YINC $23
First we define the X and YINC variables and assign them in memory, then we will simply use LDA and STA to set their values.
; 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 XINC $22 ; X increment for bouncing
define YINC $23 ; Y increment for bouncing
; Set up the data structure
; The syntax #<LABEL returns the low byte of LABEL
; The syntax #>LABEL returns the high byte of LABEL
LDA #<G_X ; POINTER TO GRAPHIC
STA $10
LDA #>G_X
STA $11
LDA #$05
STA $12 ; IMAGE WIDTH
STA $13 ; IMAGE HEIGHT
; Set initial position X=Y=0
LDA #$00
STA XPOS
STA YPOS
; Set initial increment values
LDA #$01 ; Initial X increment is +1
STA XINC
LDA #$01 ; Initial Y increment is +1
STA YINC
; Main loop for diagonal bouncing animation
MAINLOOP:
; Set pointer to the image
; Use G_O or G_X as desired
LDA #<G_O
STA $10
LDA #>G_O
STA $11
; 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
LDX XPOS
LDA XINC
CLC
ADC XPOS
CMP #$00
BMI REVX
CMP #$1C
SKIPX:
; Increment the X position by XINC
LDA XPOS
CLC
ADC XINC
STA XPOS
LDY YPOS
LDA YINC
CLC
ADC YPOS
CMP #$00
BMI REVY
CMP #$1B
SKIPY:
; Increment the Y position by YINC
LDA YPOS
CLC
ADC YINC
STA YPOS
; Continue the main loop
JMP MAINLOOP
REVX:
; Reverse the X direction by negating XINC
LDA XINC
EOR #$FF
CLC
ADC #$01
STA XINC
JMP SKIPX
REVY:
; Reverse the Y direction by negating YINC
LDA YINC
EOR #$FF
ADC #$01
STA YINC
JMP SKIPY
; ==========================================
;
; 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
Comments
Post a Comment