Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simple cursor #34

Open
Tompis1995 opened this issue Mar 29, 2018 · 12 comments
Open

simple cursor #34

Tompis1995 opened this issue Mar 29, 2018 · 12 comments

Comments

@Tompis1995
Copy link

I'm just getting used to the built-in 6502 emulator. I'm having problems trying a code even a simple cursor. All I want is a single dot that could move up, down, left, and right by my command. What could I do to accomplish this?

@BigEd
Copy link
Collaborator

BigEd commented Apr 18, 2018

Maybe take a look at the snake game: if you cut the snake down to one cell, and stop it moving, it's pretty close to a cursor, perhaps.

@mczero80
Copy link

I have a similar problem.

You can't stop something moving, because $ff only contains the last key pressed,
A released key can't be detected with $ff. I have tried to simulate a released key by
writiting #$00 to $ff before reading the value once more from it, but it always stays at $00 after that.

@BigEd
Copy link
Collaborator

BigEd commented Apr 25, 2018

Ah, that's a bit of a problem. Here in the JavaScript we see
$(document).keypress(memory.storeKeypress);
which detects keypresses. But there's nothing to detect key releases. It wouldn't be too hard to add a handler for $(document).keyup(memory.clearKeypress) which could set $ff back to $00. Would that be a good idea? Would it demand that the Snake demo be rewritten?

(Just to note: with this simple change, typing say 'L' would give you keypress for shift, keypress for L, and then two key-up events, the first of which would clear $ff.)

@mczero80
Copy link

Interesting. I hope @skilldrick takes a look and considers a patch.

@BigEd
Copy link
Collaborator

BigEd commented Apr 25, 2018

Try this - it has the right effect I think, but it does mean that the Snake demo (and anything else) can now easily miss a short keypress. Previously keys were sticky.
http://biged.github.io/easy6502/#snake

@BigEd
Copy link
Collaborator

BigEd commented Apr 25, 2018

But hang on, your approach of writing $00 to $ff should have worked. It seems to work with this demo:

go:

LDA $ff
BEQ go

STA $f8

LDA #0
STA $ff

jmp go

@mczero80
Copy link

Okay that works.

But not this:

start:
LDX #0
STX $0200
LDA $ff
BEQ start

LDX #05
STX $0200
LDA #0
STA $FF
JMP start

Basically, the pixel in the upper left should be visible when I press a key and disappear when I release the key. I guess it is a timing thing... Not enough time to recognize the pressed key.
But I am not that great 6502 assembler programmer (yet)... I don't know.

Would be cool to have a robust code snippet that works.

@BigEd
Copy link
Collaborator

BigEd commented Apr 26, 2018

I had a look, and it doesn't quite do that: $ff isn't a register which holds the code for the currently-pressed key, like a keyboard interface might do, instead it's a register which holds the code of the last key pressed. So, if you read it and set it to zero, you see each keypress just once. If you don't set it to zero, you keep seeing the same key, even if released.

(If the key is held down, then after a short delay the keyboard will start auto-repeating, and that will appear as a succession of keypresses.)

You can see this with this program:

LDX #0

waitforkey:
LDA $ff
BEQ waitforkey
LDA #05
STA $0200,x
INX
LDA #0
STA $ff
JMP waitforkey

The code in my fork is presently different: it will clear the register when the key is released. That opens the possibility of missing the key, whereas the presently published code in the main fork can't miss a keypress. (It has no rollover: if two keys were pressed in quick succession, you'd only see the second.)

@mczero80
Copy link

Ahh I see. But your example works quite well for many use cases I guess.
A cursor should be possible now

@BigEd
Copy link
Collaborator

BigEd commented May 25, 2018

Here's a simple cursor routine: a bit of a spoiler so encoded with rot13

; Hfvat K nybar gb vaqrk vagb gur fperra
; jr whfg trg 32k8 nern gb cynl va

YQK #$90  ; zvqqyr bs gur rnfl-gb-ernpu nern

cybg:
FGK $sp ; sbe qroht
YQN #05
FGN $0200,k
WZC jnvgsbexrl

jnvgsbexrl:
YQN $ss
ORD jnvgsbexrl
FGN $s8
YQN #0
FGN $ss    ; pyrne gur xrlcerff sbe arkg gvzr
FGN $200,K ; pyrne gur pheerag cvkry
YQN $s8

; JNFQ ner $77 $61 $73 $64

PZC #$70
OPF hcqbja

yrsgevtug:
PZC #$62
OPF evtug

yrsg:
QRK        ; bss gur rqtr? jub pnerf! 
WZC cybg

evtug:
VAK
WZC cybg

hcqbja:
PZC #$74
OPF hc

qbja:
GKN
PYP
NQP #32
GNK
WZC cybg

hc:
GKN
FRP
FOP #32
GNK
WZC cybg

@Tompis1995
Copy link
Author

Tompis1995 commented May 26, 2018

Wait, I got it! This is the code:

define ascii $ff
define upMove $77
define downMove $73
define rightMove $64
define leftMove $61
define CursorPosition $200

CursorStart:
ldx #$f1
stx $02
lda #$01
sta CursorPosition,x

keyFinder:
lda $ff
cmp #upMove
beq moveUp
cmp #downMove
beq moveDown
cmp #rightMove
beq moveRight
cmp #leftMove
beq moveLeft
jmp keyFinder


moveUp:
lda #$00
sta ascii
lda #$00
sta CursorPosition,x
ldy #$00
sty $03
toTwenty:
dex
iny
sty $03
ldy $03
cpy #$20
beq newUp
jmp toTwenty
newUp:
lda #$01
sta CursorPosition,x
jmp keyFinder

moveDown:
lda #$00
sta ascii
lda #$00
sta CursorPosition,x
ldy #$00
sty $03
toTwentytoo:
inx
iny
sty $03
ldy $03
cpy #$20
beq newDown
jmp toTwentytoo
newDown:
lda #$01
sta CursorPosition,x
jmp keyFinder

moveLeft:
lda #$00
sta ascii
sta CursorPosition,x
dex
lda #$01
sta CursorPosition,x
jmp keyFinder

moveRight:
lda #$00
sta ascii
sta CursorPosition,x
inx
lda #$01
sta CursorPosition,x
jmp keyFinder

The only trouble that's left is how I can make the dot go further down. Also, the dot glitches a bit when moving vertically.

@Mr-Tibbs
Copy link

Mr-Tibbs commented May 26, 2018

I finally got this to work, don't use absolute addressing mode for the reason that it only wraps around the last 2 bytes. Use indexed indirect because then you will be able to update both the high and low bytes.

Edit: I did not define at all, sorry, I am putting in comments to make it easier to read.

;up is #$77
;left is #$61
;down is #$73
;right is #$64
;$06 is like a counter that skips 20 bytes for up and down

LDA #$02 ;$XX00 High
STA $04

LDA #$00 ;$00XX low
STA $03

JMP UPLEFT ;follow the comments to loop UPLEFT

MINUS: ;and finally at this loop I refresh the screen and finish the $06 counter for up and down
LDA #$00 ; so that $03 will contain the same left and right position for the next move down
STA ($03,X)
DEC $03
INC $06
LDA $06
CMP #$1f
BNE MINUS
LDA #$00
STA ($03,X)
DEC $04 ;I then decrement $04 so that it does not just wrap around at $03.
LDA #$01
STA ($03,X)
JMP DONE ;jump to done

OVERFLOWUPLEFT:
LDA $ff ;I then check the inputs, again because I don't know which direction is warping
CMP #$61 ;around. For instance, When it is up that is warping around it branches to MINUS ^
BEQ DONE
LDA $03
CMP #$00
BEQ MINUS

DONE:
LDA #$00 ;I then zero out the input and jump to RESET
STA $ff
JMP RESET

PLUS:
LDA #$00
STA ($03,X)
INC $03
INC $06
LDA $06
CMP #$1f
BNE PLUS
LDA #$00
STA ($03,X)
INC $04
LDA #$01
STA ($03,X)
JMP DONE2

OVERFLOWDOWNRIGHT:
LDA $ff
CMP #$64
BEQ DONE2
LDA $03
CMP #$ff
BEQ PLUS

DONE2:
LDA #$00
STA $ff
JMP RESET

RESET: ;in here I refresh the screen and then I check each input, I need to fix this part, it is
LDA #$00 ; a bit awkward
STA ($03,X)
LDA #$01
STA ($03,X)
LDA $ff
CMP #$77
BEQ OVERFLOWUPLEFT ;these loops that check the overflow are here because the wraparound
CMP #$61 ;so when it does...^ go up to OVERFLOWLEFT
BEQ OVERFLOWUPLEFT
CMP #$73
BEQ OVERFLOWDOWNRIGHT
CMP #$64
BEQ OVERFLOWDOWNRIGHT
LDA #$00
STA $ff

LDA $06
CMP #$00
BEQ UPLEFT
DEC $06
JMP RESET

UPLEFT:
LDA $ff ;at first I was just trying to get the inputs from $ff a better and faster way, but I basically
CMP #$77 ;ended up doing the same thing I did before in the reset loop.
BEQ UPIF ;so it basically looks for #$77 and if it is then it jumps to upif
CMP #$61
BNE DOWNRIGHT
;NOW inc for LEFT or up
LDA #$00
STA ($03,X)
DEC $03 ;this part is for left, so it just decrements once, not that complicated.

JMP RESET
UPIF: ;when it jumps here, I make $06 the counter and it is pretty self explanatory.
LDA #$00
STA ($03,X)
DEC $03
LDA $03
CMP #$00 ;I am comparing the low bytes in $03 to #$00 because when you DEC and it is already
BEQ RESET ; #$00 then it basically wraps around to #$ff and that is annoying, so I go to RESET
INC $06
LDA $06
CMP #$20
BNE UPIF

JMP RESET

DOWNRIGHT:
LDA $ff
CMP #$73
BEQ DOWNIF
CMP #$64
BNE UPLEFT
;NOW inc for right or DOWN
LDA #$00
STA ($03,X)
INC $03

JMP RESET
DOWNIF:
LDA #$00
STA ($03,X)
INC $03
LDA $03
CMP #$ff
BEQ RESET
INC $06
LDA $06
CMP #$20
BNE DOWNIF
JMP RESET

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants