X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=libsrc%2Fc64%2Fc64-1351.s;h=132b69f9f3a3225c38aa996fcf289bccb720e1cf;hb=931add050ea929e67a45242fbff758464e8ef3c7;hp=6bd4cefe5e86e1d5239ef03b932c69b86cb07188;hpb=3bfbaee6a66a34e8dab0c5a5c4653f96f704d598;p=cc65 diff --git a/libsrc/c64/c64-1351.s b/libsrc/c64/c64-1351.s index 6bd4cefe5..132b69f9f 100644 --- a/libsrc/c64/c64-1351.s +++ b/libsrc/c64/c64-1351.s @@ -37,10 +37,9 @@ HEADER: .addr IOCTL .addr IRQ -; Data that is visible to the outside. Initialized by the kernel. +; Mouse driver flags -XPos: .word 0 ; Current mouse position, X -YPos: .word 0 ; Current mouse position, Y + .byte MOUSE_FLAG_LATE_IRQ ; Callback table, set by the kernel before INSTALL is called @@ -57,9 +56,8 @@ SCREEN_HEIGHT = 200 SCREEN_WIDTH = 320 ;---------------------------------------------------------------------------- -; -; Global variables -; +; Global variables. The bounding box values are sorted so that they can be +; written with the least effort in the BOX routine, so don't reorder them. .bss @@ -67,10 +65,12 @@ Vars: OldPotX: .res 1 ; Old hw counter values OldPotY: .res 1 -XMin: .res 2 ; X1 value of bounding box -YMin: .res 2 ; Y1 value of bounding box -XMax: .res 2 ; X2 value of bounding box +YPos: .res 2 ; Current mouse position, Y +XPos: .res 2 ; Current mouse position, X YMax: .res 2 ; Y2 value of bounding box +XMax: .res 2 ; X2 value of bounding box +YMin: .res 2 ; Y1 value of bounding box +XMin: .res 2 ; X1 value of bounding box OldValue: .res 1 ; Temp for MoveCheck routine NewValue: .res 1 ; Temp for MoveCheck routine @@ -81,9 +81,12 @@ NewValue: .res 1 ; Temp for MoveCheck routine .proc DefVars .byte 0, 0 ; OldPotX/OldPotY - .word 0, 0 ; XMin/YMin - .word SCREEN_WIDTH ; XMax + .word SCREEN_HEIGHT/2 ; YPos + .word SCREEN_WIDTH/2 ; XPos .word SCREEN_HEIGHT ; YMax + .word SCREEN_WIDTH ; XMax + .word 0 ; YMin + .word 0 ; XMin .endproc .code @@ -103,18 +106,31 @@ INSTALL: dex bpl @L1 +; Be sure the mouse cursor is invisible and at the default location. We +; need to do that here, because our mouse interrupt handler doesn't set the +; mouse position if it hasn't changed. + + sei + jsr CHIDE + lda XPos + ldx XPos+1 + jsr CMOVEX + lda YPos + ldx YPos+1 + jsr CMOVEY + cli + ; Done, return zero (= MOUSE_ERR_OK) - inx ; X = 0 + ldx #$00 txa -; rts ; Run into UNINSTALL instead + rts ; Run into UNINSTALL instead ;---------------------------------------------------------------------------- ; UNINSTALL routine. Is called before the driver is removed from memory. ; No return code required (the driver is removed from memory on return). -UNINSTALL: - rts +UNINSTALL = HIDE ; Hide cursor on exit ;---------------------------------------------------------------------------- ; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages @@ -123,7 +139,10 @@ UNINSTALL: ; no special action is required besides hiding the mouse cursor. ; No return code required. -HIDE = CHIDE +HIDE: sei + jsr CHIDE + cli + rts ;---------------------------------------------------------------------------- ; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages @@ -132,19 +151,37 @@ HIDE = CHIDE ; no special action is required besides enabling the mouse cursor. ; No return code required. -SHOW = CSHOW +SHOW: sei + jsr CSHOW + cli + rts ;---------------------------------------------------------------------------- -; BOX: Set the mouse bounding box. No checks are done if the mouse is -; currently inside the box, this is the job of the caller. It is not necessary -; to validate the parameters, trust the caller and save some code here. -; No return code required. +; BOX: Set the mouse bounding box. The parameters are passed as they come from +; the C program, that is, maxy in a/x and the other parameters on the stack. +; The C wrapper will remove the parameters from the stack when the driver +; routine returns. +; No checks are done if the mouse is currently inside the box, this is the job +; of the caller. It is not necessary to validate the parameters, trust the +; caller and save some code here. No return code required. + +BOX: ldy #5 + sei + sta YMax + stx YMax+1 + +@L1: lda (sp),y + sta XMax,y + dey + bpl @L1 -BOX: + cli rts ;---------------------------------------------------------------------------- -; MOVE: Move the mouse to a new position which is passed in X=ptr1, Y=a/x. +; MOVE: Move the mouse to a new position. The position is passed as it comes +; from the C program, that is: X on the stack and Y in a/x. The C wrapper will +; remove the parameter from the stack on return. ; No checks are done if the new position is valid (within the bounding box or ; the screen). No return code required. ; @@ -155,10 +192,13 @@ MOVE: sei ; No interrupts stx YPos+1 ; New Y position jsr CMOVEY ; Set it - lda ptr1 - ldx ptr1+1 - sta XPos - stx XPos+1 ; New X position + ldy #$01 + lda (sp),y + sta XPos+1 + tax + dey + lda (sp),y + sta XPos ; New X position jsr CMOVEX ; Move the cursor @@ -233,7 +273,9 @@ IOCTL: lda # a/y) @@ -275,19 +316,18 @@ IRQ: lda SID_ADConv1 ; Get mouse X movement ; Move the mouse pointer to the new X pos tya - jsr CMOVEY + jsr CMOVEX ; Calculate the Y movement vector @SkipX: lda SID_ADConv2 ; Get mouse Y movement - ldy OldPotY - jsr MoveCheck ; Calculate movement - sty OldPotY + ldy OldPotY + jsr MoveCheck ; Calculate movement + sty OldPotY ; Skip processing if nothing has changed - tay - beq @SkipY + bcc @SkipY ; Calculate the new Y coordinate (--> a/y) @@ -303,8 +343,8 @@ IRQ: lda SID_ADConv1 ; Get mouse X movement ; Limit the Y coordinate to the bounding box cpy YMin - sbc YMin+1 - bpl @L3 + sbc YMin+1 + bpl @L3 ldy YMin ldx YMin+1 jmp @L4 @@ -316,15 +356,16 @@ IRQ: lda SID_ADConv1 ; Get mouse X movement ldy YMax ldx YMax+1 @L4: sty YPos - stx YPos+1 + stx YPos+1 ; Move the mouse pointer to the new X pos tya - jsr CMOVEX + jsr CMOVEY ; Done + clc ; Interrupt not handled @SkipY: rts ; -------------------------------------------------------------------------- @@ -342,24 +383,27 @@ MoveCheck: sta NewValue ldx #$00 - sub OldValue ; a = mod64 (new - old) + sub OldValue ; a = mod64 (new - old) and #%01111111 - cmp #%01000000 ; if (a > 0) - bcs @L1 ; - lsr a ; a /= 2; - beq @L2 ; if (a != 0) - ldy NewValue ; y = NewValue - rts ; return - -@L1: ora #%11000000 ; else or in high order bits - cmp #$FF ; if (a != -1) + cmp #%01000000 ; if (a > 0) + bcs @L1 ; + lsr a ; a /= 2; + beq @L2 ; if (a != 0) + ldy NewValue ; y = NewValue + sec + rts ; return + +@L1: ora #%11000000 ; else or in high order bits + cmp #$FF ; if (a != -1) beq @L2 sec - ror a ; a /= 2 - dex ; high byte = -1 (X = $FF) + ror a ; a /= 2 + dex ; high byte = -1 (X = $FF) ldy NewValue + sec rts -@L2: txa ; A = $00 +@L2: txa ; A = $00 + clc rts