X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libsrc%2Fc128%2Fmouse.s;h=05628a54d043f270b5bd9aa398d788d0bb41d051;hb=380582e4a34245178c029fc76b6c80972b113844;hp=64e8a8076753c2744ba420a09f282a5050c2b829;hpb=4e3fcec239fd3d600d4ebd3c5c732a25acfe1f3a;p=cc65 diff --git a/libsrc/c128/mouse.s b/libsrc/c128/mouse.s index 64e8a8076..05628a54d 100644 --- a/libsrc/c128/mouse.s +++ b/libsrc/c128/mouse.s @@ -10,207 +10,242 @@ .export _mouse_box, _mouse_info .export _mouse_move, _mouse_pos .export _mouse_buttons, _mouse_info + .condes MouseIRQ, 2 .import _readjoy - .import popa, popsreg, addysp1 - .importzp ptr1, sp, sreg + .import popax, addysp1 + .importzp ptr1, sp .include "c128.inc" .macpack generic + .code ; -------------------------------------------------------------------------- ; -; unsigned char __fastcall__ mouse_init (unsigned char port, -; unsigned char sprite, -; unsigned char type); +; Constants ; -_mouse_init: - jsr popa ; Ignore the type, get sprite param - tax ; Save sprite number - jsr popa ; Get the port number +SPRITE_HEIGHT = 21 +SPRITE_WIDTH = 24 +SCREEN_HEIGHT = 200 +SCREEN_WIDTH = 320 +XCORR = SPRITE_WIDTH - ldy OldIRQ+1 ; Already initialized? - bne AlreadyInitialized ; Jump if yes +; -------------------------------------------------------------------------- +; +; unsigned char __fastcall__ mouse_init (unsigned char type); +; - stx MouseSprite ; Remember the sprite number - sta MousePort ; Remember the port number +.proc _mouse_init + lda Initialized ; Already initialized? + bne AlreadyInitialized ; Jump if yes ; Initialize variables ldx #0 - stx XPos + lda #XCORR + sta XPos stx XPos+1 stx YPos stx YPos+1 stx OldPotX stx OldPotY stx XMin - stx XMin+1 ; XMin = 0 - lda #29 + stx XMin+1 ; XMin = 0 + lda #50 ; ## FIXME: This is the PAL value + sta YCorr + sta YPos + stx YPos+1 + sec + sbc #SPRITE_HEIGHT ; Sprite height in pixels sta YMin - stx YMin+1 ; YMin = 29 - lda #250 + stx YMin+1 ; YMin = 29 + lda #SCREEN_HEIGHT ; Vertical screen res + add YCorr ; Add correction factor sta YMax - stx YMax+1 ; YMax = 250 - inx ; X = 1 - stx Invisible ; Mouse *not* visible - lda #<344 + stx YMax+1 + inx ; X = 1 + stx Invisible ; Mouse *not* visible + lda #<(SCREEN_WIDTH + SPRITE_WIDTH) sta XMax - stx XMax+1 ; XMax = 344 + stx XMax+1 ; XMax = 320 + sprite width -; Remember the old IRQ vector +; Save the old init status and reset bit 0. This will disable the BASIC +; IRQ handler which will otherwise try to manage the mouse sprite on its +; own - lda IRQVec - sta OldIRQ - lda IRQVec+1 - sta OldIRQ+1 + lda INIT_STATUS + sta OldInitStatus + and #$FE + sta INIT_STATUS -; Set our own IRQ vector. We cheat here to save a few bytes of code: -; The function is expected to return a value not equal to zero on success, -; and since we know that the high byte of the IRQ handler address is never -; zweo, we will return just this byte. +; Mouse successfully initialized - ldx #MouseIRQ - bne SetIRQ ; Branch always + lda #1 + sta Initialized + rts AlreadyInitialized: - lda #0 ; Error + lda #0 ; Error rts +.endproc + ; -------------------------------------------------------------------------- ; ; void mouse_done (void); ; _mouse_done: - ldx OldIRQ ; Initialized? - lda OldIRQ+1 - beq Done ; Jump if no - ldy #0 - sty OldIRQ+1 ; Reset the initialized flag -SetIRQ: sei ; Disable interrupts - stx IRQVec ; Set the new/old vector - sta IRQVec+1 - cli ; Enable interrupts -Done: rts + lda Initialized ; Initialized? + beq mddone ; Jump if no + lda #0 + sta Initialized ; Reset the initialized flag + lda OldInitStatus ; Load the old BASIC int bit + and #$01 ; Mask it + ora INIT_STATUS ; Restore the old state + sta INIT_STATUS + +; Disable the mouse sprite + +DisableSprite: + lda #$FE ; Clear bit for sprite #0 + sei ; Disable interrupts + and VIC_SPR_ENA + sta VIC_SPR_ENA ; Disable sprite + cli ; Enable interrupts +mddone: rts + ; -------------------------------------------------------------------------- ; ; void mouse_hide (void); ; -_mouse_hide: +.proc _mouse_hide + lda Invisible ; Get the flag bne @L1 ; Jump if already invisible - ldx MouseSprite ; Sprite defined? - beq @L1 ; Jump if no - - lda NotMask-1,x ; Get clean mask - - sei ; Disable interrupts - and VIC_SPR_ENA - sta VIC_SPR_ENA ; Disable sprite - cli ; Enable interrupts - + jsr DisableSprite ; Disable the mouse sprite @L1: inc Invisible ; Set the flag to invisible rts +.endproc + ; -------------------------------------------------------------------------- ; ; void mouse_show (void); ; -_mouse_show: +.proc _mouse_show + lda Invisible ; Mouse invisible? beq @L1 ; Jump if no dec Invisible ; Set the flag bne @L1 ; Jump if still invisible - ldx MouseSprite ; Sprite defined? - beq @L1 ; Jump if no sei ; Disable interrupts jsr MoveSprite1 ; Move the sprite to it's position - - ldx MouseSprite ; Get sprite number (again) - lda BitMask-1,x ; Get bit mask - ora VIC_SPR_ENA - sta VIC_SPR_ENA ; Enable sprite - - cli ; Enable interrupts + lda VIC_SPR_ENA ; Get sprite enable register + ora #$01 ; Enable sprite #0 + sta VIC_SPR_ENA ; Write back + cli ; Enable interrupts @L1: rts +.endproc + ; -------------------------------------------------------------------------- ; ; void __fastcall__ mouse_box (int minx, int miny, int maxx, int maxy); ; -_mouse_box: +.proc _mouse_box + ldy #0 ; Stack offset - sei ; Disable interrupts + add YCorr ; Adjust the Y value + bcc @L1 + inx + clc +@L1: sei ; Disable interrupts sta YMax - stx YMax+1 ; maxy + stx YMax+1 ; maxy - lda (sp),y + lda (sp),y + adc #XCORR sta XMax iny lda (sp),y - sta XMax+1 ; maxx + adc #$00 + sta XMax+1 ; maxx iny lda (sp),y - sta YMin + add YCorr + sta YMin iny lda (sp),y - sta YMin+1 ; miny + adc #$00 + sta YMin+1 ; miny iny lda (sp),y - sta XMin + add #XCORR + sta XMin iny lda (sp),y - sta XMin+1 ; minx + adc #$00 + sta XMin+1 ; minx - cli ; Enable interrupts + cli ; Enable interrupts jmp addysp1 ; Drop params, return +.endproc + ; -------------------------------------------------------------------------- ; ; void __fastcall__ mouse_pos (struct mouse_pos* pos); ; /* Return the current mouse position */ ; -_mouse_pos: +.proc _mouse_pos + sta ptr1 stx ptr1+1 ; Remember the argument pointer - ldy #0 ; Structure offset - - sei ; Disable interrupts + ldy #0 ; Structure offset + sec ; Needed for the SBC later + sei ; Disable interrupts lda XPos ; Transfer the position + sbc #XCORR sta (ptr1),y lda XPos+1 + sbc #$00 iny sta (ptr1),y - lda YPos - iny - sta (ptr1),y - lda YPos+1 - iny - sta (ptr1),y + lda YPos + ldx YPos+1 + cli ; Restore initial interrupt state + + sub YCorr ; Apply the Y correction value + bcs @L1 + dex +@L1: iny + sta (ptr1),y ; Store YPos + txa + iny + sta (ptr1),y - cli ; Restore initial interrupt state + rts ; Done - rts ; Done +.endproc ; -------------------------------------------------------------------------- ; @@ -218,7 +253,7 @@ _mouse_pos: ; /* Return the state of the mouse buttons and the position of the mouse */ ; -_mouse_info: +.proc _mouse_info ; We're cheating here to keep the code smaller: The first fields of the ; mouse_info struct are identical to the mouse_pos struct, so we will just @@ -229,51 +264,68 @@ _mouse_info: ; Fill in the button state - jsr _mouse_buttons ; Will not touch ptr1 - ldy #4 - sta (ptr1),y + jsr _mouse_buttons ; Will not touch ptr1 + ldy #4 + sta (ptr1),y rts +.endproc + ; -------------------------------------------------------------------------- ; ; void __fastcall__ mouse_move (int x, int y); ; -_mouse_move: - jsr popsreg ; Get X - sei ; Disable interrupts - - sta YPos - stx YPos+1 - lda sreg - ldx sreg+1 - sta XPos - stx XPos+1 ; Set new position - - jsr MoveSprite ; Move the sprite to the mouse pos +.proc _mouse_move + + add YCorr ; Add Y coordinate correction + bcc @L1 + inx + clc +@L1: sei + sta YPos + stx YPos+1 + cli + + jsr popax ; Get X + adc #XCORR ; Adjust X coordinate + bcc @L2 + inx +@L2: sei + sta XPos + stx XPos+1 ; Set new position + jsr MoveSprite ; Move the sprite to the mouse pos + cli ; Enable interrupts -@L9: cli ; Enable interrupts rts +.endproc ; -------------------------------------------------------------------------- ; ; unsigned char mouse_buttons (void); ; -_mouse_buttons: - lda MousePort ; Get the port +.proc _mouse_buttons + + lda #$00 ; Use port #0 jmp _readjoy ; Same as joystick +.endproc + ; -------------------------------------------------------------------------- ; ; Mouse interrupt handler ; +IRQDone:rts + MouseIRQ: - cld - lda SID_ADConv1 ; Get mouse X movement + + lda Initialized ; Mouse initialized? + beq IRQDone ; Jump if no + lda SID_ADConv1 ; Get mouse X movement ldy OldPotX jsr MoveCheck ; Calculate movement vector sty OldPotX @@ -338,14 +390,39 @@ MouseIRQ: @L4: sty YPos stx YPos+1 -; Move the mouse sprite if it is enabled +; Move the mouse sprite to the current mouse position. Must be called +; with interrupts off. MoveSprite1 is an entry without checking. - jsr MoveSprite ; Move the sprite +MoveSprite: -; Jump to the next IRQ handler + lda Invisible ; Mouse visible? + bne Done ; Jump if no - jmp (OldIRQ) +; Set the high X bit + +MoveSprite1: + lda VIC_SPR_HI_X ; Get high X bits of all sprites + and #$FE ; Clear bit for sprite #0 + ldy XPos+1 ; Test Y position + beq @L5 + ora #$01 ; Set high X bit +@L5: sta VIC_SPR_HI_X ; Set hi X sprite values + +; Set the low X byte + lda XPos + sta VIC_SPR0_X ; Set low byte + +; Set the Y position + + ldy YPos+1 ; Negative or too large? + bne Done ; Jump if yes + lda YPos + sta VIC_SPR0_Y ; Set Y position + +; Done + +Done: rts ; -------------------------------------------------------------------------- ; @@ -357,7 +434,8 @@ MouseIRQ: ; x/a = delta value for position ; -MoveCheck: +.proc MoveCheck + sty OldValue sta NewValue ldx #$00 @@ -383,60 +461,18 @@ MoveCheck: @L2: txa ; A = $00 rts -; -------------------------------------------------------------------------- -; -; Move the mouse sprite to the current mouse position. Must be called -; with interrupts off. MoveSprite1 is an entry without checking and -; loading X -; - -MoveSprite: - - lda Invisible ; Mouse visible? - bne MoveSpriteDone ; Jump if no - ldx MouseSprite ; Sprite defined? - beq MoveSpriteDone ; Jump if no - -; Set the high X bit - -MoveSprite1: - lda VIC_SPR_HI_X ; Get high X bits of all sprites - and NotMask-1,x ; Mask out sprite bit - ldy XPos+1 ; Test Y position - beq @L1 - ora BitMask-1,x ; Set high X bit -@L1: sta VIC_SPR_HI_X ; Set hi X sprite values - -; Set the low X byte - - txa - asl a ; Index*2 - tax - lda XPos - sta VIC_SPR0_X-2,x ; Set low byte - -; Set the Y position - - ldy YPos+1 ; Negative or too large? - bne MoveSpriteDone ; Jump if yes - lda YPos - sta VIC_SPR0_Y-2,x ; Set Y position - -; Done - -MoveSpriteDone: - rts +.endproc ; -------------------------------------------------------------------------- ; Data .bss -OldIRQ: .res 2 ; Old IRQ vector -MousePort: .res 1 ; Port used for the mouse -MouseSprite: .res 1 ; Number of sprite to control +Initialized: .res 1 ; True if mouse initialized +OldInitStatus: .res 1 ; Old IRQ flag value OldValue: .res 1 ; Temp for MoveCheck routine NewValue: .res 1 ; Temp for MoveCheck routine +YCorr: .res 1 ; Correction for Y coordinate Invisible: .res 1 ; Is the mouse invisible? OldPotX: .res 1 ; Old hw counter values @@ -450,12 +486,4 @@ YMin: .res 2 ; Y1 value of bounding box XMax: .res 2 ; X2 value of bounding box YMax: .res 2 ; Y2 value of bounding box -.data - -BitMask: .byte $01, $02, $04, $08, $10, $20, $40, $80 -NotMask: .byte $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F - - - -