mageco joystick interface information?

If you want to ask questions about how the machine works, peculiar details, the differences between models, here it is !
How to program the oric hardware (VIA, FDC, ...) is also welcome.
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Post by waskol »

Well, I did not managed to use the supposed code for the PASE or ALTAI Joystick interface with my joystick, I speek about the codes presented on Muso's Oric site, BUT :wink:

We have, Oricians, the chance to have the scans of a fabulous book you can download here for example :
http://www.abandonware-france.org/ltf_m ... el=497#497

This book is "au coeur de l'Oric Atmos" and is a "Must Have" (sorry, it is in french).

And starting Page 40, there is a bunch of explanation about how to manage joysticks interface, I typed in the recommended BASIC program (there is also an assembler version) :

Code: Select all

10 REM Main Program
20 POKE 618,2
30 REPEAT
40 GOSUB 1000
50 PRINT LEFTJOY,RIGHTJOY
60 UNTIL KEY$<>""
70 POKE 618,3
80 END
90 REM
1000 REM Sub Program --> Read Joysticks
1010 POKE 782,64
1020 V1=PEEK(771):V2=PEEK(769)
1030 POKE 771,192
1040 POKE 769,128:LEFTJOY=PEEK(769)-128
1050 POKE 769,64:RIGHTJOY=PEEK(769)-64
1060 POKE 771,V1:POKE 769,V2
1070 POKE 782,192
1080 RETURN
The author gives also a faster code in BASIC, loading a machine code routine and explains everything really well.

and as you say... Top Banana !!! :P

If you want to play to some games like XENON1, ZORGON'S REVENGE, LIGHT CYCLES, DRACULA'S REVENGE, ORIC MUNCH, etc... with joysticks, there are some programs you can download from www.Oric.org that Micropuce released :
- Joystick interface 1
- Joystick Interface 2

I think you can handle your joysticks now , enjoy !!!!
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Post by waskol »

Back to PASE joysticks.

Concerning the assembly program in "Au coeur de l'Oric Atmos" that permit to handle PASE joysticks, there is a slight mistype (I put the corrected version here) :

Code: Select all

10 PRINT "Loading machine code"
100 ' Read Joystick MC routine
110 POKE 618,2
120 GOSUB 1000
130 REPEAT
140 CALL#404
145 PRINT "Values : ";
150 FOR I=#400 TO #403
160 PRINT PEEK(I);" ";
170 NEXT I
180 PRINT
190 UNTIL KEY$<>""
200 POKE 618,3
210 END
1000 REM Poke machine code
1010 A=#400:READ COD$
1020 REPEAT
1030 FOR I=1 TO LEN(COD$) STEP 2
1040 B=VAL("#"+MID$(COD$,I,2))
1050 POKE A,B
1060 A=A+1
1070 NEXT I
1080 READ COD$
1090 UNTIL COD$="END"
1095 RETURN
1100 DATA 000000004898488A48AD0103
1110 DATA 48AD030348A9C08D0303A940
1120 DATA 203C048D00048E0104A98020
1130 DATA 3C048D02048E0304688D0303
1140 DATA 688D010368AA68A86860EAEA
1150 DATA 8D0103AD0103A82920AA984A
1160 DATA 290C8D520498290318690CA8 
1170 DATA B9600460EAEAEAEAEAEAEAEA
1180 DATA 000000000002080100040605
1190 DATA 00030709,END
Thus, the bug in the book was at the end of the line 1160 : instead of ...86900A8 in the book listing, and according to to the dissassembly listing that follow, we should read 8690CA8

This code was tested on real ATMOS and works perfect.


Now, for those interested in using PASE joystick interfaces with the OSDK, in C, here is a little dirty code :oops:

Code: Select all

#include <lib.h>

//procedure that read joystick status
void readjoy(int *ljoy,int *rjoy)
{
int V1,V2;
//Read Joysticks
poke(782,64);
V1=peek(771);
V2=peek(769);
poke(771,192);
poke(769,128);
*ljoy=peek(769)-128;
poke(769,64);
*rjoy=peek(769)-64;
poke(771,V1);
poke(769,V2);
poke(782,192);
}

void main()
{
  char left_joy,right_joy;
  //initialization of the printer port
  poke(618,2);
  cls();
  while (key()!=32) {
     //We read Joystick ports
     readjoy(&left_joy,&right_joy);
     //We print the values
     printf("%d  %d\n",left_joy,right_joy);     
  }
  //"release" of the printer port
  poke(618,3);
}
I have tried to do a mix of C and assembly code, but I did not succeed (I am not good enough into this kind of exercice).

Well, I started from the disassembly of the BASIC code presented above :

Code: Select all

(#0400 to #0403 are used to hold returned value)
0404:48	      PHA
0405:98       TYA
0406:48       PHA
0407:8A       TXA
0408:48       PHA
0409:AD 01 03 LDA $0301
040C:48       PHA
040D:AD 03 03 LDA $0303
0410:48       PHA
0411:A9 C0    LDA #$C0
0413:8D 03 03 STA $0303
0416:A9 40    LDA #$40
0418:20 3C 04 JSR $043C 
041B:8D 00 04 STA $0400
041E:8E 01 04 STX $0401
0421:A9 80    LDA #$80
0423:20 3C 04 JSR $043C
0426:8D 02 04 STA $0402
0429:8E 03 04 STX $0403
042C:68	      PLA
042D:8D 03 03 STA $0303
0430:68       PLA
0431:8D 01 03 STA $0301 
0434:68       PLA
0435:AA       TAX
0436:68       PLA
0437:A8       TAY
0438:68       PLA
0439:60       RTS
043A:EA       NOP
043B:EA       NOP
043C:8D 01 03 STA $0301
043F:AD 01 03 LDA $0301
0442:A8       TAY
0443:29 20    AND #$20
0445:AA       TAX 
0446:98       TYA
0447:4A       LSR A
0448:29 0C    AND #$0C
044A:8D 52 04 STA $0452
044D:98       TYA
044E:29 03    AND #$03
0450:18       CLC
0451:69 0C    ADC #$0C
0453:A8       TAY
0454:B9 60 04 LDA $0460
0457:60       RTS

0460:00 00 00 00 00 02 08 01
0468:00 04 06 05 00 03 07 09
Then I wrote this in C :

Code: Select all

#include <lib.h>

void readjoy(char *ljoy_dir,char *ljoy_fire,char *rjoy_dir,char *rjoy_fire)

void main()
{
  char ljoy_dir,ljoy_fire,rjoy_dir,rjoy_fire;

  poke(618,2);
  cls();
  while (1) {
     readjoy(&ljoy_dir,&ljoy_fire,&rjoy_dir,&rjoy_fire);
     printf("%d  %d  %d  %d\n",ljoy_dir,ljoy_fire,rjoy_dir,rjoy_fire);     
  }
  poke(618,3);
}
And wrot this little dirty asm code :

Code: Select all

_readjoy
pha
tya
pha
txa
pha
lda $0301
pha
lda $0303
pha
lda #$C0
sta $0303
lda #$40
jsr get_joystick_status
sta $0400                   ; <--first return value
stx $0401                   ; <--2nd return value
lda #$80
jsr get_joystick_status
sta $0402                   ; <--3rd return value
stx $0403                   ; <--4th return value
pla
sta $0303
pla
sta $0301 
pla
tax
pla
tay
pla
rts

get_joystick_status
sta $0301
lda $0301
tay
and #$20
tax 
tya
lsr A
and #$0C
sta $0452
tya
and #$03
clc
ADC #$0C
tay
lda joystat,y
rts

joystat
    .byt $00 $00 $00 $00 $00 $02 $08 $01 $00 $04 $06 $05 $00 $03 $07 $09
I know that I have to use the stack pile in order to retrieve my parameters address passed in my function, I understood that more or less
But I have no idea about how to use all of this in the assembly code.

If someone want to complete this asm code, you are welcome :wink:
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Post by Chema »

Greetings

I am not sure if I understood... You want that asm function to be called from C, filling the contents of those four pointers with the values that are currently being written to $400-$403?

That is quite simple. First, forget about using $400-$403 directly (even if this can be good for optimizing, but let's ignore them for now).

Params in C are allways 2 byte values, and can be accessed using
lda (sp),y with y being 0 for the first param, first byte, 1 for first param, second byte, 2 for second param first byte, and so on...

The return value of the function is coded in regs A and X (also 2 byte values).

So in your example, I think you can do something like:

Code: Select all

    ldy #0
    lda (sp),y
    sta addr1+1
    iny
    lda (sp),y
    sta addr1+2
    ...
    lda rtr1 ; First byte to return
addr1
    sta $dead ; This is self-modifying code
    
    iny
    lda (sp),y
    sta addr2+1
    iny
    lda (sp),y
    sta addr2+2
    ...
    lda rtr2 ; Second byte to return
addr2
    sta $dead ; This is self-modifying code
    
and so on.

Of course this is not the best way to do this, but serves as an example of how this is managed.

I would go for a much simpler version. I am not sure about the meaning of the values, but surely can be coded inside a byte, for example using bit 7 for indicating if fire is pressed or not and coding the status on the other bits. Maybe even splitting in reading each joystic separately.

This way you can return the value in reg X and forget about passing parameters...

Also it is sometimes faster to use self-modifying code to store the registers instead of pushing them into the stack. Moreover I doubt you *really* want to preserve them inside the function.

Just my two cents... If you need anything else, just let me know.

Cheers.
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

I add, that using page 4 is a very bad idea, this basically guarantee that the DOS will not work anymore.
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Post by waskol »

well I think that with all those explanations I understood a lot of things, I will try this :P

In fact, it is exactly what I needed to know :wink:
Post Reply