JOY81 - Programmable Joystick Interface for ZX81

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
User avatar
msch
Site Admin
Posts: 106
Joined: Sun May 19, 2013 11:39 pm
Location: Frankfurt/M, Germany

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by msch »

Finally I got my two Interfaces today - faster as expected.
And - oh miracle - I did not had to pay customs :-)
Thank you kmurta!
Mathias

ZX-Team member and classic computer collector
User avatar
kmurta
Posts: 302
Joined: Tue Sep 01, 2009 5:04 am
Location: Belo Horizonte - BR
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by kmurta »

siggi wrote: Kelly: which ports are written (using OUT) by the SETJOY program?
The JOY81 RAM is accessed through the OUT instruction, so there are a lot of address ports used. The downside of this is that there may be addressing conflict with some unknown hardware that use one of these ports, which seems to be the case. The ports used at the JOY81 are:

Top half of the address bus (z80 B register):

Code: Select all

; Keyboard row addresses table (msb byte)
key_row_addr:
        db  $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f
Botton half of the address bus (z80 C register; the first byte is a counter):

Code: Select all

; Ports to access the joystick RAM to store the key codes
joy_ram_ports:
        db  12,$11,$15,$13,$31,$51,$35,$33,$55,$53,$71,$75,$73     ;UP
        db  12,$09,$0d,$0b,$29,$49,$2d,$2b,$4d,$4c,$69,$6d,$6b     ;DOWN
        db  12,$05,$15,$0d,$25,$45,$35,$2d,$55,$4d,$65,$75,$6d     ;LEFT
        db  12,$03,$13,$0b,$23,$43,$33,$2b,$53,$4b,$63,$73,$6b     ;RIGHT
        db  18,$21,$23,$25,$29,$31,$2b,$33,$2d,$35,$61,$63,$65     ;BUTTON 1
        db  $69,$71,$6b,$73,$6d,$75
        db  18,$41,$43,$45,$49,$51,$4b,$53,$4d,$55,$61,$63,$65     ;BUTTON 2
        db  $69,$71,$6b,$73,$6d,$75
The port 127 in your Zeddy is full decoded?
1 x ZX81, 2 x TK85 , 1 TK82C, 1 TK95, 1 x Alphacom 32 printer, 1 x ZXpand
ZeXtender board, Joy81 - Programmable Joystick Controller, Turbo Sound 81
http://zx81.eu5.org
https://toddysoftware.itch.io/
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by siggi »

kmurta wrote: The port 127 in your Zeddy is full decoded?
Should be. I will check the hardware.

Thanks
Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by siggi »

The program works as expected, when I use the Standard Basic rom. When I use my patched rom, which has patched LOAD/SAVE routines to be used with MEFISDOS and has a patched printer routine to allow usage of a printer driver loaded to high-ram, the program crashes my Zeddy.

Do you call rom routines, which may run with ZXPAND, but not with my patched rom? Or do you PEEK some rom locations to decide, what to do?

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
User avatar
kmurta
Posts: 302
Joined: Tue Sep 01, 2009 5:04 am
Location: Belo Horizonte - BR
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by kmurta »

siggi wrote: Do you call rom routines, which may run with ZXPAND, but not with my patched rom? Or do you PEEK some rom locations to decide, what to do?
The unique ROM call that are used is to $02bb in the reading key routine, necessary to handle keys SHIFT and SPACE what that are not possible in BASIC.

To help you find where the problem may be, follow the source code of the JOY81 configuration routine (poorly commented, sorry):

Code: Select all

;Define keys characters. Note that the keys SHIFT, SPACE and NEWLINE are assigned
;to characters '?', '*' and '<' to allow them to be declared in a BASIC statement.

_MN equ $16      ; -
_SP equ $17      ; *
_SH equ $0f      ; ?
_NL equ $13      ; <
_DT equ $1b      ; .
_0 equ $1c
_1 equ $1d
_2 equ $1e
_3 equ $1f
_4 equ $20
_5 equ $21
_6 equ $22
_7 equ $23
_8 equ $24
_9 equ $25
_A equ $26
_B equ $27
_C equ $28
_D equ $29
_E equ $2A
_F equ $2B
_G equ $2C
_H equ $2D
_I equ $2E
_J equ $2F
_K equ $30
_L equ $31
_M equ $32
_N equ $33
_O equ $34
_P equ $35
_Q equ $36
_R equ $37
_S equ $38
_T equ $39
_U equ $3A
_V equ $3B
_W equ $3C
_X equ $3D
_Y equ $3E
_Z equ $3F


START:

;Decode the joystick keys

        ld d,$4f                ;search for variable J$ returning the address
        call srch_var           ;of its first element at hl
        ld de,dec_keys
        ld b,6                  ;J$ must contain exactly 6 characters and this isn't
                                ;checked by the program.
