Jump to content
IGNORED

Joystick read via TOS function


Recommended Posts

This is something what is actually very simple, but is used in few games. And the reason is poor Atari documentation. Just did not give enough details about how to use.

 

First step is to set joystick vector via XBIOS call 34 :

 

* Setting joystick monitoring rutine :

   move.w  #34,-(sp)   *Kbdvbase
   trap    #14
   addq.l    #2,sp    
 
   move.l  d0,a1
   lea 24(a1),a1   * Joystick vector here
   move.l  (a1),joymorg  *Save original one (which is just an rts)
   move.l  #moni,(a1)
.......

 

Monitoring rutine self:

 

moni     * Joystick monitoring, very simple:
  * it is at joyvec address set with   XBIOS 34

    addq.l  #1,a0   *a0 is odd
    move.w  (a0),joyc    * first byte is for joy 0, second for joy 1
    rts   


joyc  ds.w   1

 

Bit 7 is fire button

Bit 0 up

Bit 1 down

Bit 2 left

Bit 3 right

 

 

 

 

  • Like 1
Link to comment
Share on other sites

Either the language provide bindings (e.g. GFA Basic has such bindings to read joystick)

 

either you should get the handler as a binary blob (assembly routine compiled in position independant code, if I am correct ?) then :

 

* Call xbios 34, save the original vector (pointer) at result+24

* Load routine as binary blob, put address of routine at result+24, the routine should put read values into routine+offset (offset depends of routine)

* now in your game loop, poll routine+offset

Link to comment
Share on other sites

18 hours ago, zzip said:

What if you aren't coding in assembly, and the language doesn't allow in-line assembly?

That's good question. Easiest answer is: avoid such what allows not in-line assembly ?

 

I guess that doing XBIOS 34 call and set new vector value is not problem in C, GFA ...

That short code what getting address in a0 is what is not supported - and as Sporny Kun said should use it as binary code.

And yes, it needs then to be PC relative (relocation will not work), so:

 

moni

    addq.l  #1,a0   *a0 is odd

    move.l  a1,-(sp)

    lea joyc(pc),a1
    move.w  (a0),(a1)   * first byte is for joy 0, second for joy 1

    move.l  (sp)+,a1
    rts   

 

joyc  dc.b  0,0   * Output for 2 joysticks

 

And here can see well how longer and slower code is needed in some high level language than in ASM. For same thing.

 

Now, some longer text about why, how ....

Unlike it is by 8-bitters  input (and it is keyboard, mouse, ST joysticks) is handled not by periodical read of port state, but with interrupt based system.

When some key is pressed, interrupt is generated and scan code (always in range 0-127) is sent via ACIA. When is released same code with bit 7 set is sent - as release signal.

In case of joystick state is sent: when something is pressed, and when something is released - so SW always can see complete state.

And it is good, because reading all it like in every V-blank would eat too much CPU time.  So, there is IKBD chip, what is micro controller, and communicates via ACIA chip. When byte from IKBD is sent ACIA interrupt will be generated, and then CPU code will read that byte, and perform necessary steps. I will not go here in details - there are DOCs about it. For instance in Atari ST ProfiBuch it is described in details - not code in TOS, but IKBD chip commands, packet header codes, protocol, IKBD modes ...

And this part of code in TOS is written in ASM - with good reason - less wasted time during interrupts  - and there is lot of them when user drags the mouse.

And I think that it might be the reason why this is missing in Atari DOCs - who cares about stupid ASM coders ? ? 

Well, sarcasm, but we know that C coders don't appreciate much ASM coders - not now, not in past. Maybe instead it should cooperate better.

 

For the end: this way simply offers that use this short moni code not for only transferring, but for giving signal to running program that some input action just happened. Like fire button pressed in game. That will result in faster response like in case of usual periodical state check - like main loop of program reaches input check periodically.  Of course depends from how frequently joystick state is checked, how big improvement it can give.

Yeah, I saw really a lot of games with slow command response.

Link to comment
Share on other sites

6 hours ago, ParanoidLittleMan said:

