Lab 2 - 6502 Math Lab
For the "Bouncing Graphic"
1. Introduction:
It is the advanced version that implement four parts to make the graphic bounce when it hits the edge of the bitmapped.
The basic version was making the graphic(A dot or a circle) from A point moves to B point and re-run it again.
Therefore, the advanced version is making the graphic moves from left to right or bottom to top, or from right to left or from top to bottom.
2. Coding
The following code is about this assembly program:
;; draw-image-subroutine.6502;; This is a routine that can place an arbitrary; rectangular image on to the screen at given; coordinates.;; Chris Tyler made on 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 variablesdefine XPOS $20define YPOS $21define XINC $22define YINC $23START:; Set up the width and height elements of the data structureLDA #$05STA $12 ; IMAGE WIDTHSTA $13 ; IMAGE HEIGHT; Set initial position X=10 Y=15LDA #$0ASTA XPOSLDA #$0FSTA YPOS; Set initial incrementsLDA #$01STA XINCLDA #$FF ; -1 in two's complementSTA YINC; Main loop for diagonal animationMAINLOOP:; 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 LABELLDA #<G_OSTA $10LDA #>G_OSTA $11; Place the image on the screenLDA #$10 ; Address in zeropage of the data structureLDX XPOS ; X positionLDY YPOS ; Y positionJSR DRAW ; Call the subroutine; DelayJSR DELAY; Clear the old imageLDA #<G_BLANKSTA $10LDA #>G_BLANKSTA $11LDA #$10LDX XPOSLDY YPOSJSR DRAW; Update positionCLCLDA XPOSADC XINCSTA XPOSCLCLDA YPOSADC YINCSTA YPOS; Check for horizontal boundsLDA XPOSCMP #$00BEQ BOUNCE_XCMP #$1B ; 32 - 5 (image width)BEQ BOUNCE_XJMP CHECK_YBOUNCE_X:LDA XINCEOR #$FF ; Flip all bitsCLCADC #$01 ; Add 1 to get two's complementSTA XINCCHECK_Y:LDA YPOSCMP #$00BEQ BOUNCE_YCMP #$1B ; 32 - 5 (image height)BEQ BOUNCE_YJMP CONTINUEBOUNCE_Y:LDA YINCEOR #$FFCLCADC #$01STA YINCCONTINUE:JMP MAINLOOPDELAY:; Delay to show the imageLDY #$00LDX #$50DELAY_LOOP:DEYBNE DELAY_LOOPDEXBNE DELAY_LOOPRTS; Continue for 29 frames of animationLDA #28CMP XPOSBNE MAINLOOP; Repeat infinitelyJMP START; ==========================================;; 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 locationsdefine IMGPTR $A0define IMGPTRH $A1define IMGWIDTH $A2define IMGHEIGHT $A3define SCRPTR $A4define SCRPTRH $A5define SCRX $A6define SCRY $A7DRAW:; SAVE THE X AND Y REG VALUESSTY SCRYSTX SCRX; GET THE DATA STRUCTURETAYLDA $0000,YSTA IMGPTRLDA $0001,YSTA IMGPTRHLDA $0002,YSTA IMGWIDTHLDA $0003,YSTA 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 SCRPTRLDA #$00STA SCRPTRHLDA SCRYSTA SCRPTR; NOW DO 5 LEFT SHIFTS TO MULTIPLY BY 32LDY #$05 ; NUMBER OF SHIFTSMULT:ASL SCRPTR ; PERFORM 16-BIT LEFT SHIFTROL SCRPTRHDEYBNE MULT; NOW ADD THE X VALUELDA SCRXCLCADC SCRPTRSTA SCRPTRLDA #$00ADC SCRPTRHSTA SCRPTRH; NOW ADD THE SCREEN BASE ADDRESS OF $0200; SINCE THE LOW BYTE IS $00 WE CAN IGNORE ITLDA #$02CLCADC SCRPTRHSTA SCRPTRH; NOTE WE COULD HAVE DONE TWO: INC SCRPTRH; NOW WE HAVE A POINTER TO THE IMAGE IN MEM; COPY A ROW OF IMAGE DATACOPYROW:LDY #$00ROWLOOP:LDA (IMGPTR),YSTA (SCRPTR),YINYCPY IMGWIDTHBNE ROWLOOP; NOW WE NEED TO ADVANCE TO THE NEXT ROW; ADD IMGWIDTH TO THE IMGPTRLDA IMGWIDTHCLCADC IMGPTRSTA IMGPTRLDA #$00ADC IMGPTRHSTA IMGPTRH; ADD 32 TO THE SCRPTRLDA #32CLCADC SCRPTRSTA SCRPTRLDA #$00ADC SCRPTRHSTA SCRPTRH; DECREMENT THE LINE COUNT AND SEE IF WE'RE; DONEDEC IMGHEIGHTBNE COPYROWRTS; ==========================================; 5x5 pixel images; Image of a blue "O" on black backgroundG_O:DCB $00,$0e,$0e,$0e,$00DCB $0e,$00,$00,$00,$0eDCB $0e,$00,$00,$00,$0eDCB $0e,$00,$00,$00,$0eDCB $00,$0e,$0e,$0e,$00; Image of a yellow "X" on a black backgroundG_X:DCB $07,$00,$00,$00,$07DCB $00,$07,$00,$07,$00DCB $00,$00,$07,$00,$00DCB $00,$07,$00,$07,$00DCB $07,$00,$00,$00,$07; Image of a black squareG_BLANK:DCB $00,$00,$00,$00,$00DCB $00,$00,$00,$00,$00DCB $00,$00,$00,$00,$00DCB $00,$00,$00,$00,$00DCB $00,$00,$00,$00,$00
3. Describe
To make the graphic bounce when it hits the edge of the bitmapped by the following four parts:
1.
; Update position
; Update position
CLC
LDA XPOS
ADC XINC
STA XPOS
CLC
LDA YPOS
ADC YINC
STA YPOS
; Check for horizontal bounds
LDA XPOS
CMP #$00
BEQ BOUNCE_X
CMP #$1B ; 32 - 5 (image width)
BEQ BOUNCE_X
JMP CHECK_Y
2.
BOUNCE_X:
LDA XINC
EOR #$FF ; Flip all bits
CLC
ADC #$01 ; Add 1 to get two's complement
STA XINC
3.
CHECK_Y:
LDA YPOS
CMP #$00
BEQ BOUNCE_Y
CMP #$1B ; 32 - 5 (image height)
BEQ BOUNCE_Y
JMP CONTINUE
4.
BOUNCE_Y:
LDA YINC
EOR #$FF
CLC
ADC #$01
STA YINC
4. Reflection
The first part is about checking the XPOS which means does graphic hits the horizontal bounds and to update the position of the graphic.
The second part is for after the graphic was hit the horizontal bounds and flip the bits by add 1 to change the movement.
The third part is the opposite of the first part that checking the YPOS hits the vertical bounds and to call the fourth part.
The fourth part is almost the same as the second part and flip the bits by add 1 to move the graphic as well.
From this lab I learned something like in the modern programming languages that I wanted to compare and I would use IF-ELSE statement; however, in assembly language that I could just use CMP and Hexadecimal instead IF-ELSE.
留言
張貼留言