From: cuz Date: Tue, 23 Mar 2004 21:54:24 +0000 (+0000) Subject: Mouse driver implementation X-Git-Tag: V2.12.0~868 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=31595342d64db7c3e9732f9155aeac66bb905f82;p=cc65 Mouse driver implementation git-svn-id: svn://svn.cc65.org/cc65/trunk@2957 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/c64/c64-1351.s b/libsrc/c64/c64-1351.s index 6bd4cefe5..ab4732aaa 100644 --- a/libsrc/c64/c64-1351.s +++ b/libsrc/c64/c64-1351.s @@ -37,11 +37,6 @@ HEADER: .addr IOCTL .addr IRQ -; Data that is visible to the outside. Initialized by the kernel. - -XPos: .word 0 ; Current mouse position, X -YPos: .word 0 ; Current mouse position, Y - ; Callback table, set by the kernel before INSTALL is called CHIDE: jmp $0000 ; Hide the cursor @@ -57,9 +52,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 +61,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 +77,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 +102,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 +135,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,15 +147,31 @@ 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 ;---------------------------------------------------------------------------- @@ -243,8 +274,7 @@ IRQ: lda SID_ADConv1 ; Get mouse X movement ; Skip processing if nothing has changed - tay - beq @SkipX + bcc @SkipX ; Calculate the new X coordinate (--> a/y) @@ -275,19 +305,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 +332,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,12 +345,12 @@ 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 + jmp CMOVEY ; Done @@ -342,24 +371,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 diff --git a/libsrc/c64/mcbdefault.s b/libsrc/c64/mcbdefault.s index 44c911035..0199f717f 100644 --- a/libsrc/c64/mcbdefault.s +++ b/libsrc/c64/mcbdefault.s @@ -2,6 +2,9 @@ ; Default mouse callbacks for the C64 ; ; Ullrich von Bassewitz, 2004-03-20 +; +; All functions in this module should be interrupt safe, because they may +; be called from an interrupt handler ; .export _mouse_def_callbacks @@ -9,6 +12,7 @@ .include "mouse-kernel.inc" .include "c64.inc" + .macpack generic ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. @@ -18,71 +22,74 @@ MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register - .code ; -------------------------------------------------------------------------- -; Hide the mouse pointer +; Hide the mouse pointer. Always called with interrupts disabled. .proc hide lda #MOUSE_SPR_NMASK - sei and VIC_SPR_ENA sta VIC_SPR_ENA - cli rts .endproc ; -------------------------------------------------------------------------- -; Show the mouse pointer +; Show the mouse pointer. Always called with interrupts disabled. .proc show lda #MOUSE_SPR_MASK - sei ora VIC_SPR_ENA sta VIC_SPR_ENA - cli rts .endproc ; -------------------------------------------------------------------------- -; Move the mouse pointer X position to the value in a/x +; Move the mouse pointer X position to the value in a/x. Always called with +; interrupts disabled. .proc movex -; Set the low byte, this frees A +; Add the X correction and set the low byte. This frees A. + add #24 ; X correction sta VIC_SPR_X ; Set the high byte - txa ; Test high byte of X coord - bne @L1 - sei + txa + adc #0 + bne @L1 ; Branch if high byte not zero lda VIC_SPR_HI_X ; Get high X bits of all sprites and #MOUSE_SPR_NMASK ; Clear high bit for sprite sta VIC_SPR_HI_X - cli rts -@L1: sei - lda VIC_SPR_HI_X ; Get high X bits of all sprites - ora #MOUSE_SPR_NMASK ; Set high bit for sprite +@L1: lda VIC_SPR_HI_X ; Get high X bits of all sprites + ora #MOUSE_SPR_MASK ; Set high bit for sprite sta VIC_SPR_HI_X - cli rts .endproc ; -------------------------------------------------------------------------- -; Move the mouse pointer Y position to the value in a/x +; Move the mouse pointer Y position to the value in a/x. Always called with +; interrupts disabled. .proc movey + clc + ldx PALFLAG + bne @L1 + adc #50 ; FIXME: Should be NTSC, is PAL value + sta VIC_SPR_Y ; Set Y position + rts + +@L1: adc #50 ; Add PAL correction sta VIC_SPR_Y ; Set Y position rts @@ -100,4 +107,3 @@ _mouse_def_callbacks: .addr movey -