From 051c21726ba5038134b2326872c031d52342c6af Mon Sep 17 00:00:00 2001 From: Greg King Date: Wed, 29 May 2013 19:48:45 -0400 Subject: [PATCH 01/12] Added Inkwell lightpen drivers for the C64 and the C128. They use the mouse driver programming interface. Added a test program for lightpen drivers. Now, it knows about only those two drivers; it will need updating when others are added. --- asminc/c128.inc | 7 +- asminc/c64.inc | 4 +- include/c128.h | 3 +- include/c64.h | 5 +- libsrc/c128/mou/c128-inkwell.s | 552 +++++++++++++++++++++++++++++++++ libsrc/c64/mou/c64-inkwell.s | 526 +++++++++++++++++++++++++++++++ testcode/lib/pen-test.c | 282 +++++++++++++++++ 7 files changed, 1373 insertions(+), 6 deletions(-) create mode 100644 libsrc/c128/mou/c128-inkwell.s create mode 100644 libsrc/c64/mou/c64-inkwell.s create mode 100644 testcode/lib/pen-test.c diff --git a/asminc/c128.inc b/asminc/c128.inc index 8ec72a172..1fb8b397c 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -1,5 +1,5 @@ ; -; C64 generic definitions. Stolen from Elite128 +; C128 generic definitions. Stolen from Elite128 ; @@ -32,7 +32,7 @@ FETVEC := $2AA ; Vector patch location for FETCH STASH := $2AF ; Stash routine in RAM STAVEC := $2B9 ; Vector patch location for STASH PALFLAG := $A03 ; $FF=PAL, $00=NTSC -INIT_STATUS := $A04 ; Flag: Reset/NMI Status +INIT_STATUS := $A04 ; Flags: Reset/Restore initiation status FKEY_LEN := $1000 ; Function key lengths FKEY_TEXT := $100A ; Function key texts @@ -102,6 +102,9 @@ VIC_CTRL2 := $D016 VIC_HLINE := $D012 +VIC_LPEN_X := $D013 +VIC_LPEN_Y := $D014 + VIC_VIDEO_ADR := $D018 VIC_IRR := $D019 ; Interrupt request register diff --git a/asminc/c64.inc b/asminc/c64.inc index 6823403c5..f5dbcf549 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -95,6 +95,9 @@ VIC_CTRL2 := $D016 VIC_HLINE := $D012 +VIC_LPEN_X := $D013 +VIC_LPEN_Y := $D014 + VIC_VIDEO_ADR := $D018 VIC_IRR := $D019 ; Interrupt request register @@ -207,4 +210,3 @@ TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF - diff --git a/include/c128.h b/include/c128.h index 0b005bce0..2799f8e39 100644 --- a/include/c128.h +++ b/include/c128.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2009, Ullrich von Bassewitz */ +/* (C) 1998-2013, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -131,6 +131,7 @@ extern void c128_ptvjoy_joy[]; extern void c128_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void c128_1351_mous[]; /* Referred to by mouse_static_stddrv[] */ extern void c128_joy_mou[]; +extern void c128_nkwll40_mou[]; extern void c128_pot_mou[]; extern void c128_swlink_ser[]; extern void c128_vdc_tgi[]; /* Referred to by tgi_static_stddrv[] */ diff --git a/include/c64.h b/include/c64.h index 0a4ebaf97..adf3840b9 100644 --- a/include/c64.h +++ b/include/c64.h @@ -2,11 +2,11 @@ /* */ /* c64.h */ /* */ -/* C64 system specific definitions */ +/* C64 system-specific definitions */ /* */ /* */ /* */ -/* (C) 1998-2010 Ullrich von Bassewitz */ +/* (C) 1998-2013 Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -145,6 +145,7 @@ extern void c64_ptvjoy_joy[]; extern void c64_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void c64_1351_mou[]; /* Referred to by mouse_static_stddrv[] */ extern void c64_joy_mou[]; +extern void c64_inkwell_mou[]; extern void c64_pot_mou[]; extern void c64_swlink_ser[]; extern void c64_hi_tgi[]; /* Referred to by tgi_static_stddrv[] */ diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s new file mode 100644 index 000000000..5625213b4 --- /dev/null +++ b/libsrc/c128/mou/c128-inkwell.s @@ -0,0 +1,552 @@ +; +; Driver for the Inkwell Systems 170-C and 184-C lightpens. +; +; 2013-05-18, Greg King +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "c128.inc" + + .macpack generic + .macpack cbm + +; ------------------------------------------------------------------------ +; Header. Includes jump table. + +.segment "JUMPTABLE" + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; ASCII "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; 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 MOUSE_FLAG_EARLY_IRQ + +; Callback table, set by the kernel before INSTALL is called. + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CMOVEX: jmp $0000 ; Move the cursor to X co-ord. +CMOVEY: jmp $0000 ; Move the cursor to Y co-ord. + + +;---------------------------------------------------------------------------- +; Constants + +; This driver is for the 40-column screen. + +XSIZE = 40 +YSIZE = 25 + +SCREEN_HEIGHT = YSIZE * 8 +SCREEN_WIDTH = XSIZE * 8 +SCREEN_ZONE = YSIZE / 4 * XSIZE + +SCREEN := $0400 +COLOR_RAM := $D800 + +PRIMM := $FF7D ; Print immediate + + +;---------------------------------------------------------------------------- +; Global variables. The bounding box values are sorted so that they can be +; written with the least effort in the SETBOX and GETBOX routines; so, don't +; 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 + +INIT_save: .res 1 + +.data + +; Start with an average offset. + +XOffset: .byte 48 / 2 ; Calibration offset, for X position + +.rodata + +; 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 + +;---------------------------------------------------------------------------- +; 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: + +; Disable the BASIC interpreter's interrupt-driven sprite-motion code. +; That allows direct access to the VIC-IIe's sprite registers. + + lda INIT_STATUS + sta INIT_save + lda #%11000000 + 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. + +@L7: sei + ldx #.sizeof (DefVars) - 1 +@L0: lda DefVars,x + sta Vars,x + dex + bpl @L0 + + ldx VIC_LPEN_X + ldy VIC_LPEN_Y + stx OldPenX + sty OldPenY + cli + +; 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, 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 + ldx #6 ; Blue screen + stx VIC_BG_COLOR0 + pha + jsr CLRSCR + + ldy #.sizeof (Command2) - 1 +@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 +; set the lightpen position if it hasn't changed. + + jsr HIDE + + lda #<(SCREEN_HEIGHT / 2) + ldx #>(SCREEN_HEIGHT / 2) +PutCursor: + sei + jsr MoveY + lda #<(SCREEN_WIDTH / 2) + ldx #>(SCREEN_WIDTH / 2) + jsr MoveX + cli + +; Done, return zero. + + lda #MOUSE_ERR_OK + tax + 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: + jsr HIDE ; Hide cursor on exit + lda INIT_save + sta INIT_STATUS + rts + +;---------------------------------------------------------------------------- +; HIDE routine. Is called to hide the lightpen pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse is currently visible, and should get hidden. For most drivers, +; no special action is required besides hiding the lightpen cursor. +; No return code required. + +HIDE: sei + jsr CHIDE + cli + rts + +;---------------------------------------------------------------------------- +; SHOW routine. Is called to show the lightpen pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse is currently hidden, and should become visible. For most drivers, +; no special action is required besides enabling the lightpen cursor. +; No return code required. + +SHOW: sei + jsr CSHOW + cli + rts + +;---------------------------------------------------------------------------- +; SETBOX: Set the lightpen 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 lightpen 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 + + ldy #.sizeof (MOUSE_BOX) - 1 + sei + +@L1: lda (ptr1),y + sta XMin,y + dey + bpl @L1 + + cli + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the lightpen 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 + + ldy #.sizeof (MOUSE_BOX) - 1 +@L1: lda XMin,y + sta (ptr1),y + dey + bpl @L1 + rts + +;---------------------------------------------------------------------------- +; 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 .XA. 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. +; + +MOVE: sei ; No interrupts + jsr MoveY + + ldy #$01 + lda (sp),y + tax + dey + lda (sp),y + jsr MoveX ; Move the cursor + + cli ; Allow interrupts + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the button mask in .XA. + +BUTTONS: + lda Buttons + ldx #>0 + +; Make the lightpen buttons look like a 1351 mouse. + + asl a + asl SID_ADConv2 ; PotY + rol a + eor #MOUSE_BTN_RIGHT + and #MOUSE_BTN_LEFT | MOUSE_BTN_RIGHT + rts + +;---------------------------------------------------------------------------- +; POS: Return the lightpen 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 + +;---------------------------------------------------------------------------- +; INFO: Returns lightpen 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'll just +; call _mouse_pos to initiate 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 + +;---------------------------------------------------------------------------- +; IRQ: IRQ handler entry point. Called as a subroutine, but in the 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: + +; Record the state of the buttons. +; Try to avoid crosstalk between the keyboard and the lightpen. + + ldy #%00000000 ; Set ports A and B to input + sty CIA1_DDRB + sty CIA1_DDRA ; Keyboard won't look like buttons + lda CIA1_PRB ; Read Control-Port 1 + dec CIA1_DDRA ; Set port A back to output + eor #%11111111 ; Bit goes up when button goes down + sta Buttons + bze @L0 + lda #%11101111 ; (Don't change bit that feeds VIC-II) + sta CIA1_DDRB ; Buttons won't look like keyboard + sty CIA1_PRB ; Set "all keys pushed" + +; Read the VIC-II lightpen registers. + +@L0: lda VIC_LPEN_Y + cmp OldPenY + +; Skip processing if nothing has changed. + + beq @SkipY + sta OldPenY + +; Subtract the height of the top border, so that the lightpen co-ordinate +; will match the TGI co-ordinate. + + sub #50 + tay ; Remember low byte + ldx #>0 + +; Limit the Y co-ordinate to the bounding box. + + txa + cpy YMin + sbc YMin+1 + bpl @L3 + ldy YMin + ldx YMin+1 + jmp @L4 + +@L3: txa + cpy YMax + sbc YMax+1 + bmi @L4 + ldy YMax + ldx YMax+1 + +@L4: tya + jsr MoveY + +@SkipY: lda VIC_LPEN_X + cmp OldPenX + +; Skip processing if nothing has changed. + + beq @SkipX + sta OldPenX + +; Adjust the co-ordinate by the calibration offset. + + sub XOffset + +; Calculate the new X co-ordinate (--> .AY --> .XY). +; 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; +; but, it can reach across the screen. + + asl a + tay ; Remember low byte + lda #>0 + rol a + tax + +; Limit the X co-ordinate to the bounding box. + + cpy XMin + sbc XMin+1 + bpl @L1 + ldy XMin + ldx XMin+1 + jmp @L2 + +@L1: txa + cpy XMax + sbc XMax+1 + bmi @L2 + ldy XMax + ldx XMax+1 + +@L2: tya + jsr MoveX + +; Done + +@SkipX: clc ; Interrupt not "handled" + rts + +; Move the lightpen pointer to the new Y pos. + +MoveY: sta YPos + stx YPos+1 + jmp CMOVEY + +; Move the lightpen pointer to the new X pos. + +MoveX: sta XPos + stx XPos+1 + jmp CMOVEX diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s new file mode 100644 index 000000000..8c869d68f --- /dev/null +++ b/libsrc/c64/mou/c64-inkwell.s @@ -0,0 +1,526 @@ +; +; Driver for the Inkwell Systems 170-C and 184-C lightpens. +; +; 2013-05-16, Greg King +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "c64.inc" + + .macpack generic + .macpack cbm + +; ------------------------------------------------------------------------ +; Header. Includes jump table. + +.segment "JUMPTABLE" + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; ASCII "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; 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 MOUSE_FLAG_EARLY_IRQ + +; Callback table, set by the kernel before INSTALL is called. + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CMOVEX: jmp $0000 ; Move the cursor to X co-ord. +CMOVEY: jmp $0000 ; Move the cursor to Y co-ord. + + +;---------------------------------------------------------------------------- +; Constants + +SCREEN_HEIGHT = YSIZE * 8 +SCREEN_WIDTH = XSIZE * 8 +SCREEN_ZONE = YSIZE / 4 * XSIZE + +; This driver is for the standard 40-column screen. + +SCREEN := $0400 +COLOR_RAM := $D800 + + +;---------------------------------------------------------------------------- +; Global variables. The bounding box values are sorted so that they can be +; written with the least effort in the SETBOX and GETBOX routines; so, don't +; 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 + +; 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 + +;---------------------------------------------------------------------------- +; 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: + +; Initiate variables. Just copy the default stuff over. + + sei + ldx #.sizeof (DefVars) - 1 +@L0: lda DefVars,x + sta Vars,x + dex + bpl @L0 + + ldx VIC_LPEN_X + ldy VIC_LPEN_Y + stx OldPenX + sty OldPenY + cli + +; 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, 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 + ldx #6 ; Blue screen + stx VIC_BG_COLOR0 + pha + jsr CLRSCR + + ldy #.sizeof (Command2) - 1 +@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 +; set the lightpen position if it hasn't changed. + + jsr HIDE + + lda #<(SCREEN_HEIGHT / 2) + ldx #>(SCREEN_HEIGHT / 2) +PutCursor: + sei + jsr MoveY + lda #<(SCREEN_WIDTH / 2) + ldx #>(SCREEN_WIDTH / 2) + jsr MoveX + cli + +; Done, return zero. + + lda #MOUSE_ERR_OK + tax + 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 lightpen pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse is currently visible, and should get hidden. For most drivers, +; no special action is required besides hiding the lightpen cursor. +; No return code required. + +HIDE: sei + jsr CHIDE + cli + rts + +;---------------------------------------------------------------------------- +; SHOW routine. Is called to show the lightpen pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse is currently hidden, and should become visible. For most drivers, +; no special action is required besides enabling the lightpen cursor. +; No return code required. + +SHOW: sei + jsr CSHOW + cli + rts + +;---------------------------------------------------------------------------- +; SETBOX: Set the lightpen 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 lightpen 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 + + ldy #.sizeof (MOUSE_BOX) - 1 + sei + +@L1: lda (ptr1),y + sta XMin,y + dey + bpl @L1 + + cli + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the lightpen 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 + + ldy #.sizeof (MOUSE_BOX) - 1 +@L1: lda XMin,y + sta (ptr1),y + dey + bpl @L1 + rts + +;---------------------------------------------------------------------------- +; 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 .XA. 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. +; + +MOVE: sei ; No interrupts + jsr MoveY + + ldy #$01 + lda (sp),y + tax + dey + lda (sp),y + jsr MoveX ; Move the cursor + + cli ; Allow interrupts + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the button mask in .XA. + +BUTTONS: + lda Buttons + ldx #>0 + +; Make the lightpen buttons look like a 1351 mouse. + + asl a + asl SID_ADConv2 ; PotY + rol a + eor #MOUSE_BTN_RIGHT + and #MOUSE_BTN_LEFT | MOUSE_BTN_RIGHT + rts + +;---------------------------------------------------------------------------- +; POS: Return the lightpen 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 + +;---------------------------------------------------------------------------- +; INFO: Returns lightpen 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'll just +; call _mouse_pos to initiate 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 + +;---------------------------------------------------------------------------- +; IRQ: IRQ handler entry point. Called as a subroutine, but in the 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: + +; Record the state of the buttons. +; Try to avoid crosstalk between the keyboard and the lightpen. + + ldy #%00000000 ; Set ports A and B to input + sty CIA1_DDRB + sty CIA1_DDRA ; Keyboard won't look like buttons + lda CIA1_PRB ; Read Control-Port 1 + dec CIA1_DDRA ; Set port A back to output + eor #%11111111 ; Bit goes up when button goes down + sta Buttons + bze @L0 + lda #%11101111 ; (Don't change bit that feeds VIC-II) + sta CIA1_DDRB ; Buttons won't look like keyboard + sty CIA1_PRB ; Set "all keys pushed" + +; Read the VIC-II lightpen registers. + +@L0: lda VIC_LPEN_Y + cmp OldPenY + +; Skip processing if nothing has changed. + + beq @SkipY + sta OldPenY + +; Subtract the height of the top border, so that the lightpen co-ordinate +; will match the TGI co-ordinate. + + sub #50 + tay ; Remember low byte + ldx #>0 + +; Limit the Y co-ordinate to the bounding box. + + txa + cpy YMin + sbc YMin+1 + bpl @L3 + ldy YMin + ldx YMin+1 + jmp @L4 + +@L3: txa + cpy YMax + sbc YMax+1 + bmi @L4 + ldy YMax + ldx YMax+1 + +@L4: tya + jsr MoveY + +@SkipY: lda VIC_LPEN_X + cmp OldPenX + +; Skip processing if nothing has changed. + + beq @SkipX + sta OldPenX + +; Adjust the co-ordinate by the calibration offset. + + sub XOffset + +; Calculate the new X co-ordinate (--> .AY --> .XY). +; 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; +; but, it can reach across the screen. + + asl a + tay ; Remember low byte + lda #>0 + rol a + tax + +; Limit the X co-ordinate to the bounding box. + + cpy XMin + sbc XMin+1 + bpl @L1 + ldy XMin + ldx XMin+1 + jmp @L2 + +@L1: txa + cpy XMax + sbc XMax+1 + bmi @L2 + ldy XMax + ldx XMax+1 + +@L2: tya + jsr MoveX + +; Done + +@SkipX: clc ; Interrupt not "handled" + rts + +; Move the lightpen pointer to the new Y pos. + +MoveY: sta YPos + stx YPos+1 + jmp CMOVEY + +; Move the lightpen pointer to the new X pos. + +MoveX: sta XPos + stx XPos+1 + jmp CMOVEX diff --git a/testcode/lib/pen-test.c b/testcode/lib/pen-test.c new file mode 100644 index 000000000..ed1d75a2a --- /dev/null +++ b/testcode/lib/pen-test.c @@ -0,0 +1,282 @@ +/* +** Test program for lightpen drivers. Will work for the C64/C128. +** +** 2001-09-13, Ullrich von Bassewitz +** 2013-05-24, Greg King +** +*/ + + + +#include +#include +#include +#include +#include +#include +#include + +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) + + + +/* Statically linked driver */ +#define DYN_DRV 0 + + + +#ifdef __C64__ +# if DYN_DRV +# define mouse_stddrv "c64-inkwell.mou" +# else +# define mouse_static_stddrv c64_inkwell_mou +# endif +#endif + +#ifdef __C128__ +# if DYN_DRV +# define mouse_stddrv "c128-inkwell.mou" +# else +# define mouse_static_stddrv c128_inkwell_mou +# endif +#endif + + + +#if defined(__C64__) || defined(__C128__) + +/* Addresses of data for sprite 0 */ +#if defined(__C64__) +# define SPRITE0_DATA ((unsigned char[64])0x0340) +# define SPRITE0_PTR ((unsigned char *)0x07F8) +#elif defined(__C128__) +# define SPRITE0_DATA ((unsigned char[64])0x0E00) +# define SPRITE0_PTR ((unsigned char *)0x07F8) +#endif + +/* The lightpen sprite (an arrow) */ +static const unsigned char PenSprite[64] = { + 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, + 0xF8, 0x00, 0x00, + 0xFC, 0x00, 0x00, + 0xDE, 0x00, 0x00, + 0x8F, 0x00, 0x00, + 0x87, 0x80, 0x00, + 0x83, 0xC0, 0x00, + 0x81, 0xE0, 0x00, + 0x80, 0xF0, 0x00, + 0x80, 0x78, 0x00, + 0x80, 0x38, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00 +}; + +#endif /* __C64__ or __C128__ */ + + + +static void __fastcall__ CheckError (const char* S, unsigned char Error) +{ + if (Error != MOUSE_ERR_OK) { + cprintf ("%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error); + exit (EXIT_FAILURE); + } +} + +#if DYN_DRV +static void DoWarning (void) +/* Warn the user that a lightpen driver is needed for this program. */ +{ + cprintf ("Warning: This program needs a lightpen\r\n" + "driver with the name\r\n" + " %s\r\n" + "on disk! Press 'y' if you have it; or,\r\n" + "any other key to exit.\r\n", mouse_stddrv); + if (tolower (cgetc ()) != 'y') { + exit (EXIT_SUCCESS); + } + cprintf ("OK. Please wait patiently...\r\n"); +} +#endif + + + +static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible) +/* Display jail and cursor states. */ +{ + cclearxy (0, 7, 40); + gotoxy (0, 7); + cprintf ("Lightpen cursor is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : ""); +} + + + +int main (void) +{ + struct mouse_info info; + struct mouse_box full_box, small_box; + char C; + unsigned char width, height; + bool Invisible = false, Done = false, Jailed = false; + + /* Only the VIC-II has a lightpen connection. */ +#ifdef __C128__ + videomode (VIDEOMODE_40x25); +#endif + + /* Initiate the debugger. */ + DbgInit (0); + + /* Set dark-on-light colors. Clear the screen. */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif + cursor (0); + clrscr (); + +#if defined(__C64__) || defined(__C128__) + /* Copy the sprite data. */ + memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite); + + /* Set the VIC-II sprite pointer. */ + *SPRITE0_PTR = (unsigned) SPRITE0_DATA / sizeof SPRITE0_DATA; + + /* Set the color of sprite 0. */ + VIC.spr0_color = COLOR_BLACK; +#endif + +#if DYN_DRV + /* Output a warning about the driver that is needed. */ + DoWarning (); + + /* Load and install the lightpen driver. */ + CheckError ("mouse_load_driver", + mouse_load_driver (&mouse_def_callbacks, mouse_stddrv)); +#else + /* Install the lightpen driver. */ + CheckError ("mouse_install", + mouse_install (&mouse_def_callbacks, mouse_static_stddrv)); +#endif + + /* Get the initial lightpen bounding box. */ + mouse_getbox (&full_box); + + screensize (&width, &height); + +top: + /* Print a help line. */ + clrscr (); +/* revers (1); */ + cputs (" d)ebug h)ide q)uit s)how j)ail "); +/* revers (0); */ + + /* Put a cross at the center of the screen. */ + gotoxy (width / 2 - 3, height / 2 - 1); + cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, + width / 2, ""); + + /* Custom driver debugging line */ + cprintf ("\n\r\n Calibration X-offset = %u", (*(unsigned char *)0x3ff) * 2); + + /* Expose the arrow. */ + mouse_show (); + ShowState (Jailed, Invisible); + + /* Test loop */ + do { + /* Get the current lightpen co-ordinates and button states; + ** and, print them. + */ + mouse_info (&info); + gotoxy (0, 2); + cprintf (" X = %3d\r\n", info.pos.x); + cprintf (" Y = %3d\r\n", info.pos.y); + cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? 0x5F : '^'); + cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? 0x5F : '^'); + + /* Handle user input. */ + if (kbhit ()) { + cclearxy (1, 9, 23); + switch (tolower (C = cgetc ())) { + case 'd': + BREAK(); + + /* The debugger might have changed the colors. + ** Restore them. + */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif + goto top; + + case 'h': + mouse_hide (); + ShowState (Jailed, ++Invisible); + break; + + case 'j': + if (Jailed) { + mouse_setbox (&full_box); + Jailed = false; + } else { + small_box.minx = max (info.pos.x - 10, full_box.minx); + small_box.miny = max (info.pos.y - 10, full_box.miny); + small_box.maxx = min (info.pos.x + 10, full_box.maxx); + small_box.maxy = min (info.pos.y + 10, full_box.maxy); + mouse_setbox (&small_box); + Jailed = true; + } + ShowState (Jailed, Invisible); + break; + + case 's': + mouse_show (); + if (Invisible) { + ShowState (Jailed, --Invisible); + } + break; + + case 'q': + Done = true; + break; + + default: + gotoxy (1, 9); + cprintf ("Spurious character: $%02X", C); + } + } + } while (!Done); + +#if DYN_DRV + /* Uninstall and unload the lightpen driver. */ + CheckError ("mouse_unload", mouse_unload ()); +#else + /* Uninstall the lightpen driver. */ + CheckError ("mouse_uninstall", mouse_uninstall ()); +#endif + + /* Say goodbye. */ + cputsxy (0, 16, "Goodbye!"); + return EXIT_SUCCESS; +} From 233aa407526c410c51dfb6b4390d25a55928dcb0 Mon Sep 17 00:00:00 2001 From: Greg King Date: Wed, 29 May 2013 21:34:40 -0400 Subject: [PATCH 02/12] Replaced an obsolete spelling with the current one. --- include/c128.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/c128.h b/include/c128.h index 2799f8e39..2ca559d49 100644 --- a/include/c128.h +++ b/include/c128.h @@ -131,7 +131,7 @@ extern void c128_ptvjoy_joy[]; extern void c128_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void c128_1351_mous[]; /* Referred to by mouse_static_stddrv[] */ extern void c128_joy_mou[]; -extern void c128_nkwll40_mou[]; +extern void c128_inkwell_mou[]; extern void c128_pot_mou[]; extern void c128_swlink_ser[]; extern void c128_vdc_tgi[]; /* Referred to by tgi_static_stddrv[] */ From e63bf1cde1c0d63ca1d78238f56d35401ad3a996 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 23 Jun 2013 03:18:28 -0400 Subject: [PATCH 03/12] 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. --- include/mouse.h | 48 ++++++-- libsrc/c128/libref.s | 12 +- libsrc/c128/mou/c128-inkwell.s | 188 ++++++++----------------------- libsrc/c128/mouseref.s | 23 ++++ libsrc/c128/pencalib.c | 92 ++++++++++++++++ libsrc/c64/libref.s | 12 +- libsrc/c64/mou/c64-inkwell.s | 195 +++++++++------------------------ libsrc/c64/mouseref.s | 23 ++++ libsrc/c64/pencalib.c | 93 ++++++++++++++++ libsrc/cbm/penadjust.c | 53 +++++++++ testcode/lib/pen-test.c | 42 ++++--- 11 files changed, 463 insertions(+), 318 deletions(-) create mode 100644 libsrc/c128/mouseref.s create mode 100644 libsrc/c128/pencalib.c create mode 100644 libsrc/c64/mouseref.s create mode 100644 libsrc/c64/pencalib.c create mode 100755 libsrc/cbm/penadjust.c diff --git a/include/mouse.h b/include/mouse.h index bc90263cf..bc93f8b8c 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2003-2011, Ullrich von Bassewitz */ +/* (C) 2003-2013, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -101,6 +101,14 @@ struct mouse_callbacks { */ }; + + +/*****************************************************************************/ +/* Declarations */ +/*****************************************************************************/ + + + /* The default mouse 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 */ 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, 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); -/* 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); /* Get an error message describing the error in code. */ @@ -142,7 +157,7 @@ void mouse_hide (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); /* 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); -/* Return the current mouse position */ +/* Return the current mouse position. */ 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); -/* Call the driver specific ioctl function. NON PORTABLE! Returns an error - * code. +/* Call the driver-specific ioctl function. Return an error 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. */ diff --git a/libsrc/c128/libref.s b/libsrc/c128/libref.s index fb22515bd..4f65e3959 100644 --- a/libsrc/c128/libref.s +++ b/libsrc/c128/libref.s @@ -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 em_libref := _exit joy_libref := _exit -mouse_libref := _exit +;mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index c76234915..4cd009f2c 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -1,7 +1,7 @@ ; ; Driver for the Inkwell Systems 170-C and 184-C lightpens. ; -; 2013-06-03, Greg King +; 2013-06-17, Greg King ; .include "zeropage.inc" @@ -9,7 +9,6 @@ .include "c128.inc" .macpack generic - .macpack cbm ; ------------------------------------------------------------------------ ; Header. Includes jump table. @@ -25,7 +24,7 @@ HEADER: ; Library reference - .addr $0000 +LIBREF: .addr $0000 ; Jump table @@ -62,14 +61,8 @@ CMOVEY: jmp $0000 ; Move the cursor to Y co-ord. XSIZE = 40 YSIZE = 25 -SCREEN_HEIGHT = YSIZE * 8 SCREEN_WIDTH = XSIZE * 8 -SCREEN_ZONE = YSIZE / 4 * XSIZE - -SCREEN := $0400 -COLOR_RAM := $D800 - -PRIMM := $FF7D ; Print immediate +SCREEN_HEIGHT = YSIZE * 8 ;---------------------------------------------------------------------------- @@ -77,6 +70,19 @@ PRIMM := $FF7D ; Print immediate ; written with the least effort in the SETBOX and GETBOX routines; so, don't ; 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 Vars: @@ -89,36 +95,21 @@ 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 +OldPenX: .res 1 ; Previous HW-counter values OldPenY: .res 1 INIT_save: .res 1 .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 - -; 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 +; Jump to a function that puts a new calibration value into XOffset. +Calibrate: jmp $0000 .code @@ -138,15 +129,8 @@ INSTALL: lda #%11000000 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. -@L7: sei ldx #.sizeof (DefVars) - 1 @L0: lda DefVars,x sta Vars,x @@ -157,121 +141,37 @@ INSTALL: ldy VIC_LPEN_Y stx OldPenX sty OldPenY - cli -; 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, 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. +; Call a calibration function through the library-reference. - lda VIC_BG_COLOR0 - ldx #6 ; Blue screen - stx VIC_BG_COLOR0 - pha - jsr CLRSCR + lda LIBREF + ldx LIBREF+1 + sta ptr1 ; Point to mouse_adjuster + stx ptr1+1 + 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 + jsr Calibrate - ldy #.sizeof (Command2) - 1 -@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. +; Be sure that the lightpen cursor is invisible and at the default location. ; It needs to be done here because the lightpen interrupt handler doesn't ; set the lightpen position if it hasn't changed. - jsr HIDE +@L1: jsr CHIDE lda #<(SCREEN_HEIGHT / 2) ldx #>(SCREEN_HEIGHT / 2) -PutCursor: - sei jsr MoveY lda #<(SCREEN_WIDTH / 2) ldx #>(SCREEN_WIDTH / 2) jsr MoveX - cli ; Done, return zero. @@ -504,11 +404,11 @@ IRQ: beq @SkipX sta OldPenX -; Adjust the co-ordinate by the calibration offset. +; Adjust the value by the calibration offset. 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. ; Therefore, the VIC-II number is doubled. Then, it points to every other pixel; ; but, it can reach across the screen. @@ -517,7 +417,7 @@ IRQ: tay ; Remember low byte lda #>0 rol a - tax + tax ; Remember high byte ; Limit the X co-ordinate to the bounding box. diff --git a/libsrc/c128/mouseref.s b/libsrc/c128/mouseref.s new file mode 100644 index 000000000..fb83c439f --- /dev/null +++ b/libsrc/c128/mouseref.s @@ -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 diff --git a/libsrc/c128/pencalib.c b/libsrc/c128/pencalib.c new file mode 100644 index 000000000..cf9a3f92b --- /dev/null +++ b/libsrc/c128/pencalib.c @@ -0,0 +1,92 @@ +/* +** Calibrate lightpen drivers to the current video hardware. +** +** 2013-06-17, Greg King +** +*/ + + +#include +#include + + +#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 (); +} diff --git a/libsrc/c64/libref.s b/libsrc/c64/libref.s index fb22515bd..4f65e3959 100644 --- a/libsrc/c64/libref.s +++ b/libsrc/c64/libref.s @@ -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 em_libref := _exit joy_libref := _exit -mouse_libref := _exit +;mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s index 0f0c8a40f..367be6105 100644 --- a/libsrc/c64/mou/c64-inkwell.s +++ b/libsrc/c64/mou/c64-inkwell.s @@ -1,7 +1,7 @@ ; ; Driver for the Inkwell Systems 170-C and 184-C lightpens. ; -; 2013-06-03, Greg King +; 2013-06-17, Greg King ; .include "zeropage.inc" @@ -9,7 +9,6 @@ .include "c64.inc" .macpack generic - .macpack cbm ; ------------------------------------------------------------------------ ; Header. Includes jump table. @@ -25,7 +24,7 @@ HEADER: ; Library reference - .addr $0000 +LIBREF: .addr $0000 ; Jump table @@ -57,14 +56,8 @@ CMOVEY: jmp $0000 ; Move the cursor to Y co-ord. ;---------------------------------------------------------------------------- ; Constants -SCREEN_HEIGHT = YSIZE * 8 SCREEN_WIDTH = XSIZE * 8 -SCREEN_ZONE = YSIZE / 4 * XSIZE - -; This driver is for the standard 40-column screen. - -SCREEN := $0400 -COLOR_RAM := $D800 +SCREEN_HEIGHT = YSIZE * 8 ;---------------------------------------------------------------------------- @@ -72,29 +65,9 @@ COLOR_RAM := $D800 ; written with the least effort in the SETBOX and GETBOX routines; so, don't ; 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 -; Default values for above variables +; Default values for below variables ; (We use ".proc" because we want to define both a label and a scope.) .proc DefVars @@ -105,12 +78,31 @@ XOffset: .byte 48 / 2 ; Calibration offset, for X position .byte %00000000 ; Buttons .endproc -.proc Command1 - scrcode "Adjust by clicking on line." -.endproc -.proc Command2 - scrcode "Finish by clicking off box." -.endproc +.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 ; 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 @@ -124,7 +116,6 @@ INSTALL: ; Initiate variables. Just copy the default stuff over. - sei ldx #.sizeof (DefVars) - 1 @L0: lda DefVars,x sta Vars,x @@ -135,121 +126,37 @@ INSTALL: ldy VIC_LPEN_Y stx OldPenX sty OldPenY - cli -; 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, 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. +; Call a calibration function through the library-reference. - lda VIC_BG_COLOR0 - ldx #6 ; Blue screen - stx VIC_BG_COLOR0 - pha - jsr CLRSCR + lda LIBREF + ldx LIBREF+1 + sta ptr1 ; Point to mouse_adjuster + stx ptr1+1 + 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 + jsr Calibrate - ldy #.sizeof (Command2) - 1 -@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. +; Be sure that the lightpen cursor is invisible and at the default location. ; It needs to be done here because the lightpen interrupt handler doesn't ; set the lightpen position if it hasn't changed. - jsr HIDE +@L1: jsr CHIDE lda #<(SCREEN_HEIGHT / 2) ldx #>(SCREEN_HEIGHT / 2) -PutCursor: - sei jsr MoveY lda #<(SCREEN_WIDTH / 2) ldx #>(SCREEN_WIDTH / 2) jsr MoveX - cli ; Done, return zero. @@ -478,20 +385,20 @@ IRQ: beq @SkipX sta OldPenX -; Adjust the co-ordinate by the calibration offset. +; Adjust the value by the calibration offset. 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. -; 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. asl a tay ; Remember low byte lda #>0 rol a - tax + tax ; Remember high byte ; Limit the X co-ordinate to the bounding box. diff --git a/libsrc/c64/mouseref.s b/libsrc/c64/mouseref.s new file mode 100644 index 000000000..fb83c439f --- /dev/null +++ b/libsrc/c64/mouseref.s @@ -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 diff --git a/libsrc/c64/pencalib.c b/libsrc/c64/pencalib.c new file mode 100644 index 000000000..d0e6b0ff2 --- /dev/null +++ b/libsrc/c64/pencalib.c @@ -0,0 +1,93 @@ +/* +** Calibrate lightpen drivers to the current video hardware. +** +** 2013-06-17, Greg King +** +*/ + + +#include +#include + + +#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 (); +} diff --git a/libsrc/cbm/penadjust.c b/libsrc/cbm/penadjust.c new file mode 100755 index 000000000..104c33c8d --- /dev/null +++ b/libsrc/cbm/penadjust.c @@ -0,0 +1,53 @@ +/* +** Main lightpen driver calibration functions. +** +** 2013-06-23, Greg King +*/ + + +#include +#include +#include + + +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; + } +} diff --git a/testcode/lib/pen-test.c b/testcode/lib/pen-test.c index ed1d75a2a..aa3992635 100644 --- a/testcode/lib/pen-test.c +++ b/testcode/lib/pen-test.c @@ -2,7 +2,7 @@ ** Test program for lightpen drivers. Will work for the C64/C128. ** ** 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) #endif -/* The lightpen sprite (an arrow) */ +/* An arrow sprite */ static const unsigned char PenSprite[64] = { 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, @@ -113,9 +113,9 @@ static void DoWarning (void) static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible) /* Display jail and cursor states. */ { - cclearxy (0, 7, 40); + cclearxy (0, 7, 32); 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; bool Invisible = false, Done = false, Jailed = false; - /* Only the VIC-II has a lightpen connection. */ #ifdef __C128__ + /* Only the VIC-IIe has a lightpen connection. */ videomode (VIDEOMODE_40x25); #endif @@ -154,10 +154,12 @@ int main (void) memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite); /* 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. */ VIC.spr0_color = COLOR_BLACK; + + pen_adjust ("inkwell.dat"); #endif #if DYN_DRV @@ -179,20 +181,16 @@ int main (void) screensize (&width, &height); top: - /* Print a help line. */ clrscr (); -/* revers (1); */ - cputs (" d)ebug h)ide q)uit s)how j)ail "); -/* revers (0); */ + + /* Print a help line. */ + cputs (" d)ebug h)ide q)uit s)how j)ail"); /* Put a cross at the center of the screen. */ gotoxy (width / 2 - 3, height / 2 - 1); cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, width / 2, ""); - /* Custom driver debugging line */ - cprintf ("\n\r\n Calibration X-offset = %u", (*(unsigned char *)0x3ff) * 2); - /* Expose the arrow. */ mouse_show (); ShowState (Jailed, Invisible); @@ -206,8 +204,20 @@ top: gotoxy (0, 2); cprintf (" X = %3d\r\n", info.pos.x); cprintf (" Y = %3d\r\n", info.pos.y); - cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? 0x5F : '^'); - cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? 0x5F : '^'); + cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); + cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); /* Handle user input. */ if (kbhit ()) { @@ -277,6 +287,6 @@ top: #endif /* Say goodbye. */ - cputsxy (0, 16, "Goodbye!"); + cputsxy (0, height / 2 + 3, "Goodbye!"); return EXIT_SUCCESS; } From 88c102b993d64fa9b74af6c1a74f992480d1d9a3 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 23 Jun 2013 11:47:45 -0400 Subject: [PATCH 04/12] Renamed the mouse sample program because it also tests the mouse library. --- samples/Makefile | 8 ++++---- samples/README | 4 ++-- samples/{mousedemo.c => mousetest.c} | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename samples/{mousedemo.c => mousetest.c} (100%) diff --git a/samples/Makefile b/samples/Makefile index 046eb8fc9..327adc482 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -78,7 +78,7 @@ EXELIST = ascii \ gunzip65 \ hello \ mandelbrot \ - mousedemo \ + mousetest \ multdemo \ nachtm \ ovrldemo \ @@ -115,12 +115,12 @@ mandelbrot: mandelbrot.o endif endif -# The Apple ][ needs the start address adjusted for the mousedemo +# The Apple ][ needs the start address adjusted for the mousetest ifeq "$(SYS)" "apple2" -mousedemo: mousedemo.o +mousetest: mousetest.o @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) else -mousedemo: mousedemo.o +mousetest: mousetest.o endif multdemo: multidemo.o diff --git a/samples/README b/samples/README index 25ee43118..5997fc8d0 100644 --- a/samples/README +++ b/samples/README @@ -69,8 +69,8 @@ Platforms: Runs on all platforms that have TGI support: Apple ][, C64, C128, Oric Atmos, Geos and Lynx. ----------------------------------------------------------------------------- -Name: mousedemo -Description: Shows how to use the mouse. +Name: mousetest +Description: Tests and shows how to use the mouse. Platforms: All systems with mouse and conio support: C64, C128, CBM510, Atari, Apple ][ diff --git a/samples/mousedemo.c b/samples/mousetest.c similarity index 100% rename from samples/mousedemo.c rename to samples/mousetest.c From ecef5551a8009304a96cedd41780ab75fd6a2d52 Mon Sep 17 00:00:00 2001 From: Greg King Date: Thu, 27 Jun 2013 10:01:47 -0400 Subject: [PATCH 05/12] Merged testcode/lib/pen-test.c into the mousetest.c sample program. A command-line option can force mousetest to be built with a statically linked driver. --- samples/Makefile | 48 +++--- samples/mousetest.c | 326 +++++++++++++++++++++++++--------------- testcode/lib/pen-test.c | 292 ----------------------------------- 3 files changed, 227 insertions(+), 439 deletions(-) delete mode 100644 testcode/lib/pen-test.c diff --git a/samples/Makefile b/samples/Makefile index 327adc482..a17288ced 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -30,21 +30,14 @@ LD = ld65 else # "samples/" is a part of a complete source tree. -CA65_INC = ../asminc -CC65_INC = ../include -LD65_CFG = ../src/ld65/cfg -LD65_LIB = ../libsrc -LD65_OBJ = ../libsrc -MOUS = ../libsrc/$(SYS)*.mou -TGI = ../libsrc/$(SYS)*.tgi -CLIB = ../libsrc/$(SYS).lib -CL = ../src/cl65/cl65 -CC = ../src/cc65/cc65 -AS = ../src/ca65/ca65 -LD = ../src/ld65/ld65 - -MY_INC = --forget-inc-paths -I . -I $(CC65_INC) -MY_ASM = --forget-inc-paths -I . -I $(CA65_INC) +export CC65_HOME := $(abspath ..) +MOUS = ../mou/$(SYS)*.mou +TGI = ../tgi/$(SYS)*.tgi +CLIB = ../lib/$(SYS).lib +CL = ../bin/cl65 +CC = ../bin/cc65 +AS = ../bin/ca65 +LD = ../bin/ld65 endif # This one comes with VICE @@ -54,17 +47,20 @@ C1541 = c1541 # -------------------------------------------------------------------------- # Generic rules +%: %.c +%: %.s + .c.o: @echo $< - @$(CC) $(MY_INC) -Oirs --codesize 500 -T -g -t $(SYS) $< - @$(AS) $(basename $<).s + @$(CC) $(CFLAGS) -Oirs --codesize 500 -T -g -t $(SYS) $< + @$(AS) $(<:.c=.s) .s.o: @echo $< - @$(AS) $(MY_ASM) -t $(SYS) $< + @$(AS) $(AFLAGS) -t $(SYS) $< .o: - @$(LD) -o $@ -t $(SYS) -m $(basename $@).map $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map $^ $(CLIB) # -------------------------------------------------------------------------- @@ -105,11 +101,11 @@ hello: hello.o # The Apple machines need the start address adjusted for the mandelbrot demo ifeq "$(SYS)" "apple2" mandelbrot: mandelbrot.o - @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map --start-addr 0x4000 $^ $(CLIB) else ifeq "$(SYS)" "apple2enh" mandelbrot: mandelbrot.o - @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map --start-addr 0x4000 $^ $(CLIB) else mandelbrot: mandelbrot.o endif @@ -118,18 +114,18 @@ endif # The Apple ][ needs the start address adjusted for the mousetest ifeq "$(SYS)" "apple2" mousetest: mousetest.o - @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map --start-addr 0x4000 $^ $(CLIB) else mousetest: mousetest.o endif multdemo: multidemo.o - @$(LD) -t $(SYS) -m $(basename $@).map -C $(SYS)-overlay.cfg -o $@ $^ $(CLIB) + @$(LD) -o $@ -m $@.map -C $(SYS)-overlay.cfg $^ $(CLIB) nachtm: nachtm.o ovrldemo: overlaydemo.o - @$(LD) -t $(SYS) -m $(basename $@).map -C $(SYS)-overlay.cfg -o $@ $^ $(CLIB) + @$(LD) -o $@ -m $@.map -C $(SYS)-overlay.cfg $^ $(CLIB) plasma: plasma.o @@ -138,11 +134,11 @@ sieve: sieve.o # The Apple machines need the start address adjusted for the tgidemo ifeq "$(SYS)" "apple2" tgidemo: tgidemo.o - @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map --start-addr 0x4000 $^ $(CLIB) else ifeq "$(SYS)" "apple2enh" tgidemo: tgidemo.o - @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) + @$(LD) -o $@ -t $(SYS) -m $@.map --start-addr 0x4000 $^ $(CLIB) else tgidemo: tgidemo.o endif diff --git a/samples/mousetest.c b/samples/mousetest.c index d5d0e36a6..b2d49b072 100644 --- a/samples/mousetest.c +++ b/samples/mousetest.c @@ -1,12 +1,15 @@ /* - * Demo program for mouse usage. Will work for the C64/C128/CBM510/Atari/Apple2 - * - * Ullrich von Bassewitz, 13.09.2001 - * - */ +** Test/demo program for mouse usage. +** Will work for the C64/C128/CBM510/Atari/Apple2. +** +** 2001-09-13, Ullrich von Bassewitz +** 2013-06-26, Greg King +** +*/ +#include #include #include #include @@ -14,225 +17,306 @@ #include #include - - -#if defined(__C64__) || defined(__C128__) - -/* Address of data for sprite 0 */ -#if defined(__C64__) -# define SPRITE0_DATA 0x0340 -# define SPRITE0_PTR 0x07F8 -#elif defined(__C128__) -# define SPRITE0_DATA 0x0E00 -# define SPRITE0_PTR 0x07F8 -#endif - -/* The mouse sprite (an arrow) */ -static const unsigned char MouseSprite[64] = { - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x0F, 0xE0, 0x00, - 0x0F, 0xC0, 0x00, - 0x0F, 0x80, 0x00, - 0x0F, 0xC0, 0x00, - 0x0D, 0xE0, 0x00, - 0x08, 0xF0, 0x00, - 0x00, 0x78, 0x00, - 0x00, 0x3C, 0x00, - 0x00, 0x1E, 0x00, - 0x00, 0x0F, 0x00, - 0x00, 0x07, 0x80, - 0x00, 0x03, 0x80, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00 -}; - -#endif /* __C64__ or __C128__ */ - - -/* Dynamically loaded driver by default */ -#ifndef DYN_DRV -# define DYN_DRV 1 -#endif - - #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) -static void CheckError (const char* S, unsigned char Error) +#ifdef MOUSE_DRIVER + +/* A statically linked driver was named on the compiler's command line. +** Make sure that it is used instead of a dynamic one. +*/ +# undef DYN_DRV +# define DYN_DRV 0 +#else + +/* Use a dynamically loaded driver, by default. */ +# ifndef DYN_DRV +# define DYN_DRV 1 +# endif +#endif + + + +#if defined(__C64__) || defined(__C128__) || defined(__CBM510__) + +/* Addresses of data for sprite 0 */ +#if defined(__C64__) +# define SPRITE0_DATA ((unsigned char[64])0x0340) +# define SPRITE0_PTR ((unsigned char *)0x07F8) +#elif defined(__C128__) +# define SPRITE0_DATA ((unsigned char[64])0x0E00) +# define SPRITE0_PTR ((unsigned char *)0x07F8) +#elif defined(__CBM510__) +# define SPRITE0_DATA ((unsigned char[64])0xF400) +# define SPRITE0_PTR ((unsigned char *)0xF3F8) +#endif + +/* The mouse sprite (an arrow) */ +static const unsigned char MouseSprite[64] = { + 0xFE, 0x00, 0x00, + 0xFC, 0x00, 0x00, + 0xF8, 0x00, 0x00, + 0xFC, 0x00, 0x00, + 0xDE, 0x00, 0x00, + 0x8F, 0x00, 0x00, + 0x07, 0x80, 0x00, + 0x03, 0xC0, 0x00, + 0x01, 0xE0, 0x00, + 0x00, 0xF0, 0x00, + 0x00, 0x78, 0x00, + 0x00, 0x38, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; +#endif + + + +static void __fastcall__ CheckError (const char* S, unsigned char Error) { if (Error != MOUSE_ERR_OK) { - cprintf ("%s: %s(%d)\r\n", S, mouse_geterrormsg (Error), Error); + cprintf ("%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error); exit (EXIT_FAILURE); } } +#if DYN_DRV + +/* Points to the dynamic driver's name. */ +static const char *mouse_name; + + + static void DoWarning (void) -/* Warn the user that a mouse driver is needed for this program */ +/* Warn the user that a driver is needed for this program. */ { - cprintf ("Warning: This program needs the mouse\r\n" - "driver with the name\r\n" + cprintf ("Warning: This program needs\r\n" + "the driver with the name\r\n" " %s\r\n" - "on disk! Press 'y' if you have it or\r\n" - "any other key to exit.\r\n", mouse_stddrv); + "on a disk! Press 'y' if you have it;\r\n" + "or, any other key to exit.\r\n", mouse_stddrv); if (tolower (cgetc ()) != 'y') { exit (EXIT_SUCCESS); } - cprintf ("Ok. Please wait patiently...\r\n"); + cprintf ("OK. Please wait patiently...\r\n"); } +#endif -static void ShowState (unsigned char Jailed, unsigned char Invisible) -/* Display jail and cursor state */ +static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible) +/* Display jail and cursor states. */ { - gotoxy (0, 6); - cclear (40); - gotoxy (0, 6); - cprintf ("Mouse cursor %svisible%s", Invisible? "in" : "", Jailed? ", jailed" : ""); + cclearxy (0, 7, 32); + gotoxy (0, 7); + cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : ""); } +#if DYN_DRV +int main (int argc, char *argv[]) +#else int main (void) +#endif { struct mouse_info info; - struct mouse_box full_box; - struct mouse_box small_box; - unsigned char Invisible; - unsigned char Done; - unsigned char Jailed; + struct mouse_box full_box, small_box; + unsigned char width, height; + char C; + bool Invisible = true, Done = false, Jailed = false; /* Initialize the debugger */ DbgInit (0); - /* Clear the screen, set white on black */ - (void) bordercolor (COLOR_BLACK); - (void) bgcolor (COLOR_BLACK); - (void) textcolor (COLOR_GRAY3); + /* Set dark-on-light colors. Clear the screen. */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif cursor (0); clrscr (); + /* The pointer is created before the driver is installed, + ** in case a lightpen driver needs it during calibration. + */ + #if defined(__C64__) || defined(__C128__) || defined(__CBM510__) /* Copy the sprite data */ memcpy ((void*) SPRITE0_DATA, MouseSprite, sizeof (MouseSprite)); - /* Set the VIC sprite pointer */ - *(unsigned char*)SPRITE0_PTR = SPRITE0_DATA / 64; + /* Set the VIC-II sprite pointer. */ + *SPRITE0_PTR = ((unsigned) SPRITE0_DATA & 0x3FFF) / sizeof SPRITE0_DATA; /* Set the color of sprite 0 */ -#ifdef __CBM510__ - pokebsys ((unsigned) &VIC.spr0_color, COLOR_WHITE); -#else - VIC.spr0_color = COLOR_WHITE; +# ifdef __CBM510__ + pokebsys ((unsigned) &VIC.spr0_color, COLOR_BLACK); +# else + VIC.spr0_color = COLOR_BLACK; +# endif #endif + /* If a lightpen driver is installed, then it can get a calibration value + ** from this file (if it exists). Or, the user can adjust the pen; and, + ** the value will be put into this file, for the next time. + ** (Other drivers will ignore this.) + */ +#ifdef __CBM__ + pen_adjust ("pen.dat"); #endif #if DYN_DRV - /* Output a warning about the driver that is needed */ - DoWarning (); + /* If a dynamically loadable driver is named on the command line, + ** then use that driver instead of the standard one. + */ + if (argc > 1) { + mouse_name = argv[1]; + } else { + /* Output a warning about the standard driver that is needed. */ + DoWarning (); + mouse_name = mouse_stddrv; + } - /* Load and install the mouse driver */ + /* Load and install the driver. */ CheckError ("mouse_load_driver", - mouse_load_driver (&mouse_def_callbacks, mouse_stddrv)); + mouse_load_driver (&mouse_def_callbacks, mouse_name)); #else - /* Install the mouse driver */ + /* Install the driver. */ CheckError ("mouse_install", - mouse_install (&mouse_def_callbacks, mouse_static_stddrv)); + mouse_install (&mouse_def_callbacks, +# ifdef MOUSE_DRIVER + MOUSE_DRIVER +# else + mouse_static_stddrv +# endif + )); #endif - /* Get the initial mouse bounding box */ + /* Get the initial bounding box. */ mouse_getbox (&full_box); - /* Print a help line */ + screensize (&width, &height); + +top: clrscr (); - revers (1); - cputsxy (0, 0, "d)ebug h)ide q)uit s)how j)ail "); - revers (0); + + /* Print a help line */ + cputs (" d)ebug h)ide q)uit s)how j)ail"); + + /* Put a cross at the center of the screen. */ + gotoxy (width / 2 - 3, height / 2 - 1); + cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, + width / 2, ""); /* Test loop */ - Done = 0; - Jailed = 0; - Invisible = 1; ShowState (Jailed, Invisible); - while (!Done) { - - /* Get the current mouse coordinates and button states and print them */ + do { + /* Get the current co-ordinates and button states; and, print them. */ mouse_info (&info); gotoxy (0, 2); - cprintf ("X = %3d", info.pos.x); - gotoxy (0, 3); - cprintf ("Y = %3d", info.pos.y); - gotoxy (0, 4); - cprintf ("LB = %c", (info.buttons & MOUSE_BTN_LEFT)? '1' : '0'); - gotoxy (0, 5); - cprintf ("RB = %c", (info.buttons & MOUSE_BTN_RIGHT)? '1' : '0'); + cprintf (" X = %3d\r\n", info.pos.x); + cprintf (" Y = %3d\r\n", info.pos.y); + cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); + cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); /* Handle user input */ if (kbhit ()) { - switch (tolower (cgetc ())) { - + cclearxy (1, 9, 23); + switch (tolower (C = cgetc ())) { case 'd': BREAK(); - break; + + /* The debugger might have changed the colors. + ** Restore them. + */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif + + /* The debugger changed the screen; restore it. */ + goto top; case 'h': - ShowState (Jailed, ++Invisible); mouse_hide (); + ShowState (Jailed, ++Invisible); break; case 'j': if (Jailed) { - Jailed = 0; mouse_setbox (&full_box); + Jailed = false; } else { - Jailed = 1; small_box.minx = max (info.pos.x - 10, full_box.minx); small_box.miny = max (info.pos.y - 10, full_box.miny); small_box.maxx = min (info.pos.x + 10, full_box.maxx); small_box.maxy = min (info.pos.y + 10, full_box.maxy); mouse_setbox (&small_box); + Jailed = true; } ShowState (Jailed, Invisible); break; case 's': + mouse_show (); if (Invisible) { ShowState (Jailed, --Invisible); - mouse_show (); } break; case 'q': - Done = 1; + Done = true; break; + + default: + gotoxy (1, 9); + cprintf ("Spurious character: $%02X", C); } } - - } + } while (!Done); #if DYN_DRV - /* Uninstall and unload the mouse driver */ + /* Uninstall and unload the driver. */ CheckError ("mouse_unload", mouse_unload ()); #else - /* Uninstall the mouse driver */ + /* Uninstall the static driver. */ CheckError ("mouse_uninstall", mouse_uninstall ()); #endif /* Say goodbye */ - clrscr (); - cputs ("Goodbye!\r\n"); - + cputsxy (0, height / 2 + 3, "Goodbye!"); return EXIT_SUCCESS; } diff --git a/testcode/lib/pen-test.c b/testcode/lib/pen-test.c deleted file mode 100644 index aa3992635..000000000 --- a/testcode/lib/pen-test.c +++ /dev/null @@ -1,292 +0,0 @@ -/* -** Test program for lightpen drivers. Will work for the C64/C128. -** -** 2001-09-13, Ullrich von Bassewitz -** 2013-06-21, Greg King -** -*/ - - - -#include -#include -#include -#include -#include -#include -#include - -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#define min(a,b) (((a) < (b)) ? (a) : (b)) - - - -/* Statically linked driver */ -#define DYN_DRV 0 - - - -#ifdef __C64__ -# if DYN_DRV -# define mouse_stddrv "c64-inkwell.mou" -# else -# define mouse_static_stddrv c64_inkwell_mou -# endif -#endif - -#ifdef __C128__ -# if DYN_DRV -# define mouse_stddrv "c128-inkwell.mou" -# else -# define mouse_static_stddrv c128_inkwell_mou -# endif -#endif - - - -#if defined(__C64__) || defined(__C128__) - -/* Addresses of data for sprite 0 */ -#if defined(__C64__) -# define SPRITE0_DATA ((unsigned char[64])0x0340) -# define SPRITE0_PTR ((unsigned char *)0x07F8) -#elif defined(__C128__) -# define SPRITE0_DATA ((unsigned char[64])0x0E00) -# define SPRITE0_PTR ((unsigned char *)0x07F8) -#endif - -/* An arrow sprite */ -static const unsigned char PenSprite[64] = { - 0xFF, 0xFF, 0xFF, - 0xFC, 0x00, 0x00, - 0xF8, 0x00, 0x00, - 0xFC, 0x00, 0x00, - 0xDE, 0x00, 0x00, - 0x8F, 0x00, 0x00, - 0x87, 0x80, 0x00, - 0x83, 0xC0, 0x00, - 0x81, 0xE0, 0x00, - 0x80, 0xF0, 0x00, - 0x80, 0x78, 0x00, - 0x80, 0x38, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00, - 0x80, 0x00, 0x00 -}; - -#endif /* __C64__ or __C128__ */ - - - -static void __fastcall__ CheckError (const char* S, unsigned char Error) -{ - if (Error != MOUSE_ERR_OK) { - cprintf ("%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error); - exit (EXIT_FAILURE); - } -} - -#if DYN_DRV -static void DoWarning (void) -/* Warn the user that a lightpen driver is needed for this program. */ -{ - cprintf ("Warning: This program needs a lightpen\r\n" - "driver with the name\r\n" - " %s\r\n" - "on disk! Press 'y' if you have it; or,\r\n" - "any other key to exit.\r\n", mouse_stddrv); - if (tolower (cgetc ()) != 'y') { - exit (EXIT_SUCCESS); - } - cprintf ("OK. Please wait patiently...\r\n"); -} -#endif - - - -static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible) -/* Display jail and cursor states. */ -{ - cclearxy (0, 7, 32); - gotoxy (0, 7); - cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : ""); -} - - - -int main (void) -{ - struct mouse_info info; - struct mouse_box full_box, small_box; - char C; - unsigned char width, height; - bool Invisible = false, Done = false, Jailed = false; - -#ifdef __C128__ - /* Only the VIC-IIe has a lightpen connection. */ - videomode (VIDEOMODE_40x25); -#endif - - /* Initiate the debugger. */ - DbgInit (0); - - /* Set dark-on-light colors. Clear the screen. */ -#ifdef __CBM__ - (void) bordercolor (COLOR_GRAY2); - (void) bgcolor (COLOR_WHITE); - (void) textcolor (COLOR_GRAY1); -#else - (void) bordercolor (COLOR_BLUE); - (void) bgcolor (COLOR_WHITE); - (void) textcolor (COLOR_BLACK); -#endif - cursor (0); - clrscr (); - -#if defined(__C64__) || defined(__C128__) - /* Copy the sprite data. */ - memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite); - - /* Set the VIC-II sprite pointer. */ - *SPRITE0_PTR = ((unsigned) SPRITE0_DATA & 0x3FFF) / sizeof SPRITE0_DATA; - - /* Set the color of sprite 0. */ - VIC.spr0_color = COLOR_BLACK; - - pen_adjust ("inkwell.dat"); -#endif - -#if DYN_DRV - /* Output a warning about the driver that is needed. */ - DoWarning (); - - /* Load and install the lightpen driver. */ - CheckError ("mouse_load_driver", - mouse_load_driver (&mouse_def_callbacks, mouse_stddrv)); -#else - /* Install the lightpen driver. */ - CheckError ("mouse_install", - mouse_install (&mouse_def_callbacks, mouse_static_stddrv)); -#endif - - /* Get the initial lightpen bounding box. */ - mouse_getbox (&full_box); - - screensize (&width, &height); - -top: - clrscr (); - - /* Print a help line. */ - cputs (" d)ebug h)ide q)uit s)how j)ail"); - - /* Put a cross at the center of the screen. */ - gotoxy (width / 2 - 3, height / 2 - 1); - cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, - width / 2, ""); - - /* Expose the arrow. */ - mouse_show (); - ShowState (Jailed, Invisible); - - /* Test loop */ - do { - /* Get the current lightpen co-ordinates and button states; - ** and, print them. - */ - mouse_info (&info); - gotoxy (0, 2); - cprintf (" X = %3d\r\n", info.pos.x); - cprintf (" Y = %3d\r\n", info.pos.y); - cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? -#ifdef __CBM__ - 0x5F -#else - 'v' -#endif - : '^'); - cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? -#ifdef __CBM__ - 0x5F -#else - 'v' -#endif - : '^'); - - /* Handle user input. */ - if (kbhit ()) { - cclearxy (1, 9, 23); - switch (tolower (C = cgetc ())) { - case 'd': - BREAK(); - - /* The debugger might have changed the colors. - ** Restore them. - */ -#ifdef __CBM__ - (void) bordercolor (COLOR_GRAY2); - (void) bgcolor (COLOR_WHITE); - (void) textcolor (COLOR_GRAY1); -#else - (void) bordercolor (COLOR_BLUE); - (void) bgcolor (COLOR_WHITE); - (void) textcolor (COLOR_BLACK); -#endif - goto top; - - case 'h': - mouse_hide (); - ShowState (Jailed, ++Invisible); - break; - - case 'j': - if (Jailed) { - mouse_setbox (&full_box); - Jailed = false; - } else { - small_box.minx = max (info.pos.x - 10, full_box.minx); - small_box.miny = max (info.pos.y - 10, full_box.miny); - small_box.maxx = min (info.pos.x + 10, full_box.maxx); - small_box.maxy = min (info.pos.y + 10, full_box.maxy); - mouse_setbox (&small_box); - Jailed = true; - } - ShowState (Jailed, Invisible); - break; - - case 's': - mouse_show (); - if (Invisible) { - ShowState (Jailed, --Invisible); - } - break; - - case 'q': - Done = true; - break; - - default: - gotoxy (1, 9); - cprintf ("Spurious character: $%02X", C); - } - } - } while (!Done); - -#if DYN_DRV - /* Uninstall and unload the lightpen driver. */ - CheckError ("mouse_unload", mouse_unload ()); -#else - /* Uninstall the lightpen driver. */ - CheckError ("mouse_uninstall", mouse_uninstall ()); -#endif - - /* Say goodbye. */ - cputsxy (0, height / 2 + 3, "Goodbye!"); - return EXIT_SUCCESS; -} From 42301b78ce8696759cd18f29ae25c6764c1b80eb Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 28 Jun 2013 06:36:32 -0400 Subject: [PATCH 06/12] Included a header that defines NULL. --- libsrc/cbm/penadjust.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/cbm/penadjust.c b/libsrc/cbm/penadjust.c index 104c33c8d..f33b3a275 100755 --- a/libsrc/cbm/penadjust.c +++ b/libsrc/cbm/penadjust.c @@ -5,6 +5,7 @@ */ +#include #include #include #include From 078a1df2f68f80dc3106201d8e8e0bd66db9f2d7 Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 5 Jul 2013 12:32:19 -0400 Subject: [PATCH 07/12] Look for NULL pointer more efficiently. --- libsrc/c128/mou/c128-inkwell.s | 17 +++++++++-------- libsrc/c64/mou/c64-inkwell.s | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index 4cd009f2c..dc3469aac 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -1,7 +1,7 @@ ; ; Driver for the Inkwell Systems 170-C and 184-C lightpens. ; -; 2013-06-17, Greg King +; 2013-07-01, Greg King ; .include "zeropage.inc" @@ -148,14 +148,13 @@ INSTALL: ldx LIBREF+1 sta ptr1 ; Point to mouse_adjuster stx ptr1+1 - ldy #0 + ldy #1 lda (ptr1),y - sta Calibrate+1 ; Point to function - iny + bze @L1 ; Don't call pointer if it's NULL + sta Calibrate+2 ; Point to function + dey lda (ptr1),y - sta Calibrate+2 - ora Calibrate+1 ; Don't call pointer if it's NULL - bze @L1 + sta Calibrate+1 lda #XOffset jsr Calibrate @@ -164,7 +163,8 @@ INSTALL: ; It needs to be done here because the lightpen interrupt handler doesn't ; set the lightpen position if it hasn't changed. -@L1: jsr CHIDE +@L1: sei + jsr CHIDE lda #<(SCREEN_HEIGHT / 2) ldx #>(SCREEN_HEIGHT / 2) @@ -172,6 +172,7 @@ INSTALL: lda #<(SCREEN_WIDTH / 2) ldx #>(SCREEN_WIDTH / 2) jsr MoveX + cli ; Done, return zero. diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s index 367be6105..070d8f108 100644 --- a/libsrc/c64/mou/c64-inkwell.s +++ b/libsrc/c64/mou/c64-inkwell.s @@ -1,7 +1,7 @@ ; ; Driver for the Inkwell Systems 170-C and 184-C lightpens. ; -; 2013-06-17, Greg King +; 2013-07-01, Greg King ; .include "zeropage.inc" @@ -133,14 +133,13 @@ INSTALL: ldx LIBREF+1 sta ptr1 ; Point to mouse_adjuster stx ptr1+1 - ldy #0 + ldy #1 lda (ptr1),y - sta Calibrate+1 ; Point to function - iny + bze @L1 ; Don't call pointer if it's NULL + sta Calibrate+2 ; Point to function + dey lda (ptr1),y - sta Calibrate+2 - ora Calibrate+1 ; Don't call pointer if it's NULL - bze @L1 + sta Calibrate+1 lda #XOffset jsr Calibrate @@ -149,7 +148,8 @@ INSTALL: ; It needs to be done here because the lightpen interrupt handler doesn't ; set the lightpen position if it hasn't changed. -@L1: jsr CHIDE +@L1: sei + jsr CHIDE lda #<(SCREEN_HEIGHT / 2) ldx #>(SCREEN_HEIGHT / 2) @@ -157,6 +157,7 @@ INSTALL: lda #<(SCREEN_WIDTH / 2) ldx #>(SCREEN_WIDTH / 2) jsr MoveX + cli ; Done, return zero. From 641a609cf332bb4372a5d76a167724f5c0951086 Mon Sep 17 00:00:00 2001 From: Greg King Date: Tue, 16 Jul 2013 00:30:56 -0400 Subject: [PATCH 08/12] Moved common symbol names out of sources, and into a global include file. --- asminc/atmos.inc | 63 ++++++++++++++++++++++++++---- libsrc/atmos/joy/atmos-pase.s | 31 +++++++-------- libsrc/atmos/mainargs.s | 16 ++++---- libsrc/atmos/ser/atmos-acia.s | 41 ++++++++----------- libsrc/atmos/tgi/atmos-228-200-3.s | 18 +-------- libsrc/atmos/tgi/atmos-240-200-2.s | 28 ++++--------- 6 files changed, 105 insertions(+), 92 deletions(-) diff --git a/asminc/atmos.inc b/asminc/atmos.inc index 446f2e11c..9ab50931d 100644 --- a/asminc/atmos.inc +++ b/asminc/atmos.inc @@ -1,32 +1,81 @@ ; -; Oric atmos zeropage and ROM definitions +; Oric Atmos definitions +; BASIC 1.1 addresses ; +; --------------------------------------------------------------------------- +; Constants + +FNAME_LEN = 16 ; maximum length of file-name + + ; --------------------------------------------------------------------------- ; Zero page +BASIC_BUF := $35 ; --------------------------------------------------------------------------- ; Low memory CAPSLOCK := $20C +PATTERN := $213 IRQVec := $245 CURS_Y := $268 CURS_X := $269 STATUS := $26A TIMER3 := $276 +CFOUND_NAME := $293 KEYBUF := $2DF +PARAM1 := $2E1 ; & $2E2 +PARAM2 := $2E3 ; & $2E4 +PARAM3 := $2E5 ; & $2E6 + + +; --------------------------------------------------------------------------- +; I/O locations + +; 6522 +.struct VIA ; Versatile Interface Adapter + .res $0300 +PRB .byte ; Port Register B +PRA .byte ; Port Register A +DDRB .byte ; Data Direction Register B +DDRA .byte ; Data Direction Register A +T1 .word ; Timer 1 +T1L .word ; Timer 1 Latch +T2 .word ; Timer 2 +SR .byte ; Shift Register +ACR .byte ; Auxiliary Control Register +PCR .byte ; Peripheral Control Register +IFR .byte ; Interrupt Flags Register +IER .byte ; Interrupt Enable Register +PRA2 .byte ; Port Register A without handshaking +.endstruct + +; 6551 +.struct ACIA ; Asynchronous Communications Interface Adapter + .res $031C +DATA .byte +STATUS .byte +CMD .byte ; Command register +CTRL .byte ; Control register +.endstruct + +SCREEN := $BB80 ; --------------------------------------------------------------------------- ; ROM entries +TEXT := $EC21 +HIRES := $EC33 +CURSET := $F0C8 +CURMOV := $F0FD +DRAW := $F110 +CHAR := $F12D +POINT := $F1C8 +PAPER := $F204 +INK := $F210 PRINT := $F77C - - -; --------------------------------------------------------------------------- -; I/O - -SCREEN := $BB80 diff --git a/libsrc/atmos/joy/atmos-pase.s b/libsrc/atmos/joy/atmos-pase.s index c505a1b0f..0c657584b 100644 --- a/libsrc/atmos/joy/atmos-pase.s +++ b/libsrc/atmos/joy/atmos-pase.s @@ -1,14 +1,15 @@ ; ; P.A.S.E. joystick driver for the Atmos -; May be used multiple times when linked to the statically application. +; Can be used multiple times when statically linked to the application. ; -; Stefan Haubenthal, 2009-12-21 -; Based on Ullrich von Bassewitz, 2002-12-20 +; 2002-12-20, Based on Ullrich von Bassewitz's code. +; 2009-12-21, Stefan Haubenthal +; 2013-07-15, Greg King ; .include "joy-kernel.inc" .include "joy-error.inc" -; .include "atmos.inc" + .include "atmos.inc" ; ------------------------------------------------------------------------ @@ -49,10 +50,6 @@ JOY_COUNT = 2 ; Number of joysticks we support -PRA = $0301 -DDRA = $0303 -PRA2 = $030F - ; ------------------------------------------------------------------------ ; Data. @@ -99,24 +96,24 @@ COUNT: READ: tay - lda PRA + lda VIA::PRA pha - lda DDRA + lda VIA::DDRA pha lda #%11000000 - sta DDRA + sta VIA::DDRA lda #%10000000 - sta PRA2 - lda PRA2 + sta VIA::PRA2 + lda VIA::PRA2 sta temp1 lda #%01000000 - sta PRA2 - lda PRA + sta VIA::PRA2 + lda VIA::PRA sta temp2 pla - sta DDRA + sta VIA::DDRA pla - sta PRA2 + sta VIA::PRA2 ldx #0 tya diff --git a/libsrc/atmos/mainargs.s b/libsrc/atmos/mainargs.s index 3e1f6467b..42a94da51 100644 --- a/libsrc/atmos/mainargs.s +++ b/libsrc/atmos/mainargs.s @@ -1,19 +1,19 @@ ; -; Ullrich von Bassewitz, 2003-03-07 -; Stefan Haubenthal, 2011-01-28 +; 2003-03-07, Ullrich von Bassewitz +; 2011-01-28, Stefan Haubenthal +; 2013-07-15, Greg King ; ; Setup arguments for main ; .constructor initmainargs, 24 .import __argc, __argv + + .include "atmos.inc" .macpack generic MAXARGS = 10 ; Maximum number of arguments allowed REM = $9d ; BASIC token-code -NAME_LEN = 16 ; maximum length of command-name -BASIC_BUF = $35 -FNAM = $293 ;--------------------------------------------------------------------------- @@ -29,8 +29,8 @@ FNAM = $293 ; Because the buffer, that we're copying into, was zeroed out, ; we don't need to add a NUL character. ; - ldy #NAME_LEN - 1 ; limit the length -L0: lda FNAM,y + ldy #FNAME_LEN - 1 ; limit the length +L0: lda CFOUND_NAME,y sta name,y dey bpl L0 @@ -114,7 +114,7 @@ done: lda # -; 2012-08-11, Greg King +; 2013-07-15, Greg King ; .include "zeropage.inc" @@ -79,21 +79,7 @@ ERROR: .res 1 ; Error code MODE: .res 1 ; Graphics mode PALETTE: .res 2 -; Constants and table -; BASIC 1.1 addresses -PATTERN := $213 -PARAM1 := $2E1 ; & $2E2 -PARAM2 := $2E3 ; & $2E4 -PARAM3 := $2E5 ; & $2E6 -TEXT := $EC21 -HIRES := $EC33 -CURSET := $F0C8 -CURMOV := $F0FD -DRAW := $F110 -CHAR := $F12D -POINT := $F1C8 -PAPER := $F204 -INK := $F210 +; Constant table .rodata diff --git a/libsrc/atmos/tgi/atmos-240-200-2.s b/libsrc/atmos/tgi/atmos-240-200-2.s index e58ac36d2..b5e0463d7 100644 --- a/libsrc/atmos/tgi/atmos-240-200-2.s +++ b/libsrc/atmos/tgi/atmos-240-200-2.s @@ -2,7 +2,7 @@ ; Graphics driver for the 240x200x2 monochrome mode on the Atmos ; ; Stefan Haubenthal -; 2012-08-11, Greg King +; 2013-07-15, Greg King ; .include "zeropage.inc" @@ -66,10 +66,10 @@ YSIZE = 8 ; System font height ; Variables mapped to the zero page segment variables. Some of these are ; used for passing parameters to the driver. -X1 = ptr1 -Y1 = ptr2 -X2 = ptr3 -Y2 = ptr4 +X1 := ptr1 +Y1 := ptr2 +X2 := ptr3 +Y2 := ptr4 ; Absolute variables used in the code @@ -78,19 +78,7 @@ Y2 = ptr4 ERROR: .res 1 ; Error code MODE: .res 1 ; Graphics mode -; Constants and tables -PARAM1 = $2E1 -PARAM2 = $2E3 -PARAM3 = $2E5 -TEXT = $EC21 -HIRES = $EC33 -CURSET = $F0C8 -CURMOV = $F0FD -DRAW = $F110 -CHAR = $F12D -POINT = $F1C8 -PAPER = $F204 -INK = $F210 +; Constant table .rodata @@ -152,7 +140,7 @@ INIT: ; Must set an error code: NO ; -DONE = TEXT +DONE := TEXT ; ------------------------------------------------------------------------ ; GETERROR: Return the error code in A and clear it. @@ -181,7 +169,7 @@ CONTROL: ; Must set an error code: NO ; -CLEAR = HIRES +CLEAR := HIRES ; ------------------------------------------------------------------------ ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n). From 3574f3a742d67e688c4db59876cb26815662ee71 Mon Sep 17 00:00:00 2001 From: Greg King Date: Tue, 16 Jul 2013 01:48:57 -0400 Subject: [PATCH 09/12] Normalized some hexadecimal addresses. --- asminc/atmos.inc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/asminc/atmos.inc b/asminc/atmos.inc index 9ab50931d..ea6669243 100644 --- a/asminc/atmos.inc +++ b/asminc/atmos.inc @@ -19,18 +19,18 @@ BASIC_BUF := $35 ; --------------------------------------------------------------------------- ; Low memory -CAPSLOCK := $20C -PATTERN := $213 -IRQVec := $245 -CURS_Y := $268 -CURS_X := $269 -STATUS := $26A -TIMER3 := $276 -CFOUND_NAME := $293 -KEYBUF := $2DF -PARAM1 := $2E1 ; & $2E2 -PARAM2 := $2E3 ; & $2E4 -PARAM3 := $2E5 ; & $2E6 +CAPSLOCK := $020C +PATTERN := $0213 +IRQVec := $0245 +CURS_Y := $0268 +CURS_X := $0269 +STATUS := $026A +TIMER3 := $0276 +CFOUND_NAME := $0293 +KEYBUF := $02DF +PARAM1 := $02E1 ; & $02E2 +PARAM2 := $02E3 ; & $02E4 +PARAM3 := $02E5 ; & $02E6 ; --------------------------------------------------------------------------- From 3b544613d27fe80844e6ab8fc66e7cdb630fcdae Mon Sep 17 00:00:00 2001 From: Greg King Date: Thu, 25 Jul 2013 13:32:40 -0400 Subject: [PATCH 10/12] Moved the lightpen names from to a new . Renamed the adjuster pointer. --- include/mouse.h | 24 ------------- include/pen.h | 78 ++++++++++++++++++++++++++++++++++++++++++ libsrc/c128/mouseref.s | 8 ++--- libsrc/c128/pencalib.c | 3 +- libsrc/c64/mouseref.s | 8 ++--- libsrc/c64/pencalib.c | 3 +- libsrc/cbm/penadjust.c | 10 +++--- samples/mousetest.c | 3 +- 8 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 include/pen.h mode change 100755 => 100644 libsrc/cbm/penadjust.c diff --git a/include/mouse.h b/include/mouse.h index bc93f8b8c..5e69c7ff6 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -118,13 +118,6 @@ extern const char mouse_stddrv[]; /* The address of the static standard mouse driver for a platform */ 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); - /*****************************************************************************/ @@ -201,23 +194,6 @@ unsigned char __fastcall__ mouse_ioctl (unsigned char code, void* data); * 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. - */ - /* End of mouse.h */ diff --git a/include/pen.h b/include/pen.h new file mode 100644 index 000000000..bab6997df --- /dev/null +++ b/include/pen.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* pen.h */ +/* */ +/* Lightpen API */ +/* */ +/* */ +/* This software is provided "as-is", without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated, but is not required. */ +/* 2. Altered source versions must be marked plainly as such; and, must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _PEN_H +#define _PEN_H + + + +/*****************************************************************************/ +/* Declarations */ +/*****************************************************************************/ + + + +/* 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. +** pen_adjuster must be set before the driver is installed. +*/ +extern void __fastcall__ (*pen_adjuster) (unsigned char *pValue); + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + + +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 pen_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 pen_adjuster pointer. The file will be read only when a driver + * is installed, and only if that driver wants to be calibrated. + */ + + + +/* End of pen.h */ +#endif + + + diff --git a/libsrc/c128/mouseref.s b/libsrc/c128/mouseref.s index fb83c439f..9b18a1f08 100644 --- a/libsrc/c128/mouseref.s +++ b/libsrc/c128/mouseref.s @@ -1,10 +1,10 @@ ; ; Pointer for library references by device drivers. ; -; 2013-06-23, Greg King +; 2013-07-25, Greg King ; - .export mouse_libref, _mouse_adjuster + .export mouse_libref, _pen_adjuster .data @@ -17,7 +17,7 @@ mouse_libref: ; generic label for mouse-kernel ; 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; +; void __fastcall__ (*pen_adjuster)(unsigned char *) = NULL; ; -_mouse_adjuster: +_pen_adjuster: .addr $0000 diff --git a/libsrc/c128/pencalib.c b/libsrc/c128/pencalib.c index cf9a3f92b..7fb342f4d 100644 --- a/libsrc/c128/pencalib.c +++ b/libsrc/c128/pencalib.c @@ -1,13 +1,14 @@ /* ** Calibrate lightpen drivers to the current video hardware. ** -** 2013-06-17, Greg King +** 2013-07-25, Greg King ** */ #include #include +#include #define COMMAND1 "Adjust by clicking on line." diff --git a/libsrc/c64/mouseref.s b/libsrc/c64/mouseref.s index fb83c439f..9b18a1f08 100644 --- a/libsrc/c64/mouseref.s +++ b/libsrc/c64/mouseref.s @@ -1,10 +1,10 @@ ; ; Pointer for library references by device drivers. ; -; 2013-06-23, Greg King +; 2013-07-25, Greg King ; - .export mouse_libref, _mouse_adjuster + .export mouse_libref, _pen_adjuster .data @@ -17,7 +17,7 @@ mouse_libref: ; generic label for mouse-kernel ; 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; +; void __fastcall__ (*pen_adjuster)(unsigned char *) = NULL; ; -_mouse_adjuster: +_pen_adjuster: .addr $0000 diff --git a/libsrc/c64/pencalib.c b/libsrc/c64/pencalib.c index d0e6b0ff2..587c5627e 100644 --- a/libsrc/c64/pencalib.c +++ b/libsrc/c64/pencalib.c @@ -1,13 +1,14 @@ /* ** Calibrate lightpen drivers to the current video hardware. ** -** 2013-06-17, Greg King +** 2013-07-25, Greg King ** */ #include #include +#include #define COMMAND1 "Adjust by clicking on line." diff --git a/libsrc/cbm/penadjust.c b/libsrc/cbm/penadjust.c old mode 100755 new mode 100644 index f33b3a275..dc1ffe129 --- a/libsrc/cbm/penadjust.c +++ b/libsrc/cbm/penadjust.c @@ -1,14 +1,14 @@ /* ** Main lightpen driver calibration functions. ** -** 2013-06-23, Greg King +** 2013-07-25, Greg King */ #include #include #include -#include +#include static const char *name; @@ -40,15 +40,15 @@ static void __fastcall__ adjuster (unsigned char *XOffset) /* 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 +** the pen_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; + pen_adjuster = adjuster; } else { - mouse_adjuster = pen_calibrate; + pen_adjuster = pen_calibrate; } } diff --git a/samples/mousetest.c b/samples/mousetest.c index b2d49b072..dd90e0990 100644 --- a/samples/mousetest.c +++ b/samples/mousetest.c @@ -3,7 +3,7 @@ ** Will work for the C64/C128/CBM510/Atari/Apple2. ** ** 2001-09-13, Ullrich von Bassewitz -** 2013-06-26, Greg King +** 2013-07-25, Greg King ** */ @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include From 17333e4732e679cc85d87c2dd9a8febd1752f2cf Mon Sep 17 00:00:00 2001 From: Greg King Date: Thu, 25 Jul 2013 13:53:15 -0400 Subject: [PATCH 11/12] Fixed some line endings. My Git and repositories are configured for POSIX; but sometimes, Windows line endings "sneak" into new files. --- libsrc/c128/mouseref.s | 46 +++++----- libsrc/c128/pencalib.c | 186 ++++++++++++++++++++-------------------- libsrc/c64/mouseref.s | 46 +++++----- libsrc/c64/pencalib.c | 188 ++++++++++++++++++++--------------------- libsrc/cbm/penadjust.c | 108 +++++++++++------------ 5 files changed, 287 insertions(+), 287 deletions(-) diff --git a/libsrc/c128/mouseref.s b/libsrc/c128/mouseref.s index 9b18a1f08..90aeedf3a 100644 --- a/libsrc/c128/mouseref.s +++ b/libsrc/c128/mouseref.s @@ -1,23 +1,23 @@ -; -; Pointer for library references by device drivers. -; -; 2013-07-25, Greg King -; - - .export mouse_libref, _pen_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__ (*pen_adjuster)(unsigned char *) = NULL; -; -_pen_adjuster: - .addr $0000 +; +; Pointer for library references by device drivers. +; +; 2013-07-25, Greg King +; + + .export mouse_libref, _pen_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__ (*pen_adjuster)(unsigned char *) = NULL; +; +_pen_adjuster: + .addr $0000 diff --git a/libsrc/c128/pencalib.c b/libsrc/c128/pencalib.c index 7fb342f4d..b7bd701ec 100644 --- a/libsrc/c128/pencalib.c +++ b/libsrc/c128/pencalib.c @@ -1,93 +1,93 @@ -/* -** Calibrate lightpen drivers to the current video hardware. -** -** 2013-07-25, Greg King -** -*/ - - -#include -#include -#include - - -#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 (); -} +/* +** Calibrate lightpen drivers to the current video hardware. +** +** 2013-07-25, Greg King +** +*/ + + +#include +#include +#include + + +#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 (); +} diff --git a/libsrc/c64/mouseref.s b/libsrc/c64/mouseref.s index 9b18a1f08..90aeedf3a 100644 --- a/libsrc/c64/mouseref.s +++ b/libsrc/c64/mouseref.s @@ -1,23 +1,23 @@ -; -; Pointer for library references by device drivers. -; -; 2013-07-25, Greg King -; - - .export mouse_libref, _pen_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__ (*pen_adjuster)(unsigned char *) = NULL; -; -_pen_adjuster: - .addr $0000 +; +; Pointer for library references by device drivers. +; +; 2013-07-25, Greg King +; + + .export mouse_libref, _pen_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__ (*pen_adjuster)(unsigned char *) = NULL; +; +_pen_adjuster: + .addr $0000 diff --git a/libsrc/c64/pencalib.c b/libsrc/c64/pencalib.c index 587c5627e..00629d512 100644 --- a/libsrc/c64/pencalib.c +++ b/libsrc/c64/pencalib.c @@ -1,94 +1,94 @@ -/* -** Calibrate lightpen drivers to the current video hardware. -** -** 2013-07-25, Greg King -** -*/ - - -#include -#include -#include - - -#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 (); -} +/* +** Calibrate lightpen drivers to the current video hardware. +** +** 2013-07-25, Greg King +** +*/ + + +#include +#include +#include + + +#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 (); +} diff --git a/libsrc/cbm/penadjust.c b/libsrc/cbm/penadjust.c index dc1ffe129..8b788dd33 100644 --- a/libsrc/cbm/penadjust.c +++ b/libsrc/cbm/penadjust.c @@ -1,54 +1,54 @@ -/* -** Main lightpen driver calibration functions. -** -** 2013-07-25, Greg King -*/ - - -#include -#include -#include -#include - - -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 pen_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; - pen_adjuster = adjuster; - } else { - pen_adjuster = pen_calibrate; - } -} +/* +** Main lightpen driver calibration functions. +** +** 2013-07-25, Greg King +*/ + + +#include +#include +#include +#include + + +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 pen_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; + pen_adjuster = adjuster; + } else { + pen_adjuster = pen_calibrate; + } +} From f02843f05d3478b8ef13b4cac90205dec4f204f3 Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 26 Jul 2013 03:33:54 -0400 Subject: [PATCH 12/12] Replaced number literals in source code with meaningful symbol names. --- asminc/atmos.inc | 13 +++++++++++++ libsrc/atmos/_scrsize.s | 8 +++++--- libsrc/atmos/atmos_load.s | 16 ++++++++++------ libsrc/atmos/atmos_save.s | 18 +++++++++++------- libsrc/atmos/cgetc.s | 8 ++++---- libsrc/atmos/clrscr.s | 7 ++++--- libsrc/atmos/cputc.s | 13 +++++++------ libsrc/atmos/store_filename.s | 8 ++++++-- libsrc/atmos/tgi/atmos-240-200-2.s | 4 ++-- 9 files changed, 62 insertions(+), 33 deletions(-) diff --git a/asminc/atmos.inc b/asminc/atmos.inc index ea6669243..20bb806f1 100644 --- a/asminc/atmos.inc +++ b/asminc/atmos.inc @@ -7,6 +7,11 @@ ; --------------------------------------------------------------------------- ; Constants +SCREEN_XSIZE = 40 ; screen columns +SCREEN_YSIZE = 28 ; screen rows + +FUNCTKEY = $A5 + FNAME_LEN = 16 ; maximum length of file-name @@ -19,14 +24,22 @@ BASIC_BUF := $35 ; --------------------------------------------------------------------------- ; Low memory +MODEKEY := $0209 CAPSLOCK := $020C PATTERN := $0213 IRQVec := $0245 +JOINFLAG := $025A ; 0 = don't joiu, $4A = join BASIC programs +VERIFYFLAG := $025B ; 0 = load, 1 = verify CURS_Y := $0268 CURS_X := $0269 STATUS := $026A TIMER3 := $0276 +CFILE_NAME := $027F CFOUND_NAME := $0293 +FILESTART := $02A9 +FILEEND := $02AB +AUTORUN := $02AD ; $00 = only load, $C7 = autorun +LANGFLAG := $02AE ; $00 = BASIC, $80 = machine code KEYBUF := $02DF PARAM1 := $02E1 ; & $02E2 PARAM2 := $02E3 ; & $02E4 diff --git a/libsrc/atmos/_scrsize.s b/libsrc/atmos/_scrsize.s index 2dd58399d..7a7af33ee 100644 --- a/libsrc/atmos/_scrsize.s +++ b/libsrc/atmos/_scrsize.s @@ -1,15 +1,17 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-16, Greg King ; ; Screen size variables ; .export screensize + .include "atmos.inc" .proc screensize - ldx #40 - ldy #28 + ldx #SCREEN_XSIZE + ldy #SCREEN_YSIZE rts .endproc diff --git a/libsrc/atmos/atmos_load.s b/libsrc/atmos/atmos_load.s index 9e86373f3..b5bec3225 100644 --- a/libsrc/atmos/atmos_load.s +++ b/libsrc/atmos/atmos_load.s @@ -1,20 +1,24 @@ -; Stefan Haubenthal, 2012-05-06 -; based on code by Twilighte +; Based on code by Twilighte. +; 2012-05-06, Stefan Haubenthal +; 2013-07-22, Greg King +; ; void __fastcall__ atmos_load(const char* name); .export _atmos_load .import store_filename + .include "atmos.inc" + .proc _atmos_load sei jsr store_filename ldx #$00 - stx $02ad - stx $02ae - stx $025a - stx $025b + stx AUTORUN ; don't try to run the file + stx LANGFLAG ; BASIC + stx JOINFLAG ; don't join it to another BASIC program + stx VERIFYFLAG ; load the file jsr cload_bit cli rts diff --git a/libsrc/atmos/atmos_save.s b/libsrc/atmos/atmos_save.s index 0bd9e29cc..3d221f6fa 100644 --- a/libsrc/atmos/atmos_save.s +++ b/libsrc/atmos/atmos_save.s @@ -1,23 +1,27 @@ -; Stefan Haubenthal, 2012-05-06 -; based on code by Twilighte +; Based on code by Twilighte. +; 2012-05-06, Stefan Haubenthal +; 2013-07-22, Greg King +; ; void __fastcall__ atmos_save(const char* name, const void* start, const void* end); .export _atmos_save .import popax, store_filename + .include "atmos.inc" + .proc _atmos_save sei - sta $02ab ; file end lo - stx $02ac ; file end hi + sta FILEEND + stx FILEEND+1 jsr popax - sta $02a9 ; file start lo - stx $02aa ; file start hi + sta FILESTART + stx FILESTART+1 jsr popax jsr store_filename lda #00 - sta $02ad + sta AUTORUN jsr csave_bit cli rts diff --git a/libsrc/atmos/cgetc.s b/libsrc/atmos/cgetc.s index 38e7aa873..e13d143d2 100644 --- a/libsrc/atmos/cgetc.s +++ b/libsrc/atmos/cgetc.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-26, Greg King ; ; char cgetc (void); ; @@ -11,7 +12,6 @@ .include "atmos.inc" - ; ------------------------------------------------------------------------ ; @@ -41,8 +41,8 @@ @L2: and #$7F ; Mask out avail flag sta KEYBUF - ldy $209 - cpy #$A5 + ldy MODEKEY + cpy #FUNCTKEY bne @L3 ora #$80 ; FUNCT pressed diff --git a/libsrc/atmos/clrscr.s b/libsrc/atmos/clrscr.s index 9dce665e9..2230d6e0a 100644 --- a/libsrc/atmos/clrscr.s +++ b/libsrc/atmos/clrscr.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-16, Greg King ; .export _clrscr @@ -27,7 +28,7 @@ ; Clear full pages. Y is still zero - ldx #>(28*40) + ldx #>(SCREEN_YSIZE * SCREEN_XSIZE) lda #' ' @L1: sta (ptr2),y iny ; Bump low byte of address @@ -40,7 +41,7 @@ @L2: sta (ptr2),y iny - cpy #<(28*40) + cpy #<(SCREEN_YSIZE * SCREEN_XSIZE) bne @L2 rts diff --git a/libsrc/atmos/cputc.s b/libsrc/atmos/cputc.s index 9f65be500..a0ef14b70 100644 --- a/libsrc/atmos/cputc.s +++ b/libsrc/atmos/cputc.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-16, Greg King ; ; void cputcxy (unsigned char x, unsigned char y, char c); ; void cputc (char c); @@ -41,7 +42,7 @@ output: advance: iny - cpy #40 + cpy #SCREEN_XSIZE bne L3 inc CURS_Y ; new line ldy #0 ; + cr @@ -85,12 +86,12 @@ L3: sty CURS_X .rodata ScrTabLo: - .repeat 28, Line - .byte <(SCREEN + Line * 40) + .repeat SCREEN_YSIZE, Line + .byte <(SCREEN + Line * SCREEN_XSIZE) .endrep ScrTabHi: - .repeat 28, Line - .byte >(SCREEN + Line * 40) + .repeat SCREEN_YSIZE, Line + .byte >(SCREEN + Line * SCREEN_XSIZE) .endrep diff --git a/libsrc/atmos/store_filename.s b/libsrc/atmos/store_filename.s index cb6d8b933..41d1837f1 100644 --- a/libsrc/atmos/store_filename.s +++ b/libsrc/atmos/store_filename.s @@ -1,12 +1,16 @@ +; Helper function + .export store_filename .importzp ptr1 + .include "atmos.inc" + store_filename: sta ptr1 stx ptr1+1 - ldy #$0f ;store filename + ldy #FNAME_LEN - 1 ; store filename : lda (ptr1),y - sta $027f,y + sta CFILE_NAME,y dey bpl :- rts diff --git a/libsrc/atmos/tgi/atmos-240-200-2.s b/libsrc/atmos/tgi/atmos-240-200-2.s index b5e0463d7..762c7c02d 100644 --- a/libsrc/atmos/tgi/atmos-240-200-2.s +++ b/libsrc/atmos/tgi/atmos-240-200-2.s @@ -2,7 +2,7 @@ ; Graphics driver for the 240x200x2 monochrome mode on the Atmos ; ; Stefan Haubenthal -; 2013-07-15, Greg King +; 2013-07-16, Greg King ; .include "zeropage.inc" @@ -158,7 +158,7 @@ GETERROR: ; CONTROL: - sta $213 + sta PATTERN lda #TGI_ERR_OK sta ERROR rts