11 November 2014, 16:22 | #1 |
Posts: n/a
|
Joystick reading code
After ripping some code from a Devpac2 programming tutorial by Bullfrog, printed in Amiga Format at the end of '92/beginning of '93 and studying it I have some questions.
Mind you: i'm just starting out to understand 68k assembly on the Amiga. Here's the code: Code:
; Translate joystick into delta values _dx_joy ds.w 1 ; delta x value ; -1 for move LEFT, ; 1 for move RIGHT, _dy_joy ds.w 1 ; delta y value ; -1 for move UP, ; 1 for move DOWN _fire1 ds.w 1 ; firebutton 1 value ; 0 = not pressed ; 1 = pressed _fire2 ds.w 1 ; firebutton 2 value ; 0 = not pressed ; 1 = pressed _joy_tableX dc.w 0, 0, 1, 1, 0, 0, 0, 1,-1, 0, 0, 0,-1,-1 _joy_tableY dc.w 0, 1, 1, 0,-1, 0, 0,-1,-1, 0, 0, 0, 0, 1 joystick_test: move.l d0,-(sp) ; save d0 to stack move.w $dff00c,d0 ; put JOY1DAT value into d0 ; Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 = HI byte ; X7 X6 X5 X4 X3 X2 X1 X0 = LO byte and.w #$0303,d0 ; 0 0 0 0 0 0 1 1 ; only work with Y1, Y0, X1, X0 ; so clear bits Y7-Y2, X7-X2 bclr #8,d0 ; clear Y0 beq.s .zero1 ; if Y0 = 0 goto .zero1 ??? bset #2,d0 ; set X2 to 1 ??? .zero1: bclr #9,d0 ; clear Y1 beq.s .zero2 ; if Y1 = 0 goto .zero2 ??? bset #3,d0 ; set X3 to 1 ??? .zero2: add.w d0,d0 ; multiple d0 by 2 move.w _joy_tableX(PC,d0.w),_dx_joy ; lookup and set _dx_joy move.w _joy_tableY(PC,d0.w),_dy_joy ; lookup and set _dy_joy .fire1_test: btst.b #7,$bfe0ff ; check if firebutton 1 is pressed bne.s .no_fire1 ; not pressed add.w #1,_fire1 ; pressed ! bra.s .fire2_test .no_fire1: move.w #0,_fire1 .fire2_test: move.w #$c000,$dff034 ; set POTGO to correct status move.w $dff016,d0 ; put POTINP value into d0 btst.l #14,d0 ; check DATRY in POTINP bne.s .no_fire2 ; not pressed add.w #1,_fire2 ; pressed ! bra.s .fire2_done .no_fire2: move.w #0,_fire2 .fire2_done: move.w #$000,$dff034 ; set POTGO to correct status cmp.w #255,_fire1 ; check if fire1 is released ? blt.s .end move.w #255,_fire1 .end move.l (sp)+,d0 ; restore previous value of d0 Code:
bclr #8,d0 ; clear Y0 beq.s .zero1 ; if Y0 = 0 goto .zero1 ??? bset #2,d0 ; set X2 to 1 ??? .zero1: - Will this code ever reach the bset #2,d0 ? And why set bit 2 (X2) at all if only Y1,Y0,X1 and X0 are important? Code:
add.w d0,d0 ; multiple d0 by 2 Code:
move.w _joy_tableX(PC,d0.w),_dx_joy ; lookup and set _dx_joy move.w _joy_tableY(PC,d0.w),_dy_joy ; lookup and set _dy_joy Code:
btst.b #7,$bfe0ff ; check if firebutton 1 is pressed Code:
cmp.w #255,_fire1 ; check if fire1 is released ? blt.s .end move.w #255,_fire1 Is this a 'rogue' value? Or does it indeed mean the fire1 button was released? - Isn't this whole piece of code a bit overengineered/overkill? Can it be done much simpler? Last edited by borchen; 11 November 2014 at 22:12. |
11 November 2014, 19:49 | #2 | |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Quote:
Code:
ciaa_pra = $bfe001 joy1dat = $dff00c potgor = $dff016 bit_joyb1 = 7 bit_joyb2 = 14 ReadJoystick btst #bit_joyb2 & 7, potgor seq d0 add.w d0, d0 btst #bit_joyb1, ciaa_pra seq d0 add.w d0, d0 move.w joy1dat, d1 ror.b #2, d1 lsr.w #6, d1 and.w #%1111, d1 move.b (.conv, pc, d1.w), d0 rts .conv dc.b 0, 5, 4, 3, 1, 0, 3, 2, 8, 7, 0, 1, 7, 6, 5, 0 |
|
11 November 2014, 20:17 | #3 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,519
|
For some reason original "official" CIA addresses changed from $BFExFF and $BFDxFE to $BFEx00 and $BFDx01 (Both "old" and "new" map to same registers, CIA address bits 1 to 11 are no-care).
(or it is a typo. But CIA addresses did change, for example very first HRM CIA chapter has "old" addresses) Last edited by Toni Wilen; 12 November 2014 at 07:51. Reason: Bits 1 to 11, not 1 to 7. |
11 November 2014, 22:32 | #4 |
Posts: n/a
|
Wow...talk about fast response...great!
@Leffman (with double n) Thanks for the code, it's certainly a lot shorter, but i'm just trying to understand what the Bullfrog code does. I see you also use "add.w d0,d0"; is this line neccesary to move/shift some bits to the left? If yes; is add.w faster than lsl.w #1,d0 ? @Toni (with single n) $bfe0ff is not a typo, because the complete program, of which the joystick code is just a small part, compiles/assembles&runs fine. A lot of the code in the tutorial is from a 'framework' Bullfrog used for several games, so some parts could be very old indeed. B.T.W. I think I know what Code:
bclr #8,d0 ; clear Y0 beq.s .zero1 ; if Y0 = 0 goto .zero1 ??? bset #2,d0 ; set X2 to 1 ??? .zero1: If bit 8 already was 0, the code jumps to .zero1, else bit 2 is set to 1 in d0. Pfff...what a lot of text for this short piece of code. Last edited by borchen; 11 November 2014 at 22:43. |
11 November 2014, 22:37 | #5 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
|
12 November 2014, 04:04 | #6 | |||
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
Quote:
Code:
move.w _joy_tableX(PC,d0.w),_dx_joy move.w (_joy_tableX,PC,d0.w),_dx_joy ; new style (68020+) syntax move.w (_joy_tableX+PC+d0.w),_dx_joy ; not accepted by assemblers Quote:
Code:
tst.b $bfe0ff ; check if firebutton 1 is pressed bmi.s .nofire1 BCLR tests the bit before changing it. Most 68k instructions set the condition codes (CC) to reflect the data after the operation instead of before. Yes, it's sometimes useful to know what that bit was before changing it rather than after. BCLR is not avoiding clearing the bit if it's already zero. |
|||
12 November 2014, 11:10 | #7 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
|
Quote:
Quote:
But what about 8?? |
||
12 November 2014, 11:24 | #8 | ||
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,154
|
Quote:
Quote:
|
||
12 November 2014, 12:25 | #9 | ||
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Quote:
Quote:
0, 5, 4, 3, 1, 0, 0, 2, 8, 0, 0, 0, 7, 6, 0, 0 I think two lookup-tables for X-direction and Y-direction may be more handy actually. |
||
12 November 2014, 21:51 | #10 | |||
Posts: n/a
|
Thanks for the responses, it's much appreciated.
@matthey Quote:
I already understood that d0 is basically an index into _joy_tableX. Quote:
@robinsonb5 Quote:
Strangely the following code: Code:
cmp.w #255,_fire2 blt.s .end move.w #255,_fire2 @all If someone is interested in the complete tutorial I could upload a directory with all the code, which you can easily use as HD in Winuae, to the Zone. You'll have to lookup the right pages in AmigaFormat yourself on this website http://amr.abime.net/issues_4 The tutorial runs from October '92 to Februari '93. Last edited by borchen; 12 November 2014 at 22:04. |
|||
13 November 2014, 00:00 | #11 | ||
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
Quote:
http://en.wikipedia.org/wiki/Two%27s_complement The most significant bit of a two's complement signed number gives the sign of the number (0=pos 1=neg). The most significant bit of a byte is bit #7 using Motorola's bit counting system (least to most significant). A test of a byte sets the CCR[N] flag if bit #7 is negative (or minus). BMI (branch minus) branches if the CCR[N] bit is set because the tested byte is negative. It's not quite as simple as BTST but a trained eye will spot bit #7, bit #15 and bit #31 knowing that they are sign bits to a byte, word and longword . There are some other optimizations that could be made by the way. Instructions like MOVE.W #0,EA could be CLR.W EA and ADD.W #1,EA could be ADDQ.W #1,EA. I didn't mention them because an optimizing assembler will usually take care of them and that is how some programmers prefer to write code (although the MOVE #0,EA->CLR EA may be disabled for the 68000 because of a bug that could cause problems with hardware registers). Last edited by matthey; 13 November 2014 at 00:23. |
||
14 November 2014, 20:59 | #12 |
Posts: n/a
|
@matthey
Thanks a lot for your explanation of the relative addressing. I realise that I still have a lot to learn. My way of learning assembly is to just take/rip/steal a piece of code and start explaining it to myself using info from the web and then comment almost every line of code. B.T.W. I got a great intro into Amiga assembly by watching the following tutorial on youtube: [ Show youtube player ] In the late 80's I did have an assembler for my A500, but no clue whatsoever to do with it, due to a lack of access to information. All the people that I knew with an Amiga mostly played games, painted with Deluxepaint or were using Soundtracker, although one was using Wordperfect, because at that moment in time it was superior to the PC version. |
15 November 2014, 19:06 | #13 | |||
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
There are several areas that need to be learned to understand assembly language.
1) CPU design and data types 2) ISA, ABI+API (OS), hardware register maps (hw banging) 3) assembler, linker, editor, debugger usage Many programmers already know #1 when they start which is a big help. Much of this information can be found online as it's mostly generic and widespread in usage but it's important to know. From above, #2 is the syntax, instructions and usage of #1 and is specific to a particular hardware and software (68k and Amiga in this case). The ISA (Instruction Set Architecture) is described in the 68000PRM originally from Motorola (now Freescale). http://cache.freescale.com/files/arc...n&fileExt=.pdf It's in this documentation that the addressing modes are explained like PC relative addressing. There are also user manuals for each CPU which give more specific information including timings but these manuals are for experienced programmers who understand the ISA, CPU design and datatypes. The 68k ABI (Application Binary Interface) is SysV.4 but not well published. I don't have any documentation besides the manuals of compilers and assemblers. It describes how parameters are passed in functions (stack) and how they are returned (D0), which registers are scratch (D0,D1,A0,A1), use A7=stack etc. Amiga functions pass values in registers defined in their own API (Application Programming Interface) but do scratch the same registers and return values in D0 while needing other details as described in the HKRM reference manuals of which there are 4 or 5. The HKRM Hardware reference manual describes the hardware registers and how they can be used while the others describe the AmigaOS APIs. They are out of print but can be found online. From above, #3 is in the documentation for each developer tool used. They are usually technical as knowledge from #1 and #2 are needed but the best manuals will explain some aspects of them and give examples. Quote:
http://aminet.net/dev/asm/BarflyDisk2_00.lha There is a learning curve to a debugger but it's worth learning early as a lot can be learned by simply stepping through programs. Amiga hardware/register hitting programs are generally not good candidates for debugging though. It's better to step through a simple string function, sort, or number converter for example. Quote:
Quote:
|
|||
15 November 2014, 19:33 | #14 | |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,767
|
Quote:
|
|
15 November 2014, 22:01 | #15 | |
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
assembler: vasm linker: vlink editor: CED with AREXX debugger: BDebug (from Barfly package) I wouldn't be able to use vasm on a low spec Amiga. It's not the easiest setup to start with but I doubt any integrated environment can match it. Last edited by matthey; 16 November 2014 at 01:42. |
|
15 November 2014, 22:44 | #16 |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,767
|
That's why I use Barfly with FrexxEd and a self written real time memory viewer. Much more powerful than those integrated environments, but not so nice for beginners. Beginners should really stick with AsmOne, AsmPro or DevPac.
|
16 November 2014, 02:02 | #17 | |||
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
|
I'm a bit late to the thread, so sorry if some of this has already been answered.
Quote:
Quote:
Quote:
I put useful snippets on coppershade.org: here is an old snippet, #ChkJoy, that I used in my as yet unreleased collection of not-quite-finished games that reads both joysticks and gives the values in a useful form. |
|||
16 November 2014, 13:17 | #18 | |||
Posts: n/a
|
@Photon
You're probably Photon "Hello amiga coders" from Scoopex? Quote:
I also consult this site http://mrjester.hapisan.com/04_MC68/ alot, because this guy explains stuff clearly with a lot of examples, although his explanation of the bclr did not mention the bit-testing part of this command...bummer Quote:
B.T.W. the skeleton of my code I took from your Amiga Hardware Programming tutorial on Youtube. I inserted this joystick reading code into it. @matthey Thanks for the tip about Barfly, but I'll stick with ASMone for now. When I followed the tutorial of Bullfrog I used the Devpac installation that came with it. I do not feel like switching to yet another development-tool. Quote:
Now I want to discover why the Amiga was so great in the late 80's. @Thorham Dus ik ben niet de enige computer-nerd, die zit te pielen met 68k assembly voor de Amiga. Google translation: "So I 'm not the only computer nerd, who sits fiddle with 68k assembly for the Amiga." "...sits fiddle..." @all When I use Code:
move.w _joy_tableX(PC,d0.w),_dx_joy ; lookup and set _dx_joy Probably because the table _joy_tableX is too far away from the move.w command. So I replaced this line with: Code:
lea _joy_tableX,a0 move.w (a0,d0),_dx_joy I still have one question about the index-value d0: Right before the lookup-code I write this value into a variable called _joyIndex to check it's value and apparently d0 has the following values: $0018 for LEFT, $0006 for RIGHT, $0008 for UP and $0002 for DOWN. _joy_tableX: 0, 0, 1, 1, 0, 0, 0, 1,-1, 0, 0, 0,-1,-1 _joy_tableY: 0, 1, 1, 0,-1, 0, 0,-1,-1, 0, 0, 0, 0, 1 How can it find the value -1 for _dx_joy with index-value $0018 ? Which -1 does it find, because there are only 14 entries in the table. Or must $0018 be divided by 2, because the 9th entry in the table is -1? B.T.W. I use this http://www.sinchai.de/index.php?main...11b4f2e614eb9c interface in combination with my (t)rusty old Wico http://www.ntrautanen.fi/computers/o...mages/wico.jpg ,which is probably even older than the joystick-reading-code from Bullfrog, because I already used this joystick with my CPC464. Last edited by borchen; 16 November 2014 at 13:59. |
|||
16 November 2014, 13:56 | #19 | |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,767
|
Quote:
Google translation: No, you are most certainly not. |
|
16 November 2014, 14:18 | #20 | |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,154
|
Quote:
(If you wanted to declare a table with single-byte entries, you'd use dc.b, and dc.l if you wanted longword entries.) |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Quickshot Python: crap joystick or crappest joystick ever? | T_hairy_bootson | Nostalgia & memories | 141 | 13 September 2016 15:36 |
Reading Memory | you8mysandwich | support.WinUAE | 10 | 26 January 2011 12:00 |
Reading PC discs | Unregistered | support.Hardware | 12 | 01 September 2004 11:00 |
Reading CD-RW Media | @UAE | support.Apps | 4 | 14 December 2002 11:44 |
3D code and/or internet code for Blitz Basic 2.1 | EdzUp | Retrogaming General Discussion | 0 | 10 February 2002 11:40 |
|
|