Understanding 6502 assembly on the Commodore 64 - (8) Inputs in Assembly

Lets continue with our wonderful Commodore logo, we will use the code from the last chapters but we will stop after the creation of the sprite.  Ill include the code below to plug into Relaunch64.  By taking advantage of some more kernel functions, we can make the program a bit more interactive.









Remember of course, I'm trying to keep this as simple as possible.  In this program we create the sprite and RTS back to basic

; Jordans Super duper commodore logo maker 
; 64TASS assembler style code for 6502     
; Jordan Rubin 2014 http://technocoma.blogspot.com
;
;Creates a commodore logo SPRITE , returns to basic
;
;
; start program type SYS 49152
*=$C000

;;;;;;WORDS ARE EASIER TO REMEMBER THAN ADDRESSES, LETS ASSIGN NAMES TO OUR ADRESSES


; Sprite Enable Register

SPENA = $D015

; Sprite Shape Data Pointers

SSDP0 = $07F8
SSDP1 = $07F9

; Sprite 0 Horizontal Position

SP0X = $D000

; Sprite 0 Vertical Position

SP0Y = $D001

; Sprite 1 Horizontal Position

SP1X = $D002

; Sprite 1 Vertical Position

SP1Y = $D003

; Most Significant Bits of Sprites 0-7 Horizontal Position

MSIGX = $D010

; Sprite Vertical Expansion Register

YXPAND = $D017

; Sprite Horizontal Expansion Register

XXPAND = $D01D

; Sprite 0 Color Register

SP0COL = $D027

; Sprite 1 Color Register

SP1COL = $D028

; Sprite Multicolor Registers

SPMC = $D01C

; Sprite 0 data start

SP0DATA = $02C0

; Character out

CHROUT = $FFD2


;;;;;;;;;;;;; Load 147, hex $93 into A reg and JSR to CHROUT (Clears the screen)

START:
lda #$93
jsr CHROUT

lda #$01

sta SPENA

lda #$AA

sta SP0X

lda #$8F

sta SP0Y

lda #$0B

sta SSDP0

;;;;;;;;;;;;;;;;;;;; This is a very quick and easy loader to move the sprite data

;;;;;;;;;;;;;;;;;;;; Into memory area SP0DATA, reading each byte and incrementing
;;;;;;;;;;;;;;;;;;;; the address until weve reached all 64 bytes, hex $40
SP0INIT:
ldx #$00
jsr SPR0LOADLOOP
rts

SPR0LOADLOOP:

lda SPRITE0DATA,x
sta SP0DATA,x
inx
cpx #$40
bne SPR0LOADLOOP
rts

; DUMP OUT SPRITE DATA INTO OUR AREA SP0DATA

SPRITE0DATA:
.byte $03, $FF, $00, $07, $FF, $80, $0F, $FF, $80, $1F, $83, $80, $3E, $00, $80
.byte $7C, $00, $7F, $78, $00, $7E, $F8, $00, $7C, $F0, $00, $78, $F0, $00, $70 
.byte $F0, $00, $00, $F0, $00, $70, $F0, $00, $78, $F8, $00, $7C, $78, $00, $7E 
.byte $7C, $00, $7F, $3E, $00, $80, $1F, $83, $80, $0F, $FF, $80, $07, $FF, $80 
.byte $03, $FF, $00, $00        



We have two new kernal functions to employ, from our memory map guide:


$FF9F SCNKEY (60039, $EA87) scan the keyboard
$FFE4 GETIN  (via 810 ($32A) to 61758, $F13E) get a character

To begin we will add this to our list of labels up top


; Scan keyboard for keypress
     SCNKEY = $FF9F     
          
; Get Input
     GETIN = $FFE4


In our area called SP0INIT we have the following
SP0INIT:
ldx #$00
jsr SPR0LOADLOOP
rts

After calling (jsr) our SPRLOADLOOP it comes back and hits arts and ends, lets change this to not jump to a subroutine but actually jump to an entirely different area from which it will never return.
We can leave the RTS for posterity, but it will never be executed


SP0INIT:
ldx #$00
jsr SPR0LOADLOOP
jmp SCANKBD
rts


Naturally we will need a label called SCANKBD: in our program from which we call our 2 new functions.  From here we start our never ending loop of:

1. SCANNING THE KEYBOARD
2. DUMPING THE KEY VALUE INTOP THE ACCUMULATOR
3. JSR TO AN INSTRUCTION OF WHAT TO DO BASED ON THE KEY PRESSED

SCANKBD:
jsr SCNKEY
jsr GETIN

Directly under this I all another label to test which key was pressed and what subroutine it should JSR to if the key is pressed, were going to start small here, and only jump to one given routine if the letter C is pressed. What we want is the colors to cycle by one, each time C is pressed, and rescan for the next key


TEST:
; Look for the letter C (dec 67)
cmp #67 
; If its 67 JSR to COLORCHANGE routine
beq COLORCHANGE
; Repeat this process over and over
jmp SCANKBD            