I guess that doing XBIOS 34 call and set new vector value is not problem in C, GFA ...

That short code what getting address in a0 is what is not supported - and as Sporny Kun said should use it as binary code.

I was coding in GFA v2.0  and assembly, but I wasn't ready to write a complete game in Assembly, so I was looking for a way to read the ports from GFA-   and there must be a way to make it work, seeing how many games were written in GFA!   But I couldn't figure it out from the docs I had at the time.

Link to comment
Share on other sites

I'm not sure that GFA used this way. I made only 1 program in GFA Basic, and it did not use joystick. And there was some inline ASM too.

So, I think that you have it all now.

Would be good to write me some examples - games written in GFA Basic, using joystick, so I can look how it is exactly solved.

Usual way is btw:  reading joystick state at higher located system variables (that's how STOS does it) - but those variables are on different address in every TOS version.

Or there can be custom code for joystick read, not using TOS at all. And GFA program just calls it.

Link to comment
Share on other sites

  • 2 weeks later...

To not start new thread about input read via TOS functions, I will continue here, with reading mouse:

 

Man would expect that same as with joystick read can be done with mouse state and position read. But not, changing mouse vector using XBIOS 34 will give not address where x and y coordinates are. But they are there, in low RAM, only that address is different in diverse TOS versions. Especially in beginning, programmers used that  of course then mouse worked not in higher TOS versions. Example: Arkanoid - only TOS 1.00 and 1.02 .

I fixed that game some 10 years ago, using basically disassembled code from TOS for mouse (and keyboard) read. And then it is actually done via not using TOS function in active TOS, but using code in RAM, even if it is same, except addresses, of course. Btw. just discovered that STOS did same thing with mouse read.

I will put that code with comments here, in some later post. Now let's try to read mouse via TOS functions, as title says.

And it is possible with AES call (trap #2, d0=200).  How it is done can see when DL sources of my: Mouse and joystick tester . Page is:

http://atari.8bitchip.info/astopensw.php

 

It is possible with VDI function too, but it is little more complicated. I spent yesterday some time trying to make VDI 124 work - Sample mouse button state - which reads mouse coordinates too. And it failed. Some search, looking newer edition of Atari ST ProfiBuch - and yes, there is more info:  that function works not when AES is started, because then AES takes over screen, and then need to use AES calls - and yes, that's what lot of games do.  And I must say that I don't like it. Most of such games could work from AUTO folder - so more free RAM, and only because few AES calls it must be started from Desktop - ergo, some 40 KB RAM less, and poor user needs to bother with starting ?

 

So, let use AUTO run, and as I write this because new game Wrecking Ball by Sporny Kun, and it works from AUTO run too well, let see what can do with VDI 124 in such case.

 

First problem is that mouse is not initialized. There is solution for that, will come back on it ...  I tried my code from AUTO run, and it worked, can read fine mouse position. And button too (why only 1 ?) .

 

* Mouse read via VDI call
* AUTO start 

*  VDI init :

begin


* Init mouse  - only UK TOS 1.04 !

	pea	$FD09A0
	pea	$FD0F08  *Params for relative mode
	move.w	#1,-(a7)   * Cursor on, relative mode
* but shows not, likely missing something from AES...
	clr.w	-(a7)
	trap	#14
	lea	$C(a7),a7



* Fill in params for VDI 1 call :  
	lea	vcontr,a2   
	lea	vdi_wi,a1
	moveq	#5,d2
.vi	move.w	(a1)+,(a2)+
	dbf	d2,.vi


* Intins too :
	lea	vdi_inti,a0
	move.l	a0,pintv

	lea	VDIPB,a0
	move.l	a0,d1

	moveq	#115,d0
	trap	#2



* Prepare VDI 124 :

prepmoc 

	lea	vcontr,a2   
	lea	mousst,a1
	moveq	#5,d2
.vi	move.w	(a1)+,(a2)+
	dbf	d2,.vi
	   


seemou
  	lea	VDIPB(pc),a0
	move.l	a0,d1

	moveq	#115,d0
	trap	#2

     nop
      nop

    bra.s  seemou
******



mousst dc.w  124,0,1,0,1,0


vdi_wi	dc.w	1, 0, 6, 11, 45, 0
vdi_inti	dc.w	0,1,1,1,1,1,1,1,4,2,2   * 11 integers


VDIPB dc.l vcontr
pintv dc.l 0
ptsin dc.l vdi_inti
vioadr dc.l vintout
vptsadr dc.l  vptsout


   section bss  

vcontr ds.w 12
vintout ds.w 50
vptsout ds.w 12

Button status is at intout, coordinates at ptsout (2 words) .  Need some + work about mouse initialization. What is here is actually taken from my TOS 1.04 in RAM, used with hard disk adaptations.

In concrete game or SW using mouse just need to perform VDI 124 call periodically to get actual mouse pos. 

And once more: code above works not after Desktop start, it will actually crash because VDI 1. Only AUTO run, or boot from disk.

 

To be continued ...

 

Link to comment
Share on other sites

  • 3 weeks later...

Of course, mikro found another reason to write something bad about me or my writing. That description is not about same thing. I know much more about how to programm those IKBD chip modes than in linked article.  And everyone can see it in Atari ProfiBuch - much more details in it.  My goal was not to repeat what is in ProfiBuch, and maybe in some other sources (online). I wrote about what is missing from Atari ST related DOCs - including diverse Atari guides and ProfiBuch, Atari Compendium.

In other words - mikro is pathological hater.

Link to comment
Share on other sites

  • 4 months later...
On 9/29/2020 at 12:44 PM, Cyprian said:

nice,

it would allow to write a driver and use  Extended Joystick as a normal one

 

Anything to get the Enhanced Joystick Ports used more often. Whether it's to use the ST Power Pads/JagPads in the vast majority of games or for encouraging someone to build some adapter for PC GamePort/Atari 5200 controllers [don't knock the 5200; its CX53 Trak-Ball Controller* is dope] to be used would also be great. 

 

Cyrano Jones over in the Atari Jaguar threads may have useful info since he's ported a lot of ST games to run on the Jag and use the JagPads via its Enhanced Joystick Ports... including Gauntlet II and using the Jaguar Team Tap. If that functionality was reversed, then ST owners could play that game without needing to use a Parallel Port/Dual DB9 Cable Adapter to play that - or say Leatherneck - with 4 players. 

 

 

*In a better timeline, its creator, Dan Kramer, would've been compelled to remain at Atari Corp and create better ST Mice and Trak-Balls. In our timeline, he left after working on the SECAM XL computers. 

Link to comment
Share on other sites

  • 10 months later...
On 9/29/2020 at 4:50 PM, ParanoidLittleMan said:

This is something what is actually very simple, but is used in few games. And the reason is poor Atari documentation. Just did not give enough details about how to use.

 

 

Hi,

working on the TT I have some problems with the Joystick.

If I am in mode $14 (bconout(4,$14)) for joystick reporting, then the paquets look this way:

FF J0 J1 : FF means that joystick 1 has changed, but the byte for joystick zero is also sent.

FE J0 J1 : FE means joystick 0 has changed, but the byte for joystick 1 is also sent.

Always three bytes for those paquets.

 

In this mode, the mouse is not active !

If I go back to mouse (bconout(4,8)), then when receiving paquets for the joystick, the fire button is never reported. Only the four directions.

 

So I can't monitor one joystick and keep the mouse active.

Is it specific to the TT ?

 

Guillaume.

Link to comment
Share on other sites

5 hours ago, moulinaie said:

Hi,

So I can't monitor one joystick and keep the mouse active.

Is it specific to the TT ?

 

Guillaume.

Bonjour Guillaume (even if it's for myself, let's keep a certain quality in the language),

 

I solved the problem when I saw that in the mouse mode, the fire button of Joystick 1 sets the mouse right button!

So I added a vector on the mouse routine to detect the right button and set accordingly the bit in my joystick information.

 

So I can have two joysticks, or one joystick+mouse with full button detection

 

Guillaume.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...