l01:
        ld a,(hl)
        inc hl

        push hl
        push bc

        cp _MN                  ;if a minus sign, not change the key
        jr nz,decrow

        ld a,$ff
        inc de
        jr nokey

decrow: push de
        ld hl,keyb_rows+39
        ld bc,40
        cpdr
        ld d,c
        ld e,5
        call div_d_e
        inc a
        ld b,a
        ld e,d
        ld d,0
        ld hl,key_row_addr
        add hl,de
        ld a,(hl)
        pop de
        ld (de),a
        inc de
        ld a,$ff
        or a
l02:
        rla
        djnz l02
nokey:
        ld (de),a
        inc de
        pop bc
        pop hl
        djnz l01



;Fill setup table at $6000 with $ff
;

        ld h,$60
        ld b,8
        ld a,$ff
l03:
        ld l,$75
l04:
        ld (hl),a
        dec l
        jr nz,l04
        inc h
        djnz l03



;Now, prepare the setup table in a RAM area started
;at address $6000

        ld hl,joy_ram_ports
        ld de,dec_keys
        ld b,6          ;load counter (for six keys)
l05:
        push bc
        ld a,(de)       ;load the key row address
        inc de

        ld c,-1         ;convert the key row address to a number
l07:                    ;between $00 and $07
        rra             ;
        inc c           ;
        jr c,l07        ;

        set 6,c         ;now the number is between $60 and $67
        set 5,c         ;
        ld a,(de)       ;load the key pattern
        inc de
        push de
        ld d,c          ;'de' will be used to address the RAM

        ld b,(hl)       ;load counter
        inc hl
l06:
        ld e,(hl)
        inc hl
        ex de,hl
        push af         ;save the key pattern
        and (hl)
        ld (hl),a
        pop af
        ex de,hl
        djnz l06

        pop de
        pop bc
        djnz l05


;Transfer the setup table in RAM to the joystick board

        ld h,$60
        ld b,$fe        ;start with keyboard row 0 (SHIFT,Z,X,C,V)
        ld d,$08
l09:
        ld e,$3a        ;58 OUT's for each keyboard row
        ld l,$03
l08:
        ld a,(hl)
        ld c,l
        inc hl           ;only consider odd addresses; this is necessary because an
        inc hl           ;OUT to a port with A0=A1=0 will cause a system crash
        out (c),a        ;sent the value to JOY81 RAM
        dec e
        jr nz,l08

        ld a,b
        rlca
        ld b,a
        inc h
        dec d
        jr nz,l09

        out ($fe),a     ;turn on the NMI generator and return to BASIC 
        ret             ;with joystick board configured.


:The following routine divides d by e and places the quotient in d and the remainder in a
div_d_e:
        xor a
        ld b, 8

_loop:
        sla d
        rla
        cp e
        jr c, $+4
        sub e
        inc d

        djnz _loop
   
        ret
 
;search the variable contained in D
srch_var:
        ld hl,($4010)
nxt_var:
        ld a,(hl)
        cp $80
        jr z,var_nf
        cp d
        jr nz,chk_fnv
        inc hl
        inc hl
        inc hl
        ret     

var_nf:
        rst 08h
        db $01

chk_fnv:
        and $e0
        cp $e0		;is it a FOR-NEXT var?
        jr nz,chk_olnv
        ld bc,$0012
adv_var:
        add hl,bc
        jr nxt_var

chk_olnv:
        cp $60		;is it a one letter numeric var?
        jr nz,chk_mlnv
adv_fpn:
        ld bc,$0006
        jr adv_var

chk_mlnv:
        cp $a0		;is it a multiple letter numeric var?
        jr nz,dim_var
nxt_chr:
        inc hl
        bit 7,(hl)
        jr z,nxt_chr
        jr adv_fpn

dim_var:		;so it is a dimensional var
        inc hl
        ld c,(hl)
        inc hl
        ld b,(hl)
        inc hl
        jr adv_var



; Keyboard row addresses table (msb byte)
key_row_addr:
        db  $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f


; Ports to access the joystick RAM to store the key codes
joy_ram_ports:
        db  12,$11,$15,$13,$31,$51,$35,$33,$55,$53,$71,$75,$73     ;UP
        db  12,$09,$0d,$0b,$29,$49,$2d,$2b,$4d,$4c,$69,$6d,$6b     ;DOWN
        db  12,$05,$15,$0d,$25,$45,$35,$2d,$55,$4d,$65,$75,$6d     ;LEFT
        db  12,$03,$13,$0b,$23,$43,$33,$2b,$53,$4b,$63,$73,$6b     ;RIGHT
        db  18,$21,$23,$25,$29,$31,$2b,$33,$2d,$35,$61,$63,$65     ;BUTTON 1
        db  $69,$71,$6b,$73,$6d,$75
        db  18,$41,$43,$45,$49,$51,$4b,$53,$4d,$55,$61,$63,$65     ;BUTTON 2
        db  $69,$71,$6b,$73,$6d,$75


;Keyboard rows

keyb_rows:
        db  _SH,_Z,_X,_C,_V               ;address $fe
        db  _A,_S,_D,_F,_G                ;address $fd
        db  _Q,_W,_E,_R,_T                ;address $fb
        db  _1,_2,_3,_4,_5                ;address $f7
        db  _0,_9,_8,_7,_6                ;address $ef
        db  _P,_O,_I,_U,_Y                ;address $df
        db  _NL,_L,_K,_J,_H               ;address $bf
        db  _SP,_DT,_M,_N,_B              ;address $7f


;Decoded keys. The key code is decoded in two bytes: the row address
;and the position of the key in a row. For example, the key '8' will
;be decoded in bytes $ef and 11111011b
dec_keys:
        db  $00,$00                       ;UP
        db  $00,$00                       ;DW
        db  $00,$00                       ;LF
        db  $00,$00                       ;RG
        db  $00,$00                       ;B1
        db  $00,$00                       ;B2


;;;;;;;;;;;;;;;;
; INKEY routine
;
inkey:  call $02bb
        ld c,$0f        ; '?'
        ld a,h
        and l
        cp $fe
        jr z,sft        ; jump if only SHIFT key is pressed
        ld a,l
        inc a
        jr z,inkey      ; jump if no key pressed
        ld b,h
        ld c,l
        call $07bd
        ld c,$17        ; '*'
        ld a,(hl)       ; is SPACE ?
        or a
        jr z,sft
        ld c,$13        ; '<'
        cp $76          ; is NEWLINE ?
        jr z,sft
        ld c,a
        
sft:    ld b,0

rlsk:   xor a           ; release key
        in a,($fe)
        or %11100000
        inc a
        ret z
        jr rlsk
Dec 03, 2013 - Code edited to compatibilize it with standard 16K Zeddy
Last edited by kmurta on Tue Dec 03, 2013 10:46 am, edited 1 time in total.
1 x ZX81, 2 x TK85 , 1 TK82C, 1 TK95, 1 x Alphacom 32 printer, 1 x ZXpand
ZeXtender board, Joy81 - Programmable Joystick Controller, Turbo Sound 81
http://zx81.eu5.org
https://toddysoftware.itch.io/
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by siggi »

kmurta wrote: To help you find where the problem may be, follow the source code of the JOY81 configuration routine (poorly commented, sorry):
Typical programmers would say: "self-explanatory code does not need comments" :mrgreen:

BTW: does the comment
" ;Now, prepare the setup table in a RAM area started
;at address $8000
"
mean, that the program needs ram above 32K and won't run on standard 16K Zeddies?

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
User avatar
kmurta
Posts: 302
Joined: Tue Sep 01, 2009 5:04 am
Location: Belo Horizonte - BR
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by kmurta »

siggi wrote: Typical programmers would say: "self-explanatory code does not need comments" :mrgreen:
:lol:
siggi wrote: BTW: does the comment
" ;Now, prepare the setup table in a RAM area started
;at address $8000
"
mean, that the program needs ram above 32K and won't run on standard 16K Zeddies?
:o :o :o

Oops... :oops:

I developed the code with ZXPand in mind and forgot to adapt it to 16K Zeddys, sorry.

I correct it in post above and post here the correct program to 16K Zeddy:
SETJOY.P
(3.48 KiB) Downloaded 342 times
1 x ZX81, 2 x TK85 , 1 TK82C, 1 TK95, 1 x Alphacom 32 printer, 1 x ZXpand
ZeXtender board, Joy81 - Programmable Joystick Controller, Turbo Sound 81
http://zx81.eu5.org
https://toddysoftware.itch.io/
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by siggi »

Hi Kelly
would the hardware allow to handle 2 closed switches as a new key. So instead having 4 directions
NORHT EAST WEST SOUTH
also 4 directions "in between" them:
NORTH-WEST NORTH-EAST SOUTH-WEST and SOUTH-EAST in addition to that?

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
User avatar
kmurta
Posts: 302
Joined: Tue Sep 01, 2009 5:04 am
Location: Belo Horizonte - BR
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by kmurta »

Yes, the configuration tools consider each relevant combination of a 2 buttons joystick, so you can have the eight mentioned directions.
1 x ZX81, 2 x TK85 , 1 TK82C, 1 TK95, 1 x Alphacom 32 printer, 1 x ZXpand
ZeXtender board, Joy81 - Programmable Joystick Controller, Turbo Sound 81
http://zx81.eu5.org
https://toddysoftware.itch.io/
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: JOY81 - Programmable Joystick Interface for ZX81

Post by siggi »

But the SETJOY program does only allow to set keys for the 4 main directions, not for the 4 directions in between them....
Is there another config-tool?

Theoretically the joystick itself can give 8 directions, in combination with 2 buttons there would be 32 simulated keys possible.
Since some games use

QWE
A D
ZXC

for navigation into 8 directions, this should be possible to be set.

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
Post Reply