DEV-SNIP #1 - Input

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
User avatar
sirmorris
Posts: 2671
Joined: Thu May 08, 2008 4:45 pm
Location: oxon, uk

DEV-SNIP #1 - Input

Post by sirmorris » Tue Nov 14, 2017 11:21 am

All programs need input. All zeddies have a keyboard. Great! With the availability of peripherals with joystick connections then the world of user input is looking richer than ever. With great richness comes great complexity however.

Here is my humble submission in the category of a nice general purpose input routine, where input from a number of devices is focused into a few simple values which can tell you whether an input is:

* just activated
* held
* just released
* not activated

It's currently specialised for ZXpand but it's easily updated to work with, for example, Chroma or (I still don't believe they exist) Kempston ;) :lol:
--=== ZXpand+ ... A more moderner all-in-one upgrade solution for ZX81 ===--
* SD/MMC storage * 32K Hires-capable RAM * AY sound chip * Joystick port * Serial *
* BASIC enhancements - plug & play * Reset button * Auto-boot facility *

User avatar
sirmorris
Posts: 2671
Joined: Thu May 08, 2008 4:45 pm
Location: oxon, uk

Re: DEV-SNIP #1 - Input

Post by sirmorris » Tue Nov 14, 2017 11:22 am

Code for BRASS assembler.

Code: Select all

readinput:
    call    $1ffe               ; get the joystick bits by calling ZXpand ROM function - this will crash with no ZXpand present
    ;        UDLRF---
    or      %00000111
    ld      (LAST_J),a

    ld      de,kbin             ; read the keyboard, building a table at (de)
    ld      c,$fe
    ld      b,8

-:  ld      a,c                 ; read each of the 8 half rows
    in      a,($fe)
    ld      (de),a
    rlc     c
    inc     de
    djnz    {-}

    ; point at first input state block
    ;
    ld      hl,inputstates

    call    updateinputstate ; (up)
    call    updateinputstate ; (down)
    call    updateinputstate ;  etc.
    call    updateinputstate ;
    call    updateinputstate
    call    updateinputstate

    ; fall into here for last input - quit

updateinputstate:
    ld      a,(hl)          ; input info table
    ld      (uibittest),a   ; get opcode for j/s bit test

    inc     hl
    ld      a,(hl)          ; half-row index
    inc     hl
    ld      de,kbin         ; keyboard bits table pointer - 8 byte aligned
    or      e
    ld      e,a             ; add offset to table
    ld      a,(de)          ; get key input bits
    and     (hl)            ; result will be a=0 if required key is down
    inc     hl
    jr      z,{+}           ; skip joystick read if pressed

    ld      a,(LAST_J)

+:  sla     (hl)            ; (key & 3) = 0 - not pressed, 1 - just pressed, 2 - just released and >3 - held

uibittest = $+1
    and	0             ; if a key was already detected a will be 0 so this test succeeds
    jr      nz,{+}          ; otherwise joystick bit is tested - skip if bit = 1 (not pressed)

    set     0,(hl)          ; signify impulse

+:  inc     hl              ; ready for next input in table
    ret


    .align  8
kbin:
    .byte	0,0,0,0,0,0,0,0		; storage for keyboard half-rows

LAST_J:
	.byte	0			; storage for last joystick value

; -----  4  3  2  1  0
;                       
; $FE -  V, C, X, Z, SH   0
; $FD -  G, F, D, S, A    1
; $FB -  T, R, E, W, Q    2
; $F7 -  5, 4, 3, 2, 1    3
; $EF -  6, 7, 8, 9, 0    4
; $DF -  Y, U, I, O, P    5
; $BF -  H, J, K, L, NL   6
; $7F -  B, N, M, ., SP   7
;
; joystick bit, or $ff/%11111111 for no joy
; key row offset 0-7,
; key mask,
; input impulse

inputstates:
    .byte	%10000000,2,%00000001,0        ; up      (Q)
    .byte	%01000000,1,%00000001,0        ; down    (A)
    .byte	%00100000,7,%00001000,0        ; left    (N)
    .byte	%00010000,7,%00000100,0        ; right   (M)
    .byte	%00001000,7,%00000001,0        ; fire    (SP)
    .byte	%11111111,3,%00000001,0        ; advance (1)
    .byte	%11111111,0,$00000101,0        ; quit    (SH+X)

; calculate actual input impulse addresses
up = inputstates + 3
down = inputstates + 7
left = inputstates + 11
right = inputstates + 15
fire = inputstates + 19
advance = inputstates + 23
quit = inputstates + 27

--=== ZXpand+ ... A more moderner all-in-one upgrade solution for ZX81 ===--
* SD/MMC storage * 32K Hires-capable RAM * AY sound chip * Joystick port * Serial *
* BASIC enhancements - plug & play * Reset button * Auto-boot facility *

User avatar
sirmorris
Posts: 2671
Joined: Thu May 08, 2008 4:45 pm
Location: oxon, uk

Re: DEV-SNIP #1 - Input

Post by sirmorris » Tue Nov 14, 2017 11:22 am

How it's used.

From the main program call readinput once per frame. The variables declared at the end of the code snippet point to bytes in memory where the current control state may be read.

If the value is 0, then no control is active.
If the value is 1, then a control associated with the trigger have just activated.
If the value is 3, then the controls associated with the trigger are still activated.
If the value is 2, then the controls associated with the trigger are just deactivated.

Code: Select all

	;  do something if UP pressed
	ld	a,(up)
	or	a
	jr	nz,up
	
	; fire only when fire button first pressed
	ld	a,(fire)
	cp	1
	jr	z,dofire
How it works.

Each trigger can have a joystick direction and key associated with it. The current input state is represented by bit 0 of the trigger value. The previous state is represented by the value of bit 1.

The state of a key is determined by specifying a half-row index and a bit mask. These correspond to the keyboard matrix and the table of keys and their values are shown in the table in the comment in the code. Columns show the bit number to test in the half-row, which are labelled in the diagram's rows.

The joystick direction is determined by specifying a bit mask used in some self modifying code that tests a bit in the joystick value.

The settings for an input are specified in the 'inputstates' structure like so:

Code: Select all

    .byte	%10000000,2,%00000001,0        ; up      (Q)
Here is the 'up' trigger. It's associated with bit 7 of the joystick value. It is also available by pressing Q - which appears in half-row 2, at bit 0:

Code: Select all

; -----  4  3  2  1  0
;                       
; $FE -  V, C, X, Z, SH   0
; $FD -  G, F, D, S, A    1
; $FB -  T, R, E, W, Q    2
...
The beauty of setting things up like this is that:

* input is all in one place
* redefining input is fairly simple, change the definition table
* different phases of the input can be detected easily so no external logic for one-shots is required

... and probably other stuff too.

I hope this code is useful.
--=== ZXpand+ ... A more moderner all-in-one upgrade solution for ZX81 ===--
* SD/MMC storage * 32K Hires-capable RAM * AY sound chip * Joystick port * Serial *
* BASIC enhancements - plug & play * Reset button * Auto-boot facility *

User avatar
1024MAK
Posts: 1778
Joined: Mon Sep 26, 2011 9:56 am
Location: Looking forward to summer in Somerset, UK...

Re: DEV-SNIP #1 - Input

Post by 1024MAK » Tue Nov 14, 2017 11:49 am

sirmorris wrote:
Tue Nov 14, 2017 11:21 am
It's currently specialised for ZXpand but it's easily updated to work with, for example, Chroma or (I still don't believe they exist) Kempston ;)
Before finding this forum, I didn't think any users of ZX81's existed anymore.... :roll:
Let alone that there was new software and hardware being developed :shock:

(Maybe I should go looking for some fairies at the bottom of the garden now that the "nights are drawing in"... well, after a few pints...)

Kempston joystick interfaces (or compatible interfaces) is, I presume, what is being referred to. Kempston joystick interfaces that have a ZX81 sized edge-connector and which fit AND work do exist.

It's most likely that they were not made or marketed for the ZX81, but that ZX81 sized edge-connectors were a bit cheaper than ZX Spectrum sized edge-connectors...

Of course, the cheapest joystick "interface",is to wire up a 9 way D-connector to the keyboard matrix via soldering wires to the solder connections on the keyboard sockets...

Mark

User avatar
sirmorris
Posts: 2671
Joined: Thu May 08, 2008 4:45 pm
Location: oxon, uk

Re: DEV-SNIP #1 - Input

Post by sirmorris » Tue Nov 14, 2017 12:08 pm

:D Glad to see my trap worked first time Mark :lol:

If anyone wants to donate an interface for testing purposes..! ;)
--=== ZXpand+ ... A more moderner all-in-one upgrade solution for ZX81 ===--
* SD/MMC storage * 32K Hires-capable RAM * AY sound chip * Joystick port * Serial *
* BASIC enhancements - plug & play * Reset button * Auto-boot facility *

User avatar
mrtinb
Posts: 508
Joined: Fri Nov 06, 2015 4:44 pm
Location: Denmark
Contact:

Re: DEV-SNIP #1 - Input

Post by mrtinb » Tue Nov 14, 2017 12:37 pm

sirmorris wrote:
Tue Nov 14, 2017 11:21 am
Here is my humble submission in the category of a nice general purpose input routine, where input from a number of devices is focused into a few simple values which can tell you whether an input is:
Is this a routine that gets both a joystick direction and a key back?
Can it be used for plain keyboard read, or is it only for joystick read?
Will it work for simple keybord read on hardware that is not ZXpand, or is it ZXpand specific ports?
Martin
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube

User avatar
Andy Rea
Posts: 1267
Joined: Fri May 09, 2008 1:48 pm
Location: notts UK

Re: DEV-SNIP #1 - Input

Post by Andy Rea » Tue Nov 14, 2017 12:53 pm

Cool, very cool...

Cheers Andy
6 x ZX81, 1 x TS1500 , 1 x +3e, 1 x timex 2040 printer, 1 x timex 2020 cassette deck, siclair printer and some spectrum

User avatar
sirmorris
Posts: 2671
Joined: Thu May 08, 2008 4:45 pm
Location: oxon, uk

Re: DEV-SNIP #1 - Input

Post by sirmorris » Tue Nov 14, 2017 1:42 pm

mrtinb wrote:
Tue Nov 14, 2017 12:37 pm
Is this a routine that gets both a joystick direction and a key back? Can it be used for plain keyboard read, or is it only for joystick read?
Hi Martin. It is for game-style input, where a control/trigger is attached to a particular key and/or joystick direction. It can be used for keys only, or joystick only if desired. Specify $ff/%11111111 for either of the masks. In the example there are 2 keys which don't have a joystick equivalent.
mrtinb wrote:
Tue Nov 14, 2017 12:37 pm
Will it work for simple keybord read on hardware that is not ZXpand, or is it ZXpand specific ports?
Only the joystick is ZXpand specific. The keyboard reading is Sinclair standard. No specific hardware required :D
Andy Rea wrote:
Tue Nov 14, 2017 12:53 pm
Cool, very cool...
Whaythenkyew 8-)
--=== ZXpand+ ... A more moderner all-in-one upgrade solution for ZX81 ===--
* SD/MMC storage * 32K Hires-capable RAM * AY sound chip * Joystick port * Serial *
* BASIC enhancements - plug & play * Reset button * Auto-boot facility *

Moggy
Posts: 1507
Joined: Wed Jun 18, 2008 1:00 pm

Re: DEV-SNIP #1 - Input

Post by Moggy » Tue Nov 14, 2017 2:07 pm

@Charlie

If you genuinely need a j/stk interface I have a pukka Kempston speccy one and a no-name ZX81 interface with ZX81 edge connector, you can have with my blessings.
Never used them so have to guess they are ok.
Last edited by Moggy on Tue Nov 14, 2017 2:13 pm, edited 3 times in total.

User avatar
mrtinb
Posts: 508
Joined: Fri Nov 06, 2015 4:44 pm
Location: Denmark
Contact:

Re: DEV-SNIP #1 - Input

Post by mrtinb » Tue Nov 14, 2017 2:08 pm

sirmorris wrote:
Tue Nov 14, 2017 1:42 pm
mrtinb wrote:
Tue Nov 14, 2017 12:37 pm
Will it work for simple keybord read on hardware that is not ZXpand, or is it ZXpand specific ports?
Only the joystick is ZXpand specific. The keyboard reading is Sinclair standard. No specific hardware required :D
So if I use this routine in my program without ZXpand it will crash because I don't have ZXpand?
Martin
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests