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 |