From 5da525e0ea10987d9dbf1ad2ba5bad9548d23f59 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sat, 16 Nov 2019 14:51:24 -0500 Subject: [PATCH 096/170] Added a standard mouse driver to the cx16 library. --- doc/cx16.sgml | 9 +- include/cx16.h | 9 +- libsrc/cx16/mcbdefault.s | 65 +++++++ libsrc/cx16/mou/cx16-std.s | 310 ++++++++++++++++++++++++++++++++ libsrc/cx16/mouse_stat_stddrv.s | 11 ++ libsrc/cx16/mouse_stddrv.s | 13 ++ 6 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 libsrc/cx16/mcbdefault.s create mode 100644 libsrc/cx16/mou/cx16-std.s create mode 100644 libsrc/cx16/mouse_stat_stddrv.s create mode 100644 libsrc/cx16/mouse_stddrv.s diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 16e43db9..7189e715 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -236,7 +236,14 @@ point to Mouse drivers

-No mouse drivers are available currently for the CX16. +The default drivers, + + Supports a standard 3-button mouse connected to the PS/2 mouse port of the + Commander X16. +

RS232 device drivers

diff --git a/include/cx16.h b/include/cx16.h index a6f1b78f..b465378a 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -115,7 +115,7 @@ #define TV_NTSC_MONO 6 #define TV_RGB2 7 -/* Video mode defines */ +/* Video modes */ #define VIDEOMODE_40x30 0x00 #define VIDEOMODE_80x60 0x02 #define VIDEOMODE_40COL VIDEOMODE_40x30 @@ -123,6 +123,12 @@ #define VIDEOMODE_320x240 0x80 #define VIDEOMODE_SWAP (-1) +/* VERA's interrupt flags */ +#define VERA_IRQ_VSYNC 0b00000001 +#define VERA_IRQ_RASTER 0b00000010 +#define VERA_IRQ_SPR_COLL 0b00000100 +#define VERA_IRQ_UART 0b00001000 + /* Define hardware */ @@ -163,6 +169,7 @@ struct __emul { /* The addresses of the static drivers */ extern void cx16_std_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void cx16_std_mou[]; /* Referred to by mouse_static_stddrv[] */ diff --git a/libsrc/cx16/mcbdefault.s b/libsrc/cx16/mcbdefault.s new file mode 100644 index 00000000..d817b9ae --- /dev/null +++ b/libsrc/cx16/mcbdefault.s @@ -0,0 +1,65 @@ +; +; Default mouse callbacks for the CX16 +; +; 2019-11-09, Greg King +; +; All functions in this module should be interrupt safe +; because they might be called from an interrupt handler. +; + + .export _mouse_def_callbacks + + .include "cbm_kernal.inc" + .include "cx16.inc" + +; -------------------------------------------------------------------------- +; Hide the mouse pointer. Always called with interrupts disabled. + +.code + +hide: ldx #$00 ; Don't change sprite's scale + lda #$00 ; Disable sprite + jmp MOUSE + +; -------------------------------------------------------------------------- +; Show the mouse pointer. Always called with interrupts disabled. + +show: ldx #$00 + lda #<-$01 ; Enable sprite + jmp MOUSE + +; -------------------------------------------------------------------------- +; Prepare to move the mouse pointer. Always called with interrupts disabled. + +prep: ; Fall through + +; -------------------------------------------------------------------------- +; Draw the mouse pointer. Always called with interrupts disabled. + +draw: ; Fall through + +; -------------------------------------------------------------------------- +; Move the mouse pointer X position to the value in .XA . Always called with +; interrupts disabled. + +movex: ; Already set by drivers + ; Fall through + +; -------------------------------------------------------------------------- +; Move the mouse pointer Y position to the value in .XA . Always called with +; interrupts disabled. + +movey: rts ; Already set by drivers + +; -------------------------------------------------------------------------- +; Callback structure + +.rodata + +_mouse_def_callbacks: + .addr hide + .addr show + .addr prep + .addr draw + .addr movex + .addr movey diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s new file mode 100644 index 00000000..eb3f8316 --- /dev/null +++ b/libsrc/cx16/mou/cx16-std.s @@ -0,0 +1,310 @@ +; +; Driver for the Commander X16 Kernal's mouse driver. +; +; 2019-11-16, Greg King +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "cx16.inc" + .include "cbm_kernal.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _cx16_std_mou + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; ASCII "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr HIDE + .addr SHOW + .addr SETBOX + .addr GETBOX + .addr MOVE + .addr BUTTONS + .addr POS + .addr INFO + .addr IOCTL + .addr IRQ + +; Mouse driver flags + + .byte $00 ; Don't need interrupts + +; Callback table, set by the mouse kernel before INSTALL is called + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CPREP: jmp $0000 ; Prepare to move the cursor +CDRAW: jmp $0000 ; Draw the cursor +CMOVEX: jmp $0000 ; Move the cursor to X coord +CMOVEY: jmp $0000 ; Move the cursor to Y coord + + +;---------------------------------------------------------------------------- +; Constants + +SCREEN_WIDTH = 640 - 1 ; (origin is zero) +SCREEN_HEIGHT = 480 - 1 + +;---------------------------------------------------------------------------- +; Global variables. + +.bss + +XPos := MOUSEX ; Current mouse position, X +YPos := MOUSEY ; Current mouse position, Y + +XMin := MOUSEL ; X1 value of bounding box +XMax := MOUSER ; X2 value of bounding box +YMin := MOUSET ; Y1 value of bounding box +YMax := MOUSEB ; Y2 value of bounding box +Box := XMin + +Buttons := MOUSEBT ; button status bits + +.rodata + +; Default values for above variables +; (We use ".proc" because we want to define both a label and a scope.) + +.proc DefBox + .word 0 ; XMin + .word SCREEN_WIDTH ; XMax + .word 0 ; YMin + .word SCREEN_HEIGHT ; YMax +.endproc + +; These button masks are compatible with the CBM 1351 and the CMD SmartMouse. + +ButtMask: + .byte %00000000 ; No buttons + .byte %00010000 ; Left + .byte %00000001 ; Right + .byte %00010001 ; Left, right + .byte %00000010 ; Middle + .byte %00010010 ; Left, middle + .byte %00000011 ; Middle, right + .byte %00010011 ; Left, middle, right + +.code + +;---------------------------------------------------------------------------- +; INSTALL routine. Is called after the driver is loaded into memory. +; If possible, check if the hardware is present. +; Must return a MOUSE_ERR_xx code in .XA . + +INSTALL: + +; Initialize variables. Just copy the default stuff over. + + ldx #.sizeof(DefBox) - 1 +@L1: lda DefBox,x + sta Box,x + dex + bpl @L1 + + ldx #$00 ; Don't change sprite's scale + lda #$01 ; Initiate and show sprite + jsr MOUSE + +; Be sure the mouse cursor is invisible, and at the default location. We +; need to do that here, because the mouse interrupt handler might not 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 + + ldx #>MOUSE_ERR_OK + txa + rts + +;---------------------------------------------------------------------------- +; UNINSTALL routine -- is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). + +UNINSTALL := HIDE ; Hide cursor on exit + +;---------------------------------------------------------------------------- +; HIDE routine -- is called to hide the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse currently is visible, and should get hidden. For most drivers, +; no special action is required besides disabling the mouse cursor. +; No return code required. + +HIDE: jmp CHIDE + +;---------------------------------------------------------------------------- +; SHOW routine -- is called to show the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse currently is hidden, and should become visible. For most drivers, +; no special action is required besides enabling the mouse cursor. +; No return code required. + +SHOW: jmp CSHOW + +;---------------------------------------------------------------------------- +; SETBOX: Set the mouse bounding box. The parameters are passed as they come +; from the C program, that is, a pointer to a mouse_box struct in .XA . +; No checks are done if the mouse is currently inside the box, that 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. + +SETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + lda (ptr1) + ldy #$01 + + sei + sta XMin + lda (ptr1),y + sta YMin + iny + lda (ptr1),y + sta XMax + iny + lda (ptr1),y + sta YMax + cli + + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the mouse bounding box. The parameters are passed as they +; come from the C program, that is, a pointer to a mouse_box struct in .XA . + +GETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + lda XMin + sta (ptr1) + ldy #$01 + lda YMin + sta (ptr1),y + iny + lda XMax + sta (ptr1),y + iny + lda YMax + sta (ptr1),y + rts + +;---------------------------------------------------------------------------- +; MOVE: Put the mouse at a new position. That position is passed as it comes +; from the C program, that is: X on the stack and Y in .XA . The C wrapper +; will remove the parameter from the stack, on return. +; No checks are done to see if the new position is valid (within +; the bounding box or the screen). No return code required. + +MOVE: sei ; No interrupts + + sta YPos + stx YPos+1 ; New Y position + jsr CMOVEY ; Set it + + ldy #$01 + lda (sp),y + sta XPos+1 + tax + dey + lda (sp),y + sta XPos ; New X position + jsr CMOVEX ; Move the cursor + + cli ; Allow interrupts + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the CBM 1351 button mask in .XA . + +BUTTONS: + lda Buttons + and #%00000111 + tax + lda ButtMask,x + ldx #>$0000 + rts + +;---------------------------------------------------------------------------- +; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. +; No return code required. + +POS: ldy #MOUSE_POS::XCOORD ; Structure offset + + sei ; Disable interrupts + lda XPos ; Transfer the position + sta (ptr1),y + lda XPos+1 + iny + sta (ptr1),y + lda YPos + iny + sta (ptr1),y + lda YPos+1 + cli ; Enable interrupts + + iny + sta (ptr1),y ; Store last byte + rts ; Done + +;---------------------------------------------------------------------------- +; INFO: Returns mouse position and current button mask in the MOUSE_INFO +; struct pointed to by ptr1. No return code required. +; +; 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 just will +; call mouse_pos to initialize the struct pointer, and fill the position +; fields. + +INFO: jsr POS + +; Fill in the button state + + jsr BUTTONS ; Will not touch ptr1 + ldy #MOUSE_INFO::BUTTONS + sta (ptr1),y + rts + +;---------------------------------------------------------------------------- +; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; specific data in ptr1, and the ioctl code in A. +; Must return an error code in .XA . +; + +IOCTL: lda #MOUSE_ERR_INV_IOCTL +; rts ; Fall through + +;---------------------------------------------------------------------------- +; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context +; (so be careful). The routine MUST return carry set if the interrupt has been +; 'handled' -- which means that the interrupt source is gone. Otherwise, it +; MUST return carry clear. + +IRQ: rts ; Kernal ROM does this routine's job diff --git a/libsrc/cx16/mouse_stat_stddrv.s b/libsrc/cx16/mouse_stat_stddrv.s new file mode 100644 index 00000000..1ff8ad43 --- /dev/null +++ b/libsrc/cx16/mouse_stat_stddrv.s @@ -0,0 +1,11 @@ +; +; Address of the static standard mouse driver +; +; 2019-11-08,Greg King +; +; const void mouse_static_stddrv[]; +; + + .import _cx16_std_mou + + .export _mouse_static_stddrv := _cx16_std_mou diff --git a/libsrc/cx16/mouse_stddrv.s b/libsrc/cx16/mouse_stddrv.s new file mode 100644 index 00000000..d708bb66 --- /dev/null +++ b/libsrc/cx16/mouse_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard mouse driver +; +; 2019-11-08, Greg King +; +; const char mouse_stddrv[]; +; + + .export _mouse_stddrv + +.rodata + +_mouse_stddrv: .asciiz "cx16-std.mou" -- 2.26.0