In this post I explore how to read from the joystick. This program is very similar to the one in my last post about reading the console keys. There are some big changes in the decision tree, and of course minor ones in the output strings.
The decision tree still uses the BEQ and BNE instructions, but in a slightly different fashion. Due to the length of code to process all the directions the comparisons couldn’t be placed consecutively (CMP, BEQ, CMP, BEQ, etc). BEQ and BNE only allow execution changes up to 128 bytes away from the branch instruction itself. To accommodate I moved each direction handler inline with the compare. The big difference is now instead of BEQ (if the compare equals), I used BNE (the compare does not equal), and the BNE changes program execution to the next direction handler. This effectively keeps each branch at a minimal distance away.
Library Code
As with last time, I added to my A8 Assembly library to support the joystick. Just the additions are listed.
A8DEFS.LIB Code
1500 ; Joystick 1502 STICK0 = $0278 ;632 1504 STICK1 = $0279 ;633 1510 JOYNO = $0F ;15 1512 JOYU = $0E ;14 1514 JOYD = $0D ;13 1516 JOYL = $0B ;11 1518 JOYR = $07 ;7 1520 JOYUL = $0A ;10 1522 JOYUR = $06 ;6 1524 JOYDL = $09 ;9 1526 JOYDR = $05 ;5 1530 STRIG0 = $0284 ;644 1532 STRIG1 = $0285 ;645
Source Code
01 ; ------------------------------ 02 ; App.: STICK.M65 03 ; Desc: Stick Control Detection 04 ; ------------------------------ 10 .TITLE "Stick, Version 1.0" 15 .OPT OBJ,NO EJECT 20 *= $3600 25 .INCLUDE #D2:A8DEFS.LIB 0200 ; ------------------------------ 0201 ; Setup App 0202 ; ------------------------------ 0204 APPST 0210 ; Set Margin 0212 LDA #0 0214 STA LMARG 0220 ; Cursor Off 0222 LDA #1 0224 STA CRSINH 0319 ; Setup Screen 0320 ; Position 0,0 0322 LDX #0 0324 LDY #0 0326 JSR CURXY 0330 ; Print Title 0332 LDA #STITLE/256 0334 LDY #STITLE&255 0336 JSR PRTLN 0340 ; Position 0,2 0342 LDX #0 0344 LDY #2 0346 JSR CURXY 0350 ; Print Statement 0352 LDA #SEXIT/256 0354 LDY #SEXIT&255 0356 JSR PRTLN 0400 ; Position 0,4 0402 LDX #0 0404 LDY #4 0406 JSR CURXY 0410 ; Print Statement 0412 LDA #SMSG/256 0414 LDY #SMSG&255 0416 JSR PRTLN 0500 ; ------------------------------ 0501 ; Read Loop 0502 ; ------------------------------ 0510 RDLOOP 0520 ; Check Button 1 0522 LDA STRIG0 0524 CMP #0 0526 BEQ RJFIRE 0530 ; Check Joystick 1 0532 LDA STICK0 0534 STA IDIR 0536 CMP #JOYNO 0538 BNE JMOVED 0550 ; Goto start of loop 0552 JMP RDLOOP 1000 ; ------------------------------ 1001 ; Fire Button 1002 ; ------------------------------ 1010 RJFIRE 1020 JSR RCLEAR 1021 ; Print FIRE 1022 LDA #SJFIRE/256 1024 LDY #SJFIRE&255 1026 JSR PRTLN 1027 ; Goto APPDON (exit) 1028 JMP APPDON 1100 ; ------------------------------ 1101 ; Stick Moved 1102 ; ------------------------------ 1110 JMOVED 1112 ; Clear text 1114 JSR RCLEAR 1120 ; Which way? 1122 LDA IDIR 1200 ; ------------------------------ 1201 ; Up 1202 ; ------------------------------ 1210 RJU 1212 CMP #JOYU ; 14-Up 1214 BNE RJD 1220 ; Print UP 1222 LDA #SJU/256 1224 LDX #SJU&255 1226 JSR PRTCH 1230 ; Goto loop start 1232 JMP RDLOOP 1300 ; ------------------------------ 1301 ; Down 1302 ; ------------------------------ 1310 RJD 1312 CMP #JOYD ; 13-Down 1314 BNE RJL 1320 ; Print DOWN 1322 LDA #SJD/256 1324 LDX #SJD&255 1326 JSR PRTCH 1330 ; Goto loop start 1332 JMP RDLOOP 1400 ; ------------------------------ 1401 ; Left 1402 ; ------------------------------ 1410 RJL 1412 CMP #JOYL ; 11-Left 1414 BNE RJR 1420 ; Print LEFT 1422 LDA #SJL/256 1424 LDX #SJL&255 1426 JSR PRTCH 1430 ; Goto loop start 1432 JMP RDLOOP 1500 ; ------------------------------ 1501 ; Right 1502 ; ------------------------------ 1510 RJR 1512 CMP #JOYR ; 7-Right 1514 BNE RJUL 1520 ; Print RIGHT 1522 LDA #SJR/256 1524 LDX #SJR&255 1526 JSR PRTCH 1530 ; Goto loop start 1532 JMP RDLOOP 1600 ; ------------------------------ 1601 ; Up + Left 1602 ; ------------------------------ 1610 RJUL 1612 CMP #JOYUL ; 10-Up+Left 1614 BNE RJUR 1620 ; Print UP 1622 LDA #SJU/256 1624 LDX #SJU&255 1626 JSR PRTCH 1630 ; Print LEFT 1632 LDA #SJL/256 1634 LDX #SJL&255 1636 JSR PRTCH 1640 ; Goto loop start 1642 JMP RDLOOP 1700 ; ------------------------------ 1701 ; Up + Right 1702 ; ------------------------------ 1710 RJUR 1712 CMP #JOYUR ; 6-Up+Right 1714 BNE RJDL 1720 ; Print UP 1722 LDA #SJU/256 1724 LDX #SJU&255 1726 JSR PRTCH 1730 ; Print RIGHT 1732 LDA #SJR/256 1734 LDX #SJR&255 1736 JSR PRTCH 1740 ; Goto loop start 1742 JMP RDLOOP 1800 ; ------------------------------ 1801 ; Down + Left 1802 ; ------------------------------ 1810 RJDL 1812 CMP #JOYDL ; 9-Down+Left 1814 BNE RJDR 1820 ; Print DOWN 1822 LDA #SJD/256 1824 LDX #SJD&255 1826 JSR PRTCH 1830 ; Print LEFT 1832 LDA #SJL/256 1834 LDX #SJL&255 1836 JSR PRTCH 1840 ; Goto loop start 1842 JMP RDLOOP 1900 ; ------------------------------ 1901 ; Down + Right 1902 ; ------------------------------ 1910 RJDR 1912 CMP #JOYDR ; 5-Down+Right 1914 BNE RDLEND 1920 ; Print DOWN 1922 LDA #SJD/256 1924 LDX #SJD&255 1926 JSR PRTCH 1930 ; Print RIGHT 1932 LDA #SJR/256 1934 LDX #SJR&255 1936 JSR PRTCH 1940 ; Goto loop start 1942 JMP RDLOOP 2000 ; ------------------------------ 2001 ; Loop For Next Press Check 2002 ; ------------------------------ 2010 RDLEND 2012 JMP RDLOOP 2100 ; ------------------------------ 2101 ; End Of Program 2102 ; ------------------------------ 2110 APPDON 2119 ; Turn cursor on 2120 LDA #0 2122 STA CRSINH 2129 ; Exit program 2130 RTS 2500 ; ------------------------------ 2501 ; Clear Key Pressed Text 2502 ; ------------------------------ 2510 RCLEAR 2512 ; Position 13,4 2514 LDX #13 2516 LDY #4 2518 JSR CURXY 2520 ; Print blank 2522 LDA #SJNONE/256 2524 LDX #SJNONE&255 2526 JSR PRTCH 2530 ; Position 13,4 2532 LDX #13 2534 LDY #4 2536 JSR CURXY 2539 ; Exit routine 2540 RTS 030000 ; ----- String Data ----- 030002 STITLE .BYTE CLS,"-|STICK|--------------------------------",EOL 030004 SEXIT .BYTE "Press FIRE button to exit.",EOL 030006 SMSG .BYTE "You pressed: ",EOL 030010 SJFIRE .BYTE "FIRE",EOL 030020 SJU .BYTE "UP ",EOS 030022 SJD .BYTE "DOWN ",EOS 030024 SJL .BYTE "LEFT ",EOS 030026 SJR .BYTE "RIGHT ",EOS 030040 SJNONE .BYTE " ",EOS 031000 ; ----- Variables ----- 031005 IDIR .BYTE 0 050000 ; ----- Function Includes ----- 050010 .INCLUDE #D2:A8FUNCS.LIB 064000 ; ---------- E N D ---------- 064001 .END
Breakdown
Since the program is fundamentally the same as the console key program and the code is documented fairly well, I will just document the decision tree.
- 20: Program loading address
- 200-416: Setup the screen
- 510: Start of the read loop
- 522: Load the accumulator with the value in joystick 1 trigger register (STRIG0)
- 524: Compare the accumulator with the value 0 (0 means the button was pushed)
- 526: If the comparison was equal, branch to location RJFIRE (fire button handler)
- 532: Load the accumulator with the value in joystick 1 register (STICK0)
- 534: Store the accumulator in location IDIR. The accumulator will change before we have a chance to check it. This is the direction the joystick was pushed.
- 536: Compare the accumulator with the value JOYNO or 15 (15 means the joystick has not been moved)
- 538: If the comparison was not equal, branch to location JMOVED (joystick has been moved)
- 552: Go to start of read loop to check again
- 1010: Start of fire button handler (RJFIRE)
- 1020: Call the clear text subroutine
- 1022-1026: Print FIRE
- 1028: Goto location APPDON which is the exit routine
- 1110: Start of the Joystick Moved routine (JMOVED)
- 1114: Call the clear text subroutine
- 1122: Load the accumulator with the value in location IDIR (the direction stored after reading earlier)
The next section is a direction handler. It is essentially the same for each direction so I will only document the first:
- 1210: Start of the UP handler (RJU)
- 1212: Compare the accumulator with JOYU or 14 (14 means up was pushed)
- 1214: If the comparison is not equal, branch to the next direction handler (RJD which is down)
- 1222-1226: Print the direction (UP)
- 1232: Go to start of read loop to check again
The rest of the program:
- 2010: Start of the read loop end
- 2012: Goto the start of the read loop to check again
- 2100-2130: End of program routine. Turn cursor back on and exit.
- 2500-2540: Clear display text subroutine
- 30000-30040: String data
- 31000-31005: Variable storage
Results
Waiting for input:
Joystick pushed UP:
Joystick pushed diagonally DOWN and LEFT:
Fire button pressed:
Files:
The source code is again around 5K in size, but assembles down to just 521 bytes.