|
Subject: [stella] Simple Joystick Input Reading Routine From: Ruffin Bailey <rufbo@xxxxxxxxxxx> Date: Sat, 27 Jun 1998 11:23:28 -0500 |
Well, it's about time I wrote some more code. I thought I'd start with
a real entry level joystick input reading routine. Hopefully this is
fairly well commented and easy to understand. The sprite is real basic
(just 10100101 for 16 scan lines) and there are no checks for
out-of-bounds movements. I would recommend opening the source
(joymove.a) in BBEdit or the like so that the long comments don't wrap
around, or chaging your font to something relatively small.
One word for DAsm users: You will need to change all byte and word
commands from "byte" and "word" to ".byte" and ".word". Sorry about
that. There are only two "words" at the end of this file.
Here's the main portion of code for reading SWCHA. It seems to have
lost some of its formatting in the paste. Let me know what you think!
; **********This is the routine to read the Player Zero
joystick**********
; One important thing to note is that this simple routine does NOT
check for
; out of bounds movements. If you move the sprite too far down off of
the
; screen, I don't know what would happen!
; SWCHA dissection:
; Player Zero Player One
;--------------- --------------
; D7 D6 D5 D4 D3 D2 D1 D0
; R L U Dwn R L U Dwn
lda #$00
sta HMP0 ; This is perhaps not the most elegant way to achieve
; this, but I want to make sure the sprite does not move
; in the horizontal or x-direction if the joystick doesn't
; point that way, so I'm init'n HMP0 now. As the porgram
; stands now, "a" already equals zero, but it won't
; hurt to be prepared for a code change above.
lda SWCHA ; load the byte that holds the joystick input
bmi next ; if D7 is a 1, P0 stick doesn't point right
ldy #%11110000 ; this will be a -1 movement (to the right)
sty HMP0 ; store in Horizontal Movement Player Zero
next
rol ; shuffle the bits to the left.
bmi next2 ; if D6 isn't zero, head to the next check
ldy #%00010000 ; switching D7 from 1 to a 0 makes this a +1 movement
sty HMP0 ; (to the left) put this in HMP0 Note that it is physically
; impossible to latch both D6 and D7 with a joystick, but
; if some hacker did, the end result would be a move to
; the left with this set-up. Try it in an emulator!
next2
rol
bmi next3
inc ypos ; if D5 is latched (ie, equals zero), move the sprite up
inc ypos ; two scan lines. Change the y position two scans
; Why two scans? B/c one is painfully slow!
next3
rol
bmi endofchk ; if D4 isn't latched, that's the last bit in SWCHA that
; deals with player zero. Go ahead and skip out of this
; joystick check routine if that's the case.
dec ypos ; Otherwise the joystick is pressing down, and the ypos
dec ypos ; of the sprite should be changed accordingly.
endofchk
nop ; There's no reason for this No Operation cmd other than
; I was an English major and hate to see any heading without
; an entry! ;)
Attachment:
joymove.bin
Description: .MPW Shell Document
include "6502"
include "vcs.h"
ypos equ $80
p0graph equ $81
; rasm -p -l JBPF2.asm >demo.lst
; PF0 | PF1 | PF2
; 4 5 6 7|7 6 5 4 3 2 1 0|0 1 2 3 4 5 6 7
;
org $F000
Start
SEI ; Disable interrupts, if there are any.
CLD ; Clear BCD math bit.
LDX #$FF
TXS ; Set stack to beginning.
LDA #0
B1 STA 0,X
DEX
BNE B1
lda #$50
sta ypos ; init ypos
JSR GameInit ; this just starts the game as if the reset switch was hit. -R
MainLoop
JSR VerticalBlank ;Execute the vertical blank.
JSR GameCalc ;Do calculations during Vblank
JSR DrawScreen ;Draw the screen
JSR OverScan ;Do more calculations during overscan
JMP MainLoop ;Continue forever.
VerticalBlank ;*********************** VERTICAL BLANK HANDLER
LDX #0
LDA #2
STA WSYNC
STA WSYNC
STA WSYNC
STA VSYNC ;Begin vertical sync.
STA WSYNC ; First line of VSYNC
STA WSYNC ; Second line of VSYNC.
LDA #44
STA TIM64T
LDA #0
STA CXCLR ; collison register
STA WSYNC ; Third line of VSYNC.
STA VSYNC ; (0)
RTS
GameCalc ;******************************* GAME CALCULATION ROUTINES
lda #%10001000 ; hopefully this is mid-lum blue
sta COLUP0 ; this is the temp color for the bean
lda #%00110110 ;
sta COLUPF ; this is the pf (platform) color
lda #%11011000 ; mid green
sta COLUP1 ; temp color for goals
lda #%00000000 ; bkgd test color
sta COLUBK ; store it in the background
lda #%00000000 ; un-mirrored playfield
sta CTRLPF
lda #%10100101 ; temp sprite graphic
sta p0graph
; **********This is the routine to read the Player Zero joystick**********
; One important thing to note is that this simple routine does NOT check for
; out of bounds movements. If you move the sprite too far down off of the
; screen, I don't know what would happen!
; SWCHA dissection:
; Player Zero Player One
;--------------- --------------
; D7 D6 D5 D4 D3 D2 D1 D0
; R L U Dwn R L U Dwn
lda #$00
sta HMP0 ; This is perhaps not the most elegant way to achieve
; this, but I want to make sure the sprite does not move
; in the horizontal or x-direction if the joystick doesn't
; point that way, so I'm init'n HMP0 now. As the porgram
; stands now, "a" already equals zero, but it won't
; hurt to be prepared for a code change above.
lda SWCHA ; load the byte that holds the joystick input
bmi next ; if D7 is a 1, P0 stick doesn't point right
ldy #%11110000 ; this will be a -1 movement (to the right)
sty HMP0 ; store in Horizontal Movement Player Zero
next
rol ; shuffle the bits to the left.
bmi next2 ; if D6 isn't zero, head to the next check
ldy #%00010000 ; switching D7 from 1 to a 0 makes this a +1 movement
sty HMP0 ; (to the left) put this in HMP0 Note that it is physically
; impossible to latch both D6 and D7 with a joystick, but
; if some hacker did, the end result would be a move to
; the left with this set-up. Try it in an emulator!
next2
rol
bmi next3
inc ypos ; if D5 is latched (ie, equals zero), move the sprite up
inc ypos ; two scan lines. Change the y position two scans
; Why two scans? B/c one is painfully slow!
next3
rol
bmi endofchk ; if D4 isn't latched, that's the last bit in SWCHA that
; deals with player zero. Go ahead and skip out of this
; joystick check routine if that's the case.
dec ypos ; Otherwise the joystick is pressing down, and the ypos
dec ypos ; of the sprite should be changed accordingly.
endofchk
nop ; There's no reason for this No Operation cmd other than
; I was an English major and hate to see any heading without
; an entry! ;)
DrawScreen ;**************************** SCREEN DRAWING ROUTINES
LDA INTIM
BNE DrawScreen ; Whew!
STA WSYNC
STA VBLANK ;End the VBLANK period with a zero. +2
ldx #$1 ; +2
ldy $AA
Stall
sta WSYNC
lda $B2
sta PF2
lda $B1
sta PF1
EOSchk ; End of Screen check
inx
cpx #$C1
beq Scan3
cpx ypos ; is this where the sprite should be drawn?
beq drawchar ; if this is the sprite's scanline, go draw it
sta WSYNC ; if not, wait for sync,
jmp EOSchk ; check for EOS and either start the next line or go to Scan3
drawchar
ldy #$01
sta RESMP0
sta WSYNC
EOSchk2
inx
cpx #$C1
beq Scan3
iny
lda p0graph ; holds the player0 graphic
sta GRP0 ; putting the with the graphic into GRP0 "enables" the
; sprite and makes it visible.
sta WSYNC
cpy #$10 ; let the sprite run over $10 or 16 scan lines.
bne EOSchk2
lda #$00
sta GRP0 ; turn Player Zero's sprite off so it doesn't run to the bottom
; of the screen!
jmp EOSchk
Scan3 ; this is where your code should kick out when the screen is
; finished
LDA #$02
STA WSYNC ;Finish this scanline.
STA VBLANK ; Make TIA output invisible,
; Now we need to worry about it bleeding when we turn
; the TIA output back on.
; X will be now zero.
LDX #$00
STX PF0
STX PF1
STX PF1
STX GRP0
STX GRP1
STX ENAM0
STX ENAM1
STX ENABL
sta HMOVE ; don't know what I'm doing
RTS
;
OverScan ;***************************** OVERSCAN CALCULATIONS
LDX #30
KillLines
STA WSYNC
DEX
BNE KillLines
RTS
;
; GameInit could conceivably be called when the Select key is pressed,
; or some other event.
;
GameInit
RTS
org $FFFC
word Start
word Start
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [stella] ~mactari NOT ~rufbo, Ruffin Bailey | Thread | [stella] BMI & BPL questions, Ruffin Bailey |
| Re: [stella] Linux?, Teknovore | Date | RE: [stella] TAsm?, John Saeger |
| Month |