COLORCHANGE:

; Load Y register with current color
ldy SP0COL
; Increment Y , Y=Y+1
iny
; Store value in Y to SP0COL
sty SP0COL
; Jump back to SCANKBD
jmp SCANKBD


The color change routine is really simple and self explanatory, in making it easy there is no test to see what the current color is, and how it should wrap around if it hits the last color, we happen to get lucky at that memory address and it seems to work.

We have no way out of our program though.  While this is not entirely important, it is bad practice.
Lets add to this, so that when 'E' is pressed, the program ends

First we will add onto our TEST label

TEST:
; Look for the letter C (dec 67)
cmp #67 
; If its 67 JSR to COLORCHANGE routine
beq COLORCHANGE
cmp #69 
; If its 69 JSR to END routine
beq END
; Repeat this process over and over
jmp SCANKBD    

Now we can add a routine under COLORCHANGE called END, in this we just put a command to deactivate the sprite and then rts to end the program.


END:
ldy #$00
sty SPENA
rts


 Truly there is no limit to the amount of things we can do, in the next chapter we will expand upon this.

The final code is presented below, so you can but and paste it into relaunch64

; Jordans Super duper commodore logo maker, mover and shaker 
; 64TASS assembler style code for 6502     
; Jordan Rubin 2014 http://technocoma.blogspot.com
;
;Creates a commodore logo SPRITE , moves it to the to right and makes it red 
;
;
; start program type SYS 49152
*=$C000

;;;;;;WORDS ARE EASIER TO REMEMBER THAN ADDRESSES, LETS ASSIGN NAMES TO OUR ADRESSES


; Sprite Enable Register

SPENA = $D015

; Sprite Shape Data Pointers

SSDP0 = $07F8
SSDP1 = $07F9

; Sprite 0 Horizontal Position

SP0X = $D000

; Sprite 0 Vertical Position

SP0Y = $D001

; Sprite 1 Horizontal Position

SP1X = $D002

; Sprite 1 Vertical Position

SP1Y = $D003

; Most Significant Bits of Sprites 0-7 Horizontal Position

MSIGX = $D010

; Sprite Vertical Expansion Register

YXPAND = $D017

; Sprite Horizontal Expansion Register

XXPAND = $D01D

; Sprite 0 Color Register

SP0COL = $D027

; Sprite 1 Color Register

SP1COL = $D028

; Sprite Multicolor Registers

SPMC = $D01C

; Sprite 0 data start

SP0DATA = $02C0

; Character out

CHROUT = $FFD2

; Scan keyboard for keypress
SCNKEY = $FF9F

; Get Input
GETIN = $FFE4


;;;;;;;;;;;;; Load 147, hex $93 into A reg and JSR to CHROUT (Clears the screen)

START:
lda #$93
jsr CHROUT

lda #$01

sta SPENA

lda #$AA

sta SP0X

lda #$8F

sta SP0Y

lda #$0B

sta SSDP0

;;;;;;;;;;;;;;;;;;;; This is a very quick and easy loader to move the sprite data

;;;;;;;;;;;;;;;;;;;; Into memory area SP0DATA, reading each byte and incrementing 
;;;;;;;;;;;;;;;;;;;; the address until weve reached all 64 bytes, hex $40

SP0INIT:

ldx #$00
jsr SPR0LOADLOOP
jmp SCANKBD
rts

SPR0LOADLOOP:

lda SPRITE0DATA,x
sta SP0DATA,x
inx
cpx #$40
bne SPR0LOADLOOP
rts

;;;;;;;;;;;;;;;;  Our scan keyboard function, if a key is pressed, it will appear

;;;;;;;;;;;;;;;;  In the accumulator, hex value
SCANKBD:
jsr SCNKEY
jsr GETIN 

TEST:

; Is the key C
cmp #67
beq COLORCHANGE
; Is the key E
cmp #69
beq END    
jmp SCANKBD

COLORCHANGE:

ldy SP0COL
iny
sty SP0COL
jmp SCANKBD

END:

ldy #$00
sty SPENA
rts

; DUMP OUT SPRITE DATA INTO OUR AREA SP0DATA

SPRITE0DATA:
.byte $03, $FF, $00, $07, $FF, $80, $0F, $FF, $80, $1F, $83, $80, $3E, $00, $80
.byte $7C, $00, $7F, $78, $00, $7E, $F8, $00, $7C, $F0, $00, $78, $F0, $00, $70 
.byte $F0, $00, $00, $F0, $00, $70, $F0, $00, $78, $F8, $00, $7C, $78, $00, $7E 
.byte $7C, $00, $7F, $3E, $00, $80, $1F, $83, $80, $0F, $FF, $80, $07, $FF, $80 
.byte $03, $FF, $00, $00                         


NEXT----->
Understanding 6502 assembly on the Commodore 64 - (9) The Hexadecimal Conundrum

Table of contents

No comments:

Post a Comment