Used a library-reference method to calibrate lightpen drivers.
The mouse reference is a pointer. If it's NULL, the driver uses a default. If it's non-NULL, then it points to a function that the driver can call. That function will adjust the driver's calibration value. It could ask the user to adjust the pen; or, it could read a file that holds a value from a previous calibration. Application writers can choose how it's done: a function that's provided by the library, a custom function, or nothing.
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003-2011, Ullrich von Bassewitz */
|
/* (C) 2003-2013, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -101,6 +101,14 @@ struct mouse_callbacks {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Declarations */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The default mouse callbacks */
|
/* The default mouse callbacks */
|
||||||
extern const struct mouse_callbacks mouse_def_callbacks;
|
extern const struct mouse_callbacks mouse_def_callbacks;
|
||||||
|
|
||||||
@@ -110,6 +118,13 @@ extern const char mouse_stddrv[];
|
|||||||
/* The address of the static standard mouse driver for a platform */
|
/* The address of the static standard mouse driver for a platform */
|
||||||
extern const void mouse_static_stddrv[];
|
extern const void mouse_static_stddrv[];
|
||||||
|
|
||||||
|
/* A program optionally can set this pointer to a function that gives
|
||||||
|
** a calibration value to a driver. If this pointer isn't NULL,
|
||||||
|
** then a driver that wants a value can call that function.
|
||||||
|
** mouse_adjuster must be set before the driver is installed.
|
||||||
|
*/
|
||||||
|
extern void __fastcall__ (*mouse_adjuster) (unsigned char *pValue);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -127,10 +142,10 @@ unsigned char mouse_unload (void);
|
|||||||
|
|
||||||
unsigned char __fastcall__ mouse_install (const struct mouse_callbacks* c,
|
unsigned char __fastcall__ mouse_install (const struct mouse_callbacks* c,
|
||||||
void* driver);
|
void* driver);
|
||||||
/* Install an already loaded driver. Returns an error code. */
|
/* Install an already loaded driver. Return an error code. */
|
||||||
|
|
||||||
unsigned char mouse_uninstall (void);
|
unsigned char mouse_uninstall (void);
|
||||||
/* Uninstall the currently loaded driver. Returns an error code. */
|
/* Uninstall the currently loaded driver. Return an error code. */
|
||||||
|
|
||||||
const char* __fastcall__ mouse_geterrormsg (unsigned char code);
|
const char* __fastcall__ mouse_geterrormsg (unsigned char code);
|
||||||
/* Get an error message describing the error in code. */
|
/* Get an error message describing the error in code. */
|
||||||
@@ -142,7 +157,7 @@ void mouse_hide (void);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void mouse_show (void);
|
void mouse_show (void);
|
||||||
/* Show the mouse. See mouse_hide for more information. */
|
/* Show the mouse. See mouse_hide() for more information. */
|
||||||
|
|
||||||
void __fastcall__ mouse_setbox (const struct mouse_box* box);
|
void __fastcall__ mouse_setbox (const struct mouse_box* box);
|
||||||
/* Set the bounding box for the mouse pointer movement. The mouse X and Y
|
/* Set the bounding box for the mouse pointer movement. The mouse X and Y
|
||||||
@@ -176,14 +191,31 @@ unsigned char mouse_buttons (void);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void __fastcall__ mouse_pos (struct mouse_pos* pos);
|
void __fastcall__ mouse_pos (struct mouse_pos* pos);
|
||||||
/* Return the current mouse position */
|
/* Return the current mouse position. */
|
||||||
|
|
||||||
void __fastcall__ mouse_info (struct mouse_info* info);
|
void __fastcall__ mouse_info (struct mouse_info* info);
|
||||||
/* Return the state of the mouse buttons and the position of the mouse */
|
/* Return the state of the mouse buttons and the position of the mouse. */
|
||||||
|
|
||||||
unsigned char __fastcall__ mouse_ioctl (unsigned char code, void* data);
|
unsigned char __fastcall__ mouse_ioctl (unsigned char code, void* data);
|
||||||
/* Call the driver specific ioctl function. NON PORTABLE! Returns an error
|
/* Call the driver-specific ioctl function. Return an error code.
|
||||||
* code.
|
* NON-PORTABLE!
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __fastcall__ pen_calibrate (unsigned char *XOffset);
|
||||||
|
/* Ask the user to help to calibrate a lightpen. Changes the screen!
|
||||||
|
* A pointer to this function can be put into mouse_adjuster.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __fastcall__ pen_adjust (const char *filename);
|
||||||
|
/* Get a lightpen calibration value from a file if it exists. Otherwise, call
|
||||||
|
* pen_calibrate() to create a value; then, write it into a file, so that it
|
||||||
|
* will be available at the next time that the lightpen is used.
|
||||||
|
* Might change the screen.
|
||||||
|
* pen_adjust() is optional; if you want to use its feature,
|
||||||
|
* then it must be called before a driver is installed.
|
||||||
|
* Note: This function merely saves the file-name pointer, and sets
|
||||||
|
* the mouse_adjuster pointer. The file will be read only when a driver
|
||||||
|
* is installed, and only if that driver wants to be calibrated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
;
|
;
|
||||||
; Oliver Schmidt, 2013-05-31
|
; 2013-05-31, Oliver Schmidt
|
||||||
|
; 2013-06-11, Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.export em_libref, joy_libref, mouse_libref, ser_libref, tgi_libref
|
.export em_libref
|
||||||
|
.export joy_libref
|
||||||
|
; .export mouse_libref
|
||||||
|
.export ser_libref
|
||||||
|
.export tgi_libref
|
||||||
|
|
||||||
.import _exit
|
.import _exit
|
||||||
|
|
||||||
em_libref := _exit
|
em_libref := _exit
|
||||||
joy_libref := _exit
|
joy_libref := _exit
|
||||||
mouse_libref := _exit
|
;mouse_libref := _exit
|
||||||
ser_libref := _exit
|
ser_libref := _exit
|
||||||
tgi_libref := _exit
|
tgi_libref := _exit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
;
|
;
|
||||||
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
|
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
|
||||||
;
|
;
|
||||||
; 2013-06-03, Greg King
|
; 2013-06-17, Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
.include "c128.inc"
|
.include "c128.inc"
|
||||||
|
|
||||||
.macpack generic
|
.macpack generic
|
||||||
.macpack cbm
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Header. Includes jump table.
|
; Header. Includes jump table.
|
||||||
@@ -25,7 +24,7 @@ HEADER:
|
|||||||
|
|
||||||
; Library reference
|
; Library reference
|
||||||
|
|
||||||
.addr $0000
|
LIBREF: .addr $0000
|
||||||
|
|
||||||
; Jump table
|
; Jump table
|
||||||
|
|
||||||
@@ -62,14 +61,8 @@ CMOVEY: jmp $0000 ; Move the cursor to Y co-ord.
|
|||||||
XSIZE = 40
|
XSIZE = 40
|
||||||
YSIZE = 25
|
YSIZE = 25
|
||||||
|
|
||||||
SCREEN_HEIGHT = YSIZE * 8
|
|
||||||
SCREEN_WIDTH = XSIZE * 8
|
SCREEN_WIDTH = XSIZE * 8
|
||||||
SCREEN_ZONE = YSIZE / 4 * XSIZE
|
SCREEN_HEIGHT = YSIZE * 8
|
||||||
|
|
||||||
SCREEN := $0400
|
|
||||||
COLOR_RAM := $D800
|
|
||||||
|
|
||||||
PRIMM := $FF7D ; Print immediate
|
|
||||||
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
@@ -77,6 +70,19 @@ PRIMM := $FF7D ; Print immediate
|
|||||||
; written with the least effort in the SETBOX and GETBOX routines; so, don't
|
; written with the least effort in the SETBOX and GETBOX routines; so, don't
|
||||||
; re-order them.
|
; re-order them.
|
||||||
|
|
||||||
|
.rodata
|
||||||
|
|
||||||
|
; Default values for below variables
|
||||||
|
; (We use ".proc" because we want to define both a label and a scope.)
|
||||||
|
|
||||||
|
.proc DefVars
|
||||||
|
.word 0 ; XMin
|
||||||
|
.word 0 ; YMin
|
||||||
|
.word SCREEN_WIDTH - 1 ; XMax
|
||||||
|
.word SCREEN_HEIGHT - 1 ; YMax
|
||||||
|
.byte %00000000 ; Buttons
|
||||||
|
.endproc
|
||||||
|
|
||||||
.bss
|
.bss
|
||||||
|
|
||||||
Vars:
|
Vars:
|
||||||
@@ -89,36 +95,21 @@ Buttons: .res 1 ; Button status bits
|
|||||||
XPos: .res 2 ; Current lightpen position, X
|
XPos: .res 2 ; Current lightpen position, X
|
||||||
YPos: .res 2 ; Current lightpen position, Y
|
YPos: .res 2 ; Current lightpen position, Y
|
||||||
|
|
||||||
OldPenX: .res 1 ; Old HW-counter values
|
OldPenX: .res 1 ; Previous HW-counter values
|
||||||
OldPenY: .res 1
|
OldPenY: .res 1
|
||||||
|
|
||||||
INIT_save: .res 1
|
INIT_save: .res 1
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
; Start with an average offset.
|
; Default Inkwell calibration.
|
||||||
|
; The first number is the width of the left border;
|
||||||
|
; the second number is the actual calibration value.
|
||||||
|
|
||||||
XOffset: .byte 48 / 2 ; Calibration offset, for X position
|
XOffset: .byte (24 + 24) / 2 ; x-offset
|
||||||
|
|
||||||
.rodata
|
; Jump to a function that puts a new calibration value into XOffset.
|
||||||
|
Calibrate: jmp $0000
|
||||||
; Default values for above variables
|
|
||||||
; (We use ".proc" because we want to define both a label and a scope.)
|
|
||||||
|
|
||||||
.proc DefVars
|
|
||||||
.word 0 ; XMin
|
|
||||||
.word 0 ; YMin
|
|
||||||
.word SCREEN_WIDTH - 1 ; XMax
|
|
||||||
.word SCREEN_HEIGHT - 1 ; YMax
|
|
||||||
.byte %00000000 ; Buttons
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
.proc Command1
|
|
||||||
scrcode "Adjust by clicking on line."
|
|
||||||
.endproc
|
|
||||||
.proc Command2
|
|
||||||
scrcode "Finish by clicking off box."
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
.code
|
.code
|
||||||
@@ -138,15 +129,8 @@ INSTALL:
|
|||||||
lda #%11000000
|
lda #%11000000
|
||||||
sta INIT_STATUS
|
sta INIT_STATUS
|
||||||
|
|
||||||
bit MODE
|
|
||||||
bpl @L7 ; Already 40 columns
|
|
||||||
jsr PRIMM
|
|
||||||
.byte $1B, 'x' ; Toggle the screen-width mode
|
|
||||||
.byte $0E, $00 ; Switch to lower-case chars.
|
|
||||||
|
|
||||||
; Initiate variables. Just copy the default stuff over.
|
; Initiate variables. Just copy the default stuff over.
|
||||||
|
|
||||||
@L7: sei
|
|
||||||
ldx #.sizeof (DefVars) - 1
|
ldx #.sizeof (DefVars) - 1
|
||||||
@L0: lda DefVars,x
|
@L0: lda DefVars,x
|
||||||
sta Vars,x
|
sta Vars,x
|
||||||
@@ -157,121 +141,37 @@ INSTALL:
|
|||||||
ldy VIC_LPEN_Y
|
ldy VIC_LPEN_Y
|
||||||
stx OldPenX
|
stx OldPenX
|
||||||
sty OldPenY
|
sty OldPenY
|
||||||
cli
|
|
||||||
|
|
||||||
; There is a delay between when the VIC sends its signal, and when the display
|
; Call a calibration function through the library-reference.
|
||||||
; shows that signal. There is another delay between the display and when
|
|
||||||
; the lightpen says that it saw that signal. Each display and pen is different.
|
|
||||||
; Therefore, this driver must be calibrated to them. A white box is painted on
|
|
||||||
; the screen; and, a line is drawn down the middle of it. When the user clicks
|
|
||||||
; on that line, the difference between its position and where the VIC thinks
|
|
||||||
; that the pen is pointing becomes an offset that is subtracted from what the
|
|
||||||
; VIC sees.
|
|
||||||
|
|
||||||
lda VIC_BG_COLOR0
|
lda LIBREF
|
||||||
ldx #6 ; Blue screen
|
ldx LIBREF+1
|
||||||
stx VIC_BG_COLOR0
|
sta ptr1 ; Point to mouse_adjuster
|
||||||
pha
|
stx ptr1+1
|
||||||
jsr CLRSCR
|
ldy #0
|
||||||
|
lda (ptr1),y
|
||||||
|
sta Calibrate+1 ; Point to function
|
||||||
|
iny
|
||||||
|
lda (ptr1),y
|
||||||
|
sta Calibrate+2
|
||||||
|
ora Calibrate+1 ; Don't call pointer if it's NULL
|
||||||
|
bze @L1
|
||||||
|
lda #<XOffset ; Function will set this variable
|
||||||
|
ldx #>XOffset
|
||||||
|
jsr Calibrate
|
||||||
|
|
||||||
ldy #.sizeof (Command2) - 1
|
; Be sure that the lightpen cursor is invisible and at the default location.
|
||||||
@L2: lda Command2,y
|
|
||||||
sta SCREEN + SCREEN_ZONE * 2 + XSIZE * 3 + (XSIZE - .sizeof (Command2)) / 2,y
|
|
||||||
lda #15 ; Light gray text
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE * 2 + XSIZE * 3 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
dey
|
|
||||||
bpl @L2
|
|
||||||
ldy #.sizeof (Command1) - 1
|
|
||||||
@L1: lda Command1,y
|
|
||||||
sta SCREEN + SCREEN_ZONE * 2 + XSIZE * 1 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
lda #15 ; Light gray text
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE * 2 + XSIZE * 1 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
dey
|
|
||||||
bpl @L1
|
|
||||||
|
|
||||||
ldx #SCREEN_ZONE
|
|
||||||
@L3: lda #$80 | $20 ; Reversed space screen-code
|
|
||||||
sta SCREEN + SCREEN_ZONE - 1,x
|
|
||||||
lda #15 ; Light gray box
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE - 1,x
|
|
||||||
dex
|
|
||||||
bnz @L3
|
|
||||||
|
|
||||||
ldy #$80 | $5d ; Reversed vertical-bar screen-code
|
|
||||||
.repeat 4, L
|
|
||||||
sty SCREEN + SCREEN_ZONE + (L + 1) * XSIZE + XSIZE / 2
|
|
||||||
.endrep
|
|
||||||
|
|
||||||
lda VIC_SPR0_COLOR
|
|
||||||
ldx #12 ; Medium gray pointer
|
|
||||||
stx VIC_SPR0_COLOR
|
|
||||||
pha
|
|
||||||
jsr SHOW
|
|
||||||
|
|
||||||
lda #<(SCREEN_HEIGHT / 4 / 2)
|
|
||||||
ldx #>(SCREEN_HEIGHT / 4 / 2)
|
|
||||||
jsr PutCursor
|
|
||||||
|
|
||||||
; Wait for the main button to be released.
|
|
||||||
|
|
||||||
@L4: lda Buttons
|
|
||||||
bnz @L4
|
|
||||||
|
|
||||||
; Wait for the main button to be pressed.
|
|
||||||
|
|
||||||
@L5: lda Buttons
|
|
||||||
bze @L5
|
|
||||||
|
|
||||||
; Find out if the pen is on or off the box.
|
|
||||||
|
|
||||||
ldy YPos
|
|
||||||
ldx YPos+1
|
|
||||||
txa
|
|
||||||
cpy #<(YSIZE / 4 * 1 * 8)
|
|
||||||
sbc #>(YSIZE / 4 * 1 * 8)
|
|
||||||
bmi @L6 ; Above box
|
|
||||||
txa
|
|
||||||
cpy #<(YSIZE / 4 * 2 * 8)
|
|
||||||
sbc #>(YSIZE / 4 * 2 * 8)
|
|
||||||
bpl @L6 ; Below box
|
|
||||||
|
|
||||||
; The pen is on the box; adjust the offset.
|
|
||||||
|
|
||||||
lda OldPenX
|
|
||||||
sub #(XSIZE * 8 / 2 + 8/2) / 2
|
|
||||||
sta XOffset
|
|
||||||
sta OldPenX ; Make IRQ update X co-ordinate
|
|
||||||
jmp @L4
|
|
||||||
|
|
||||||
; Wait for the main button to be released.
|
|
||||||
|
|
||||||
@L6: lda Buttons
|
|
||||||
bnz @L6
|
|
||||||
|
|
||||||
lda XOffset ; Tell test program about calibration
|
|
||||||
sta $3ff
|
|
||||||
|
|
||||||
pla
|
|
||||||
sta VIC_SPR0_COLOR
|
|
||||||
pla
|
|
||||||
sta VIC_BG_COLOR0
|
|
||||||
jsr CLRSCR
|
|
||||||
|
|
||||||
; Be sure the lightpen cursor is invisible and at the default location.
|
|
||||||
; It needs to be done here because the lightpen interrupt handler doesn't
|
; It needs to be done here because the lightpen interrupt handler doesn't
|
||||||
; set the lightpen position if it hasn't changed.
|
; set the lightpen position if it hasn't changed.
|
||||||
|
|
||||||
jsr HIDE
|
@L1: jsr CHIDE
|
||||||
|
|
||||||
lda #<(SCREEN_HEIGHT / 2)
|
lda #<(SCREEN_HEIGHT / 2)
|
||||||
ldx #>(SCREEN_HEIGHT / 2)
|
ldx #>(SCREEN_HEIGHT / 2)
|
||||||
PutCursor:
|
|
||||||
sei
|
|
||||||
jsr MoveY
|
jsr MoveY
|
||||||
lda #<(SCREEN_WIDTH / 2)
|
lda #<(SCREEN_WIDTH / 2)
|
||||||
ldx #>(SCREEN_WIDTH / 2)
|
ldx #>(SCREEN_WIDTH / 2)
|
||||||
jsr MoveX
|
jsr MoveX
|
||||||
cli
|
|
||||||
|
|
||||||
; Done, return zero.
|
; Done, return zero.
|
||||||
|
|
||||||
@@ -504,11 +404,11 @@ IRQ:
|
|||||||
beq @SkipX
|
beq @SkipX
|
||||||
sta OldPenX
|
sta OldPenX
|
||||||
|
|
||||||
; Adjust the co-ordinate by the calibration offset.
|
; Adjust the value by the calibration offset.
|
||||||
|
|
||||||
sub XOffset
|
sub XOffset
|
||||||
|
|
||||||
; Calculate the new X co-ordinate (--> .AY --> .XY).
|
; Calculate the new X co-ordinate.
|
||||||
; The VIC-II register is eight bits; but, the screen co-ordinate is nine bits.
|
; The VIC-II register is eight bits; but, the screen co-ordinate is nine bits.
|
||||||
; Therefore, the VIC-II number is doubled. Then, it points to every other pixel;
|
; Therefore, the VIC-II number is doubled. Then, it points to every other pixel;
|
||||||
; but, it can reach across the screen.
|
; but, it can reach across the screen.
|
||||||
@@ -517,7 +417,7 @@ IRQ:
|
|||||||
tay ; Remember low byte
|
tay ; Remember low byte
|
||||||
lda #>0
|
lda #>0
|
||||||
rol a
|
rol a
|
||||||
tax
|
tax ; Remember high byte
|
||||||
|
|
||||||
; Limit the X co-ordinate to the bounding box.
|
; Limit the X co-ordinate to the bounding box.
|
||||||
|
|
||||||
|
|||||||
23
libsrc/c128/mouseref.s
Normal file
23
libsrc/c128/mouseref.s
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
;
|
||||||
|
; Pointer for library references by device drivers.
|
||||||
|
;
|
||||||
|
; 2013-06-23, Greg King
|
||||||
|
;
|
||||||
|
|
||||||
|
.export mouse_libref, _mouse_adjuster
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
mouse_libref: ; generic label for mouse-kernel
|
||||||
|
|
||||||
|
; A program optionally can set this pointer to a function that gives
|
||||||
|
; a calibration value to a driver. If this pointer isn't NULL,
|
||||||
|
; then a driver that wants a value can call that function.
|
||||||
|
;
|
||||||
|
; The function might read a value from a file; or, it might ask the user
|
||||||
|
; to help calibrate the driver.
|
||||||
|
;
|
||||||
|
; void __fastcall__ (*mouse_adjuster)(unsigned char *) = NULL;
|
||||||
|
;
|
||||||
|
_mouse_adjuster:
|
||||||
|
.addr $0000
|
||||||
92
libsrc/c128/pencalib.c
Normal file
92
libsrc/c128/pencalib.c
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
** Calibrate lightpen drivers to the current video hardware.
|
||||||
|
**
|
||||||
|
** 2013-06-17, Greg King
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define COMMAND1 "Adjust by clicking on line."
|
||||||
|
#define COMMAND2 "Finish by clicking off bar."
|
||||||
|
|
||||||
|
|
||||||
|
/* There is a delay between when the VIC sends its signal, and when the display
|
||||||
|
** shows that signal. There is another delay between the display and when the
|
||||||
|
** lightpen says that it saw that signal. Each display and pen is different.
|
||||||
|
** Therefore, the driver must be calibrated to them. A white bar is painted on
|
||||||
|
** the screen; and, a line is drawn down the middle of it. When the user
|
||||||
|
** clicks on that line, the difference between its position and where the VIC
|
||||||
|
** thinks that the pen is pointing becomes an offset that is subtracted from
|
||||||
|
** what the VIC sees.
|
||||||
|
*/
|
||||||
|
void __fastcall__ pen_calibrate (unsigned char *XOffset)
|
||||||
|
{
|
||||||
|
unsigned char oldBg = bgcolor (COLOR_BLUE);
|
||||||
|
unsigned char oldText = textcolor (COLOR_GRAY3);
|
||||||
|
unsigned char oldRev = revers (1);
|
||||||
|
unsigned char sprite0Color = VIC.spr_color[0];
|
||||||
|
unsigned char width, width2, height, height4, height8;
|
||||||
|
struct mouse_info info;
|
||||||
|
|
||||||
|
screensize (&width, &height);
|
||||||
|
width2 = width / 2;
|
||||||
|
height4 = height / 4;
|
||||||
|
height8 = height4 * 8;
|
||||||
|
|
||||||
|
/* Draw a bar and line. */
|
||||||
|
|
||||||
|
clrscr ();
|
||||||
|
cclearxy (0, height4, height4 * width);
|
||||||
|
cvlinexy (width2, height4 + 1, height4 - 2);
|
||||||
|
|
||||||
|
/* Print instructions. */
|
||||||
|
|
||||||
|
revers (0);
|
||||||
|
cputsxy (width2 - (sizeof COMMAND1) / 2, height / 2 + 1, COMMAND1);
|
||||||
|
cputsxy (width2 - (sizeof COMMAND2) / 2, height / 2 + 3, COMMAND2);
|
||||||
|
|
||||||
|
VIC.spr_color[0] = COLOR_GRAY2;
|
||||||
|
mouse_show ();
|
||||||
|
mouse_move (width2 * 8, height8 / 2);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* Wait for the main button to be released. */
|
||||||
|
|
||||||
|
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
/* Wait for the main button to be pressed. */
|
||||||
|
|
||||||
|
do {
|
||||||
|
mouse_info (&info);
|
||||||
|
} while (!(info.buttons & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
/* Find out if the pen is on or off the bar. */
|
||||||
|
|
||||||
|
if (info.pos.y < height8 || info.pos.y >= height8 * 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* On the bar; adjust the offset. */
|
||||||
|
/* Characters are eight pixels wide.
|
||||||
|
** The VIC-II sees every other pixel;
|
||||||
|
** so, we use half of the difference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*XOffset += (info.pos.x - (width2 * 8 + 8/2)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Off the bar; wait for the main button to be released. */
|
||||||
|
|
||||||
|
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
mouse_hide ();
|
||||||
|
VIC.spr_color[0] = sprite0Color;
|
||||||
|
revers (oldRev);
|
||||||
|
textcolor (oldText);
|
||||||
|
bgcolor (oldBg);
|
||||||
|
clrscr ();
|
||||||
|
}
|
||||||
@@ -1,12 +1,18 @@
|
|||||||
;
|
;
|
||||||
; Oliver Schmidt, 2013-05-31
|
; 2013-05-31, Oliver Schmidt
|
||||||
|
; 2013-06-11, Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.export em_libref, joy_libref, mouse_libref, ser_libref, tgi_libref
|
.export em_libref
|
||||||
|
.export joy_libref
|
||||||
|
; .export mouse_libref
|
||||||
|
.export ser_libref
|
||||||
|
.export tgi_libref
|
||||||
|
|
||||||
.import _exit
|
.import _exit
|
||||||
|
|
||||||
em_libref := _exit
|
em_libref := _exit
|
||||||
joy_libref := _exit
|
joy_libref := _exit
|
||||||
mouse_libref := _exit
|
;mouse_libref := _exit
|
||||||
ser_libref := _exit
|
ser_libref := _exit
|
||||||
tgi_libref := _exit
|
tgi_libref := _exit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
;
|
;
|
||||||
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
|
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
|
||||||
;
|
;
|
||||||
; 2013-06-03, Greg King
|
; 2013-06-17, Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
.include "c64.inc"
|
.include "c64.inc"
|
||||||
|
|
||||||
.macpack generic
|
.macpack generic
|
||||||
.macpack cbm
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Header. Includes jump table.
|
; Header. Includes jump table.
|
||||||
@@ -25,7 +24,7 @@ HEADER:
|
|||||||
|
|
||||||
; Library reference
|
; Library reference
|
||||||
|
|
||||||
.addr $0000
|
LIBREF: .addr $0000
|
||||||
|
|
||||||
; Jump table
|
; Jump table
|
||||||
|
|
||||||
@@ -57,14 +56,8 @@ CMOVEY: jmp $0000 ; Move the cursor to Y co-ord.
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
; Constants
|
; Constants
|
||||||
|
|
||||||
SCREEN_HEIGHT = YSIZE * 8
|
|
||||||
SCREEN_WIDTH = XSIZE * 8
|
SCREEN_WIDTH = XSIZE * 8
|
||||||
SCREEN_ZONE = YSIZE / 4 * XSIZE
|
SCREEN_HEIGHT = YSIZE * 8
|
||||||
|
|
||||||
; This driver is for the standard 40-column screen.
|
|
||||||
|
|
||||||
SCREEN := $0400
|
|
||||||
COLOR_RAM := $D800
|
|
||||||
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
@@ -72,29 +65,9 @@ COLOR_RAM := $D800
|
|||||||
; written with the least effort in the SETBOX and GETBOX routines; so, don't
|
; written with the least effort in the SETBOX and GETBOX routines; so, don't
|
||||||
; re-order them.
|
; re-order them.
|
||||||
|
|
||||||
.bss
|
|
||||||
|
|
||||||
Vars:
|
|
||||||
XMin: .res 2 ; X1 value of bounding box
|
|
||||||
YMin: .res 2 ; Y1 value of bounding box
|
|
||||||
XMax: .res 2 ; X2 value of bounding box
|
|
||||||
YMax: .res 2 ; Y2 value of bounding box
|
|
||||||
Buttons: .res 1 ; Button status bits
|
|
||||||
XPos: .res 2 ; Current lightpen position, X
|
|
||||||
YPos: .res 2 ; Current lightpen position, Y
|
|
||||||
|
|
||||||
OldPenX: .res 1 ; Old HW-counter values
|
|
||||||
OldPenY: .res 1
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
; Start with an average offset.
|
|
||||||
|
|
||||||
XOffset: .byte 48 / 2 ; Calibration offset, for X position
|
|
||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
|
|
||||||
; Default values for above variables
|
; Default values for below variables
|
||||||
; (We use ".proc" because we want to define both a label and a scope.)
|
; (We use ".proc" because we want to define both a label and a scope.)
|
||||||
|
|
||||||
.proc DefVars
|
.proc DefVars
|
||||||
@@ -105,12 +78,31 @@ XOffset: .byte 48 / 2 ; Calibration offset, for X position
|
|||||||
.byte %00000000 ; Buttons
|
.byte %00000000 ; Buttons
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
.proc Command1
|
.bss
|
||||||
scrcode "Adjust by clicking on line."
|
|
||||||
.endproc
|
Vars:
|
||||||
.proc Command2
|
XMin: .res 2 ; X1 value of bounding box
|
||||||
scrcode "Finish by clicking off box."
|
YMin: .res 2 ; Y1 value of bounding box
|
||||||
.endproc
|
XMax: .res 2 ; X2 value of bounding box
|
||||||
|
YMax: .res 2 ; Y2 value of bounding box
|
||||||
|
Buttons: .res 1 ; Button status bits
|
||||||
|
|
||||||
|
XPos: .res 2 ; Current lightpen position, X
|
||||||
|
YPos: .res 2 ; Current lightpen position, Y
|
||||||
|
|
||||||
|
OldPenX: .res 1 ; Previous HW-counter values
|
||||||
|
OldPenY: .res 1
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
; Default Inkwell calibration.
|
||||||
|
; The first number is the width of the left border;
|
||||||
|
; the second number is the actual calibration value.
|
||||||
|
|
||||||
|
XOffset: .byte (24 + 24) / 2 ; x-offset
|
||||||
|
|
||||||
|
; Jump to a function that puts a new calibration value into XOffset.
|
||||||
|
Calibrate: jmp $0000
|
||||||
|
|
||||||
|
|
||||||
.code
|
.code
|
||||||
@@ -124,7 +116,6 @@ INSTALL:
|
|||||||
|
|
||||||
; Initiate variables. Just copy the default stuff over.
|
; Initiate variables. Just copy the default stuff over.
|
||||||
|
|
||||||
sei
|
|
||||||
ldx #.sizeof (DefVars) - 1
|
ldx #.sizeof (DefVars) - 1
|
||||||
@L0: lda DefVars,x
|
@L0: lda DefVars,x
|
||||||
sta Vars,x
|
sta Vars,x
|
||||||
@@ -135,121 +126,37 @@ INSTALL:
|
|||||||
ldy VIC_LPEN_Y
|
ldy VIC_LPEN_Y
|
||||||
stx OldPenX
|
stx OldPenX
|
||||||
sty OldPenY
|
sty OldPenY
|
||||||
cli
|
|
||||||
|
|
||||||
; There is a delay between when the VIC sends its signal, and when the display
|
; Call a calibration function through the library-reference.
|
||||||
; shows that signal. There is another delay between the display and when
|
|
||||||
; the lightpen says that it saw that signal. Each display and pen is different.
|
|
||||||
; Therefore, this driver must be calibrated to them. A white box is painted on
|
|
||||||
; the screen; and, a line is drawn down the middle of it. When the user clicks
|
|
||||||
; on that line, the difference between its position and where the VIC thinks
|
|
||||||
; that the pen is pointing becomes an offset that is subtracted from what the
|
|
||||||
; VIC sees.
|
|
||||||
|
|
||||||
lda VIC_BG_COLOR0
|
lda LIBREF
|
||||||
ldx #6 ; Blue screen
|
ldx LIBREF+1
|
||||||
stx VIC_BG_COLOR0
|
sta ptr1 ; Point to mouse_adjuster
|
||||||
pha
|
stx ptr1+1
|
||||||
jsr CLRSCR
|
ldy #0
|
||||||
|
lda (ptr1),y
|
||||||
|
sta Calibrate+1 ; Point to function
|
||||||
|
iny
|
||||||
|
lda (ptr1),y
|
||||||
|
sta Calibrate+2
|
||||||
|
ora Calibrate+1 ; Don't call pointer if it's NULL
|
||||||
|
bze @L1
|
||||||
|
lda #<XOffset ; Function will set this variable
|
||||||
|
ldx #>XOffset
|
||||||
|
jsr Calibrate
|
||||||
|
|
||||||
ldy #.sizeof (Command2) - 1
|
; Be sure that the lightpen cursor is invisible and at the default location.
|
||||||
@L2: lda Command2,y
|
|
||||||
sta SCREEN + SCREEN_ZONE * 2 + XSIZE * 3 + (XSIZE - .sizeof (Command2)) / 2,y
|
|
||||||
lda #15 ; Light gray text
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE * 2 + XSIZE * 3 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
dey
|
|
||||||
bpl @L2
|
|
||||||
ldy #.sizeof (Command1) - 1
|
|
||||||
@L1: lda Command1,y
|
|
||||||
sta SCREEN + SCREEN_ZONE * 2 + XSIZE * 1 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
lda #15 ; Light gray text
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE * 2 + XSIZE * 1 + (XSIZE - .sizeof (Command1)) / 2,y
|
|
||||||
dey
|
|
||||||
bpl @L1
|
|
||||||
|
|
||||||
ldx #SCREEN_ZONE
|
|
||||||
@L3: lda #$80 | $20 ; Reversed space screen-code
|
|
||||||
sta SCREEN + SCREEN_ZONE - 1,x
|
|
||||||
lda #15 ; Light gray box
|
|
||||||
sta COLOR_RAM + SCREEN_ZONE - 1,x
|
|
||||||
dex
|
|
||||||
bnz @L3
|
|
||||||
|
|
||||||
ldy #$80 | $5d ; Reversed vertical-bar screen-code
|
|
||||||
.repeat 4, L
|
|
||||||
sty SCREEN + SCREEN_ZONE + (L + 1) * XSIZE + XSIZE / 2
|
|
||||||
.endrep
|
|
||||||
|
|
||||||
lda VIC_SPR0_COLOR
|
|
||||||
ldx #12 ; Medium gray pointer
|
|
||||||
stx VIC_SPR0_COLOR
|
|
||||||
pha
|
|
||||||
jsr SHOW
|
|
||||||
|
|
||||||
lda #<(SCREEN_HEIGHT / 4 / 2)
|
|
||||||
ldx #>(SCREEN_HEIGHT / 4 / 2)
|
|
||||||
jsr PutCursor
|
|
||||||
|
|
||||||
; Wait for the main button to be released.
|
|
||||||
|
|
||||||
@L4: lda Buttons
|
|
||||||
bnz @L4
|
|
||||||
|
|
||||||
; Wait for the main button to be pressed.
|
|
||||||
|
|
||||||
@L5: lda Buttons
|
|
||||||
bze @L5
|
|
||||||
|
|
||||||
; Find out if the pen is on or off the box.
|
|
||||||
|
|
||||||
ldy YPos
|
|
||||||
ldx YPos+1
|
|
||||||
txa
|
|
||||||
cpy #<(YSIZE / 4 * 1 * 8)
|
|
||||||
sbc #>(YSIZE / 4 * 1 * 8)
|
|
||||||
bmi @L6 ; Above box
|
|
||||||
txa
|
|
||||||
cpy #<(YSIZE / 4 * 2 * 8)
|
|
||||||
sbc #>(YSIZE / 4 * 2 * 8)
|
|
||||||
bpl @L6 ; Below box
|
|
||||||
|
|
||||||
; The pen is on the box; adjust the offset.
|
|
||||||
|
|
||||||
lda OldPenX
|
|
||||||
sub #(XSIZE * 8 / 2 + 8/2) / 2
|
|
||||||
sta XOffset
|
|
||||||
sta OldPenX ; Make IRQ update X co-ordinate
|
|
||||||
jmp @L4
|
|
||||||
|
|
||||||
; Wait for the main button to be released.
|
|
||||||
|
|
||||||
@L6: lda Buttons
|
|
||||||
bnz @L6
|
|
||||||
|
|
||||||
lda XOffset ; Tell test program about calibration
|
|
||||||
sta $3ff
|
|
||||||
|
|
||||||
pla
|
|
||||||
sta VIC_SPR0_COLOR
|
|
||||||
pla
|
|
||||||
sta VIC_BG_COLOR0
|
|
||||||
jsr CLRSCR
|
|
||||||
|
|
||||||
; Be sure the lightpen cursor is invisible and at the default location.
|
|
||||||
; It needs to be done here because the lightpen interrupt handler doesn't
|
; It needs to be done here because the lightpen interrupt handler doesn't
|
||||||
; set the lightpen position if it hasn't changed.
|
; set the lightpen position if it hasn't changed.
|
||||||
|
|
||||||
jsr HIDE
|
@L1: jsr CHIDE
|
||||||
|
|
||||||
lda #<(SCREEN_HEIGHT / 2)
|
lda #<(SCREEN_HEIGHT / 2)
|
||||||
ldx #>(SCREEN_HEIGHT / 2)
|
ldx #>(SCREEN_HEIGHT / 2)
|
||||||
PutCursor:
|
|
||||||
sei
|
|
||||||
jsr MoveY
|
jsr MoveY
|
||||||
lda #<(SCREEN_WIDTH / 2)
|
lda #<(SCREEN_WIDTH / 2)
|
||||||
ldx #>(SCREEN_WIDTH / 2)
|
ldx #>(SCREEN_WIDTH / 2)
|
||||||
jsr MoveX
|
jsr MoveX
|
||||||
cli
|
|
||||||
|
|
||||||
; Done, return zero.
|
; Done, return zero.
|
||||||
|
|
||||||
@@ -478,20 +385,20 @@ IRQ:
|
|||||||
beq @SkipX
|
beq @SkipX
|
||||||
sta OldPenX
|
sta OldPenX
|
||||||
|
|
||||||
; Adjust the co-ordinate by the calibration offset.
|
; Adjust the value by the calibration offset.
|
||||||
|
|
||||||
sub XOffset
|
sub XOffset
|
||||||
|
|
||||||
; Calculate the new X co-ordinate (--> .AY --> .XY).
|
; Calculate the new X co-ordinate.
|
||||||
; The VIC-II register is eight bits; but, the screen co-ordinate is nine bits.
|
; The VIC-II register is eight bits; but, the screen co-ordinate is nine bits.
|
||||||
; Therefor, the VIC-II number is doubled. Then, it points to every other pixel;
|
; Therefore, the VIC-II number is doubled. Then, it points to every other pixel;
|
||||||
; but, it can reach across the screen.
|
; but, it can reach across the screen.
|
||||||
|
|
||||||
asl a
|
asl a
|
||||||
tay ; Remember low byte
|
tay ; Remember low byte
|
||||||
lda #>0
|
lda #>0
|
||||||
rol a
|
rol a
|
||||||
tax
|
tax ; Remember high byte
|
||||||
|
|
||||||
; Limit the X co-ordinate to the bounding box.
|
; Limit the X co-ordinate to the bounding box.
|
||||||
|
|
||||||
|
|||||||
23
libsrc/c64/mouseref.s
Normal file
23
libsrc/c64/mouseref.s
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
;
|
||||||
|
; Pointer for library references by device drivers.
|
||||||
|
;
|
||||||
|
; 2013-06-23, Greg King
|
||||||
|
;
|
||||||
|
|
||||||
|
.export mouse_libref, _mouse_adjuster
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
mouse_libref: ; generic label for mouse-kernel
|
||||||
|
|
||||||
|
; A program optionally can set this pointer to a function that gives
|
||||||
|
; a calibration value to a driver. If this pointer isn't NULL,
|
||||||
|
; then a driver that wants a value can call that function.
|
||||||
|
;
|
||||||
|
; The function might read a value from a file; or, it might ask the user
|
||||||
|
; to help calibrate the driver.
|
||||||
|
;
|
||||||
|
; void __fastcall__ (*mouse_adjuster)(unsigned char *) = NULL;
|
||||||
|
;
|
||||||
|
_mouse_adjuster:
|
||||||
|
.addr $0000
|
||||||
93
libsrc/c64/pencalib.c
Normal file
93
libsrc/c64/pencalib.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
** Calibrate lightpen drivers to the current video hardware.
|
||||||
|
**
|
||||||
|
** 2013-06-17, Greg King
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define COMMAND1 "Adjust by clicking on line."
|
||||||
|
#define COMMAND2 "Finish by clicking off bar."
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** There is a delay between when the VIC sends its signal, and when the display
|
||||||
|
** shows that signal. There is another delay between the display and when
|
||||||
|
** the lightpen says that it saw that signal. Each display and pen is different.
|
||||||
|
** Therefore, the driver must be calibrated to them. A white bar is painted on
|
||||||
|
** the screen; and, a line is drawn down the middle of it. When the user clicks
|
||||||
|
** on that line, the difference between its position and where the VIC thinks
|
||||||
|
** that the pen is pointing becomes an offset that is subtracted from what the
|
||||||
|
** VIC sees.
|
||||||
|
*/
|
||||||
|
void __fastcall__ pen_calibrate (unsigned char *XOffset)
|
||||||
|
{
|
||||||
|
unsigned char oldBg = bgcolor (COLOR_BLUE);
|
||||||
|
unsigned char oldText = textcolor (COLOR_GRAY3);
|
||||||
|
unsigned char oldRev = revers (1);
|
||||||
|
unsigned char sprite0Color = VIC.spr_color[0];
|
||||||
|
unsigned char width, width2, height, height4, height8;
|
||||||
|
struct mouse_info info;
|
||||||
|
|
||||||
|
screensize (&width, &height);
|
||||||
|
width2 = width / 2;
|
||||||
|
height4 = height / 4;
|
||||||
|
height8 = height4 * 8;
|
||||||
|
|
||||||
|
/* Draw a bar and line. */
|
||||||
|
|
||||||
|
clrscr ();
|
||||||
|
cclearxy (0, height4, height4 * width);
|
||||||
|
cvlinexy (width2, height4 + 1, height4 - 2);
|
||||||
|
revers (0);
|
||||||
|
|
||||||
|
/* Print instructions. */
|
||||||
|
|
||||||
|
cputsxy (width2 - (sizeof COMMAND1) / 2, height / 2 + 1, COMMAND1);
|
||||||
|
cputsxy (width2 - (sizeof COMMAND2) / 2, height / 2 + 3, COMMAND2);
|
||||||
|
|
||||||
|
VIC.spr_color[0] = COLOR_GRAY2;
|
||||||
|
mouse_show ();
|
||||||
|
mouse_move (width2 * 8, height8 / 2);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* Wait for the main button to be released. */
|
||||||
|
|
||||||
|
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
/* Wait for the main button to be pressed. */
|
||||||
|
|
||||||
|
do {
|
||||||
|
mouse_info (&info);
|
||||||
|
} while (!(info.buttons & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
/* Find out if the pen is on or off the bar. */
|
||||||
|
|
||||||
|
if (info.pos.y < height8 || info.pos.y >= height8 * 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* On the bar; adjust the offset. */
|
||||||
|
/* Characters are eight pixels wide.
|
||||||
|
** The VIC-II sees every other pixel;
|
||||||
|
** so, we use half of the difference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*XOffset += (info.pos.x - (width2 * 8 + 8/2)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Off the bar; wait for the main button to be released. */
|
||||||
|
|
||||||
|
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
|
||||||
|
|
||||||
|
mouse_hide ();
|
||||||
|
VIC.spr_color[0] = sprite0Color;
|
||||||
|
revers (oldRev);
|
||||||
|
textcolor (oldText);
|
||||||
|
bgcolor (oldBg);
|
||||||
|
clrscr ();
|
||||||
|
}
|
||||||
53
libsrc/cbm/penadjust.c
Executable file
53
libsrc/cbm/penadjust.c
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
** Main lightpen driver calibration functions.
|
||||||
|
**
|
||||||
|
** 2013-06-23, Greg King
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char *name;
|
||||||
|
|
||||||
|
|
||||||
|
/* Get a lightpen calibration value from a file if it exists. Otherwise, call
|
||||||
|
** pen_calibrate() to create a value; then, write it into a file, so that it
|
||||||
|
** will be available at the next time that the lightpen is used.
|
||||||
|
** Might change the screen.
|
||||||
|
*/
|
||||||
|
static void __fastcall__ adjuster (unsigned char *XOffset)
|
||||||
|
{
|
||||||
|
int fd = open (name, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
pen_calibrate (XOffset);
|
||||||
|
fd = open (name, O_WRONLY | O_CREAT | O_EXCL);
|
||||||
|
if (fd >= 0) {
|
||||||
|
(void) write (fd, XOffset, 1);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(void) read (fd, XOffset, 1);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pen_adjust() is optional; if you want to use its feature,
|
||||||
|
** then it must be called before a driver is installed.
|
||||||
|
** Note: This function merely saves the file-name pointer, and sets
|
||||||
|
** the mouse_adjuster pointer. The file will be read only when a driver
|
||||||
|
** is installed, and only if that driver wants to be calibrated.
|
||||||
|
*/
|
||||||
|
void __fastcall__ pen_adjust (const char *filename)
|
||||||
|
{
|
||||||
|
if (filename != NULL && filename[0] != '\0') {
|
||||||
|
name = filename;
|
||||||
|
mouse_adjuster = adjuster;
|
||||||
|
} else {
|
||||||
|
mouse_adjuster = pen_calibrate;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
** Test program for lightpen drivers. Will work for the C64/C128.
|
** Test program for lightpen drivers. Will work for the C64/C128.
|
||||||
**
|
**
|
||||||
** 2001-09-13, Ullrich von Bassewitz
|
** 2001-09-13, Ullrich von Bassewitz
|
||||||
** 2013-05-24, Greg King
|
** 2013-06-21, Greg King
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
# define SPRITE0_PTR ((unsigned char *)0x07F8)
|
# define SPRITE0_PTR ((unsigned char *)0x07F8)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The lightpen sprite (an arrow) */
|
/* An arrow sprite */
|
||||||
static const unsigned char PenSprite[64] = {
|
static const unsigned char PenSprite[64] = {
|
||||||
0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF,
|
||||||
0xFC, 0x00, 0x00,
|
0xFC, 0x00, 0x00,
|
||||||
@@ -113,9 +113,9 @@ static void DoWarning (void)
|
|||||||
static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible)
|
static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible)
|
||||||
/* Display jail and cursor states. */
|
/* Display jail and cursor states. */
|
||||||
{
|
{
|
||||||
cclearxy (0, 7, 40);
|
cclearxy (0, 7, 32);
|
||||||
gotoxy (0, 7);
|
gotoxy (0, 7);
|
||||||
cprintf ("Lightpen cursor is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : "");
|
cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,8 +128,8 @@ int main (void)
|
|||||||
unsigned char width, height;
|
unsigned char width, height;
|
||||||
bool Invisible = false, Done = false, Jailed = false;
|
bool Invisible = false, Done = false, Jailed = false;
|
||||||
|
|
||||||
/* Only the VIC-II has a lightpen connection. */
|
|
||||||
#ifdef __C128__
|
#ifdef __C128__
|
||||||
|
/* Only the VIC-IIe has a lightpen connection. */
|
||||||
videomode (VIDEOMODE_40x25);
|
videomode (VIDEOMODE_40x25);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -154,10 +154,12 @@ int main (void)
|
|||||||
memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite);
|
memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite);
|
||||||
|
|
||||||
/* Set the VIC-II sprite pointer. */
|
/* Set the VIC-II sprite pointer. */
|
||||||
*SPRITE0_PTR = (unsigned) SPRITE0_DATA / sizeof SPRITE0_DATA;
|
*SPRITE0_PTR = ((unsigned) SPRITE0_DATA & 0x3FFF) / sizeof SPRITE0_DATA;
|
||||||
|
|
||||||
/* Set the color of sprite 0. */
|
/* Set the color of sprite 0. */
|
||||||
VIC.spr0_color = COLOR_BLACK;
|
VIC.spr0_color = COLOR_BLACK;
|
||||||
|
|
||||||
|
pen_adjust ("inkwell.dat");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DYN_DRV
|
#if DYN_DRV
|
||||||
@@ -179,20 +181,16 @@ int main (void)
|
|||||||
screensize (&width, &height);
|
screensize (&width, &height);
|
||||||
|
|
||||||
top:
|
top:
|
||||||
/* Print a help line. */
|
|
||||||
clrscr ();
|
clrscr ();
|
||||||
/* revers (1); */
|
|
||||||
cputs (" d)ebug h)ide q)uit s)how j)ail ");
|
/* Print a help line. */
|
||||||
/* revers (0); */
|
cputs (" d)ebug h)ide q)uit s)how j)ail");
|
||||||
|
|
||||||
/* Put a cross at the center of the screen. */
|
/* Put a cross at the center of the screen. */
|
||||||
gotoxy (width / 2 - 3, height / 2 - 1);
|
gotoxy (width / 2 - 3, height / 2 - 1);
|
||||||
cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4,
|
cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4,
|
||||||
width / 2, "");
|
width / 2, "");
|
||||||
|
|
||||||
/* Custom driver debugging line */
|
|
||||||
cprintf ("\n\r\n Calibration X-offset = %u", (*(unsigned char *)0x3ff) * 2);
|
|
||||||
|
|
||||||
/* Expose the arrow. */
|
/* Expose the arrow. */
|
||||||
mouse_show ();
|
mouse_show ();
|
||||||
ShowState (Jailed, Invisible);
|
ShowState (Jailed, Invisible);
|
||||||
@@ -206,8 +204,20 @@ top:
|
|||||||
gotoxy (0, 2);
|
gotoxy (0, 2);
|
||||||
cprintf (" X = %3d\r\n", info.pos.x);
|
cprintf (" X = %3d\r\n", info.pos.x);
|
||||||
cprintf (" Y = %3d\r\n", info.pos.y);
|
cprintf (" Y = %3d\r\n", info.pos.y);
|
||||||
cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? 0x5F : '^');
|
cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ?
|
||||||
cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? 0x5F : '^');
|
#ifdef __CBM__
|
||||||
|
0x5F
|
||||||
|
#else
|
||||||
|
'v'
|
||||||
|
#endif
|
||||||
|
: '^');
|
||||||
|
cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ?
|
||||||
|
#ifdef __CBM__
|
||||||
|
0x5F
|
||||||
|
#else
|
||||||
|
'v'
|
||||||
|
#endif
|
||||||
|
: '^');
|
||||||
|
|
||||||
/* Handle user input. */
|
/* Handle user input. */
|
||||||
if (kbhit ()) {
|
if (kbhit ()) {
|
||||||
@@ -277,6 +287,6 @@ top:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Say goodbye. */
|
/* Say goodbye. */
|
||||||
cputsxy (0, 16, "Goodbye!");
|
cputsxy (0, height / 2 + 3, "Goodbye!");
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user