diff --git a/asminc/atari.inc b/asminc/atari.inc index c60f6642d..da926af81 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -318,7 +318,7 @@ APPMHI = $0E ;APPLICATIONS MEMORY HI LIMIT INTZBS = $10 ;INTERRUPT HANDLER -POKMSK = $10 ;SYSTEM MASK FOR POKEY IRG ENABLE +POKMSK = $10 ;SYSTEM MASK FOR POKEY IRQ ENABLE BRKKEY = $11 ;BREAK KEY FLAG RTCLOK = $12 ;REAL TIME CLOCK (IN 16 MSEC UNITS> BUFADR = $15 ;INDIRECT BUFFER ADDRESS REGISTER @@ -485,10 +485,10 @@ VKEYBD = $0208 ;POKEY KEYBOARD IRQ VECTOR VSERIN = $020A ;POKEY SERIAL INPUT READY IRQ VSEROR = $020C ;POKEY SERIAL OUTPUT READY IRQ VSEROC = $020E ;POKEY SERIAL OUTPUT COMPLETE IRQ -VTIMR1 = $0210 ;POKEY TIMER 1 IRG -VTIMR2 = $0212 ;POKEY TIMER 2 IRG -VTIMR4 = $0214 ;POKEY TIMER 4 IRG -VIMIRQ = $0216 ;IMMEDIATE IRG VECTOR +VTIMR1 = $0210 ;POKEY TIMER 1 IRQ +VTIMR2 = $0212 ;POKEY TIMER 2 IRQ +VTIMR4 = $0214 ;POKEY TIMER 4 IRQ +VIMIRQ = $0216 ;IMMEDIATE IRQ VECTOR CDTMV1 = $0218 ;COUNT DOWN TIMER 1 CDTMV2 = $021A ;COUNT DOWN TIMER 2 CDTMV3 = $021C ;COUNT DOWN TIMER 3 diff --git a/libsrc/atari/irq.s b/libsrc/atari/irq.s index 8ec1b12df..9f12d47ed 100644 --- a/libsrc/atari/irq.s +++ b/libsrc/atari/irq.s @@ -16,11 +16,11 @@ .segment "INIT" initirq: - lda VVBLKI - ldx VVBLKI+1 + lda VVBLKD + ldx VVBLKD+1 sta IRQInd+1 stx IRQInd+2 - lda #6 + lda #7 ldy #IRQStub jsr SETVBV @@ -31,7 +31,7 @@ initirq: .code doneirq: - lda #6 + lda #7 ldy IRQInd+1 ldx IRQInd+2 jsr SETVBV @@ -44,7 +44,6 @@ doneirq: IRQStub: cld ; Just to be sure .ifdef __ATARIXL__ - pha .ifdef CHARGEN_RELOC lda CHBAS pha @@ -64,7 +63,6 @@ IRQStub: sta CHBAS sta CHBASE .endif - pla .endif jmp IRQInd ; Jump to the saved IRQ vector diff --git a/libsrc/atari/libref.s b/libsrc/atari/libref.s index 8d96ff62d..4f7cbbef6 100644 --- a/libsrc/atari/libref.s +++ b/libsrc/atari/libref.s @@ -2,7 +2,7 @@ ; Oliver Schmidt, 2013-05-31 ; - .export em_libref, joy_libref, tgi_libref, ser_libref + .export em_libref, joy_libref, tgi_libref, ser_libref, mouse_libref .import _exit .import atari_ser_libref @@ -12,6 +12,9 @@ ser_libref := atari_ser_libref .ifdef __ATARIXL__ .import CIO_handler tgi_libref := CIO_handler + .import set_VTIMR1_handler +mouse_libref := set_VTIMR1_handler .else +mouse_libref := _exit tgi_libref := _exit .endif diff --git a/libsrc/atari/mcbdefault.s b/libsrc/atari/mcbdefault.s new file mode 100644 index 000000000..ac5056cf9 --- /dev/null +++ b/libsrc/atari/mcbdefault.s @@ -0,0 +1,126 @@ +; +; Default mouse callbacks for the Ataris +; +; Christian Groessler, 03.01.2014 +; +; derived from Apple2 version by +; Oliver Schmidt, 22.09.2005 +; +; All functions in this module should be interrupt safe, because they may +; be called from an interrupt handler +; + + .export _mouse_def_callbacks + .importzp tmp4 + .import mul40,loc_tmp + + .include "atari.inc" + +; ------------------------------------------------------------------------ + + .bss + +backup: .res 1 +visible:.res 1 + +; ------------------------------------------------------------------------ + + .segment "EXTZP" : zeropage +scrptr: .res 2 + +; ------------------------------------------------------------------------ + + + .rodata + + ; Callback structure +_mouse_def_callbacks: + .addr hide + .addr show + .addr prep + .addr draw + .addr movex + .addr movey + +; ------------------------------------------------------------------------ + + .data + +cursor = 11 ; '+' screen code' + +; setcursor + +getcursor: +column: ldy #$00 ; Patched at runtime + lda (scrptr),y + rts + +setcursor: +column2:ldy #$00 ; Patched at runtime + sta (scrptr),y + rts + +; ------------------------------------------------------------------------ + + .code + +done: + rts + +; Hide the mouse cursor. +hide: + dec visible + +prep: + jsr getcursor ; Get character at cursor position + cmp #cursor ; "mouse" character + bne overwr ; no, probably program has overwritten it + lda backup ; + jmp setcursor ; Draw character +overwr: sta backup + rts + +; Show the mouse cursor. +show: + inc visible + +draw: + lda visible + beq done + jsr getcursor ; Cursor visible at current position? + sta backup ; Save character at cursor position + lda #cursor + jmp setcursor ; Draw cursor + + +; Move the mouse cursor x position to the value in A/X. +movex: + cpx #1 + ror a + lsr a ; convert to character position + lsr a + sta column+1 + sta column2+1 + rts + +; Move the mouse cursor y position to the value in A/X. +movey: + tax + ldy tmp4 ; mul40 uses tmp4 + lda loc_tmp ; and this local variable + pha + txa ; get parameter back + lsr a ; convert y position to character line + lsr a + lsr a + jsr mul40 + clc + adc SAVMSC + sta scrptr + txa + adc SAVMSC+1 + sta scrptr+1 + pla + sta loc_tmp + sty tmp4 + rts diff --git a/libsrc/atari/mou/atrami.s b/libsrc/atari/mou/atrami.s new file mode 100644 index 000000000..21e1b4c81 --- /dev/null +++ b/libsrc/atari/mou/atrami.s @@ -0,0 +1,2 @@ +AMIGA_MOUSE = 1 +.include "atrst.s" diff --git a/libsrc/atari/mou/atrjoy.s b/libsrc/atari/mou/atrjoy.s new file mode 100644 index 000000000..aa61615ad --- /dev/null +++ b/libsrc/atari/mou/atrjoy.s @@ -0,0 +1,435 @@ +; +; Driver for a "joystick mouse". +; +; C128 version: Ullrich von Bassewitz, 2004-04-05, 2009-09-26 +; Adapted to Atari: Christian Groessler, 2014-01-02 +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "atari.inc" + + .macpack generic + +; ------------------------------------------------------------------------ +; Header. Includes jump table + +.segment "JUMPTABLE" + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr HIDE + .addr SHOW + .addr SETBOX + .addr GETBOX + .addr MOVE + .addr BUTTONS + .addr POS + .addr INFO + .addr IOCTL + .addr IRQ + +; Mouse driver flags + + .byte MOUSE_FLAG_LATE_IRQ + +; Callback table, set by the kernel before INSTALL is called + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CPREP: jmp $0000 ; Prepare to move the cursor +CDRAW: jmp $0000 ; Draw the cursor +CMOVEX: jmp $0000 ; Move the cursor to X coord +CMOVEY: jmp $0000 ; Move the cursor to Y coord + + +;---------------------------------------------------------------------------- +; Constants + +SCREEN_HEIGHT = 191 +SCREEN_WIDTH = 319 + +.enum JOY + UP = $01 + DOWN = $02 + LEFT = $04 + RIGHT = $08 +.endenum + +;---------------------------------------------------------------------------- +; 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 +; reorder them. + +.bss + +Vars: +YPos: .res 2 ; Current mouse position, Y +XPos: .res 2 ; Current mouse position, X +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 mask + + +Temp: .res 1 ; Temporary value used in the int handler + +; Default values for above variables + +.rodata + +; (We use ".proc" because we want to define both a label and a scope.) + +.proc DefVars + .word SCREEN_HEIGHT/2 ; YPos + .word SCREEN_WIDTH/2 ; XPos + .word 0 ; XMin + .word 0 ; YMin + .word SCREEN_WIDTH ; XMax + .word SCREEN_HEIGHT ; YMax + .byte 0 ; Buttons +.endproc + +.code + +;---------------------------------------------------------------------------- +; INSTALL routine. Is called after the driver is loaded into memory. If +; possible, check if the hardware is present. +; Must return an MOUSE_ERR_xx code in a/x. + +INSTALL: + +; Initialize variables. Just copy the default stuff over + + ldx #.sizeof(DefVars)-1 +@L1: lda DefVars,x + sta Vars,x + dex + bpl @L1 + +; Make sure the mouse cursor is at the default location. + + lda XPos + ldx XPos+1 + jsr CMOVEX + lda YPos + ldx YPos+1 + jsr CMOVEY + +; Done, return zero (= MOUSE_ERR_OK) + + ldx #$00 + txa + rts + +;---------------------------------------------------------------------------- +; UNINSTALL routine. Is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). + +UNINSTALL = HIDE ; Hide cursor on exit + +;---------------------------------------------------------------------------- +; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is only called +; if the mouse is currently visible and should get hidden. For most drivers, +; no special action is required besides hiding the mouse cursor. +; No return code required. + +HIDE: php + sei + jsr CHIDE + plp + rts + +;---------------------------------------------------------------------------- +; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is only called +; if the mouse is currently hidden and should become visible. For most drivers, +; no special action is required besides enabling the mouse cursor. +; No return code required. + +SHOW: php + sei + jsr CSHOW + plp + rts + +;---------------------------------------------------------------------------- +; SETBOX: Set the mouse bounding box. The parameters are passed as they come +; from the C program, that is, a pointer to a mouse_box struct in a/x. +; No checks are done if the mouse is currently inside the box, this is the job +; of the caller. It is not necessary to validate the parameters, trust the +; caller and save some code here. No return code required. + +SETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + ldy #.sizeof (MOUSE_BOX)-1 + php + sei + +@L1: lda (ptr1),y + sta XMin,y + dey + bpl @L1 + + plp + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the mouse bounding box. The parameters are passed as they +; come from the C program, that is, a pointer to a mouse_box struct in a/x. + +GETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + ldy #.sizeof (MOUSE_BOX)-1 + php + sei + +@L1: lda XMin,y + sta (ptr1),y + dey + bpl @L1 + + plp + 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 a/x. 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: php + sei ; No interrupts + + pha + txa + pha + jsr CPREP + pla + tax + pla + + sta YPos + stx YPos+1 ; New Y position + jsr CMOVEY ; Set it + + ldy #$01 + lda (sp),y + sta XPos+1 + tax + dey + lda (sp),y + sta XPos ; New X position + jsr CMOVEX ; Move the cursor + + jsr CDRAW + + plp ; Restore interrupt flag + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the button mask in a/x. + +BUTTONS: + lda Buttons + ldx #$00 + rts + +;---------------------------------------------------------------------------- +; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. +; No return code required. + +POS: ldy #MOUSE_POS::XCOORD ; Structure offset + + php + 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 + plp ; Restore interrupt flag + + iny + sta (ptr1),y ; Store last byte + + rts ; Done + +;---------------------------------------------------------------------------- +; INFO: Returns mouse position and current button mask in the MOUSE_INFO +; struct pointed to by ptr1. No return code required. +; +; We're cheating here to keep the code smaller: The first fields of the +; mouse_info struct are identical to the mouse_pos struct, so we will just +; call _mouse_pos to initialize the struct pointer and fill the position +; fields. + +INFO: jsr POS + +; Fill in the button state + + lda Buttons + 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 a/x. +; + +IOCTL: lda #MOUSE_ERR_INV_IOCTL + rts + +;---------------------------------------------------------------------------- +; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context +; (so be careful). The routine MUST return carry set if the interrupt has been +; 'handled' - which means that the interrupt source is gone. Otherwise it +; MUST return carry clear. +; + +IRQ: + +; Check for a pressed button and place the result into Buttons + + ldx #0 + lda TRIG0 ; joystick #0 trigger + bne @L0 ; not pressed + ldx #MOUSE_BTN_LEFT +@L0: stx Buttons + + lda PORTA ; get joystick direction bits + and #15 ; clear joystick #1 bits + eor #15 + sta Temp + + jsr CPREP + +; Check left/right + + lda Temp ; Read joystick #0 + and #(JOY::LEFT | JOY::RIGHT) + beq @SkipX ; + +; We will cheat here and rely on the fact that either the left, OR the right +; bit can be active + + and #JOY::RIGHT ; Check RIGHT bit + bne @Right + lda #$FF + tax + bne @AddX ; Branch always +@Right: lda #$01 + ldx #$00 + +; Calculate the new X coordinate (--> a/y) + +@AddX: add XPos + tay ; Remember low byte + txa + adc XPos+1 + tax + +; Limit the X coordinate 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: sty XPos + stx XPos+1 + +; Move the mouse pointer to the new X pos + + tya + jsr CMOVEX + +; Calculate the Y movement vector + +@SkipX: lda Temp ; Read joystick #0 + and #(JOY::UP | JOY::DOWN) ; Check up/down + beq @SkipY ; + +; We will cheat here and rely on the fact that either the up, OR the down +; bit can be active + + lsr a + bcc @Down + lda #$FF + tax + bne @AddY +@Down: lda #$01 + ldx #$00 + +; Calculate the new Y coordinate (--> a/y) + +@AddY: add YPos + tay ; Remember low byte + txa + adc YPos+1 + tax + +; Limit the Y coordinate to the bounding box + + 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: sty YPos + stx YPos+1 + +; Move the mouse pointer to the new X pos + + tya + jsr CMOVEY + +; Done + +@SkipY: jsr CDRAW + clc ; Interrupt not "handled" + rts + diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s new file mode 100644 index 000000000..116cecee2 --- /dev/null +++ b/libsrc/atari/mou/atrst.s @@ -0,0 +1,697 @@ +; +; Mouse driver for ST & Amiga mouses and Atari trakball. +; +; Original access routines: 05/07/2000 Freddy Offenga +; Converted to driver: Christian Groessler, 2014-01-04 +; +; Defines: +; AMIGA_MOUSE - builds Amiga mouse version +; TRAK_MOUSE - builds trakball version +; If none of these defines are active, the ST mouse version +; is being built. +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "atari.inc" + + .macpack generic + +.if .not ( .defined (AMIGA_MOUSE) .or .defined (TRAK_MOUSE)) + ST_MOUSE = 1 +.endif + +; ------------------------------------------------------------------------ +; Header. Includes jump table + +.segment "JUMPTABLE" + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; Library reference + +libref: .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr HIDE + .addr SHOW + .addr SETBOX + .addr GETBOX + .addr MOVE + .addr BUTTONS + .addr POS + .addr INFO + .addr IOCTL + .addr IRQ + +; Mouse driver flags + + .byte MOUSE_FLAG_LATE_IRQ + +; Callback table, set by the kernel before INSTALL is called + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CPREP: jmp $0000 ; Prepare to move the cursor +CDRAW: jmp $0000 ; Draw the cursor +CMOVEX: jmp $0000 ; Move the cursor to X coord +CMOVEY: jmp $0000 ; Move the cursor to Y coord + + +;---------------------------------------------------------------------------- +; Constants + +SCREEN_HEIGHT = 191 +SCREEN_WIDTH = 319 + +.enum JOY + UP = $01 + DOWN = $02 + LEFT = $04 + RIGHT = $08 +.endenum + +;---------------------------------------------------------------------------- +; 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 +; reorder them. + +.bss + +Vars: +YPos: .res 2 ; Current mouse position, Y +XPos: .res 2 ; Current mouse position, X +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 mask + +XPosWrk: .res 2 +YPosWrk: .res 2 + +.if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE) +dumx: .res 1 +dumy: .res 1 +.endif + +.ifdef TRAK_MOUSE +oldval: .res 1 +.endif + +.ifndef __ATARIXL__ +OldT1: .res 2 +.else + +.data +set_VTIMR1_handler: + .byte $4C, 0, 0 +.endif + +.rodata + +; Default values for some of the above variables +; (We use ".proc" because we want to define both a label and a scope.) + +.proc DefVars + .word (SCREEN_HEIGHT+1)/2 ; YPos + .word (SCREEN_WIDTH+1)/2 ; XPos + .word 0 ; XMin + .word 0 ; YMin + .word SCREEN_WIDTH ; XMax + .word SCREEN_HEIGHT ; YMax + .byte 0 ; Buttons +.endproc + +.ifdef ST_MOUSE + +; ST mouse lookup table + +STTab: .byte $FF,$01,$00,$01 + .byte $00,$FF,$00,$01 + .byte $01,$00,$FF,$00 + .byte $01,$00,$01,$FF + +.endif + +.ifdef AMIGA_MOUSE + +; Amiga mouse lookup table + +AmiTab: .byte $FF,$01,$00,$FF + .byte $00,$FF,$FF,$01 + .byte $01,$FF,$FF,$00 + .byte $FF,$00,$01,$FF + +.endif + +.code + +;---------------------------------------------------------------------------- +; INSTALL routine. Is called after the driver is loaded into memory. If +; possible, check if the hardware is present. +; Must return an MOUSE_ERR_xx code in a/x. + +INSTALL: + +; Initialize variables. Just copy the default stuff over + + ldx #.sizeof(DefVars)-1 +@L1: lda DefVars,x + sta Vars,x + dex + bpl @L1 + +; Make sure the mouse cursor is at the default location. + + lda XPos + sta XPosWrk + ldx XPos+1 + stx XPosWrk+1 + jsr CMOVEX + lda YPos + sta YPosWrk + ldx YPos+1 + stx YPosWrk+1 + jsr CMOVEY + +; Install timer irq routine to poll mouse. + +.ifdef __ATARIXL__ + + ; Setup pointer to wrapper install/deinstall function. + lda libref + sta set_VTIMR1_handler+1 + lda libref+1 + sta set_VTIMR1_handler+2 + + ; Install my handler. + sec + lda #T1Han + jsr set_VTIMR1_handler + +.else + + lda VTIMR1 + sta OldT1 + lda VTIMR1+1 + sta OldT1+1 + + php + sei + lda #T1Han + sta VTIMR1+1 + plp + +.endif + + lda #%00000001 + sta AUDCTL + + lda #0 + sta AUDC1 + + lda #15 + sta AUDF1 + sta STIMER + + lda POKMSK + ora #%00000001 ; timer 1 enable + sta POKMSK + sta IRQEN + +; Done, return zero (= MOUSE_ERR_OK) + + ldx #$00 + txa + rts + +;---------------------------------------------------------------------------- +; UNINSTALL routine. Is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). + +UNINSTALL: + +; uninstall timer irq routine + + lda POKMSK + and #%11111110 ; timer 1 disable + sta IRQEN + sta POKMSK + +.ifdef __ATARIXL__ + + clc + jsr set_VTIMR1_handler + +.else + + php + sei + lda OldT1 + sta VTIMR1 + lda OldT1+1 + sta VTIMR1+1 + plp + +.endif + ; fall thru... + +;---------------------------------------------------------------------------- +; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is only called +; if the mouse is currently visible and should get hidden. For most drivers, +; no special action is required besides hiding the mouse cursor. +; No return code required. + +HIDE: php + sei + jsr CHIDE + plp + rts + +;---------------------------------------------------------------------------- +; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is only called +; if the mouse is currently hidden and should become visible. For most drivers, +; no special action is required besides enabling the mouse cursor. +; No return code required. + +SHOW: php + sei + jsr CSHOW + plp + rts + +;---------------------------------------------------------------------------- +; SETBOX: Set the mouse bounding box. The parameters are passed as they come +; from the C program, that is, a pointer to a mouse_box struct in a/x. +; No checks are done if the mouse is currently inside the box, this is the job +; of the caller. It is not necessary to validate the parameters, trust the +; caller and save some code here. No return code required. + +SETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + ldy #.sizeof (MOUSE_BOX)-1 + php + sei + +@L1: lda (ptr1),y + sta XMin,y + dey + bpl @L1 + + plp + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the mouse bounding box. The parameters are passed as they +; come from the C program, that is, a pointer to a mouse_box struct in a/x. + +GETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + ldy #.sizeof (MOUSE_BOX)-1 + php + sei + +@L1: lda XMin,y + sta (ptr1),y + dey + bpl @L1 + + plp + 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 a/x. 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: php + sei ; No interrupts + + pha + txa + pha + jsr CPREP + pla + tax + pla + + sta YPos + sta YPosWrk + stx YPos+1 ; New Y position + stx YPosWrk+1 + jsr CMOVEY ; Set it + + ldy #$01 + lda (sp),y + sta XPos+1 + sta XPosWrk+1 + tax + dey + lda (sp),y + sta XPos ; New X position + sta XPosWrk + jsr CMOVEX ; Move the cursor + + jsr CDRAW + + plp ; Restore interrupt flag + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the button mask in a/x. + +BUTTONS: + lda Buttons + ldx #$00 + rts + +;---------------------------------------------------------------------------- +; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. +; No return code required. + +POS: ldy #MOUSE_POS::XCOORD ; Structure offset + + php + 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 + plp ; Restore interrupt flag + + iny + sta (ptr1),y ; Store last byte + + rts ; Done + +;---------------------------------------------------------------------------- +; INFO: Returns mouse position and current button mask in the MOUSE_INFO +; struct pointed to by ptr1. No return code required. +; +; We're cheating here to keep the code smaller: The first fields of the +; mouse_info struct are identical to the mouse_pos struct, so we will just +; call _mouse_pos to initialize the struct pointer and fill the position +; fields. + +INFO: jsr POS + +; Fill in the button state + + lda Buttons + 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 a/x. +; + +IOCTL: lda #MOUSE_ERR_INV_IOCTL + rts + +;---------------------------------------------------------------------------- +; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context +; (so be careful). The routine MUST return carry set if the interrupt has been +; 'handled' - which means that the interrupt source is gone. Otherwise it +; MUST return carry clear. +; + +IRQ: + +; Check for a pressed button and place the result into Buttons + + ldx #0 + lda TRIG0 ; joystick #0 trigger + bne @L0 ; not pressed + ldx #MOUSE_BTN_LEFT +@L0: stx Buttons + + jsr CPREP + +; Limit the X coordinate to the bounding box + + lda XPosWrk+1 + ldy XPosWrk + tax + cpy XMin + sbc XMin+1 + bpl @L2 + ldy XMin + ldx XMin+1 + jmp @L3 +@L2: txa + + cpy XMax + sbc XMax+1 + bmi @L3 + ldy XMax + ldx XMax+1 +@L3: sty XPos + stx XPos+1 + + tya + jsr CMOVEX + +; Limit the Y coordinate to the bounding box + + lda YPosWrk+1 + ldy YPosWrk + tax + cpy YMin + sbc YMin+1 + bpl @L4 + ldy YMin + ldx YMin+1 + jmp @L5 +@L4: txa + + cpy YMax + sbc YMax+1 + bmi @L5 + ldy YMax + ldx YMax+1 +@L5: sty YPos + stx YPos+1 + + tya + jsr CMOVEY + + jsr CDRAW + + clc + rts + + +;---------------------------------------------------------------------------- +; T1Han: Local IRQ routine to poll mouse +; + +T1Han: tya + pha + txa + pha + +.ifdef DEBUG + lda RANDOM + sta COLBK +.endif + + lda PORTA + tay + +.ifdef ST_MOUSE + +; ST mouse version + + and #%00000011 + ora dumx + tax + lda STTab,x + bmi nxst + + beq xist + + dec XPosWrk + lda XPosWrk + cmp #255 + bne nxst + dec XPosWrk+1 + jmp nxst + +xist: inc XPosWrk + bne nxst + inc XPosWrk+1 + +nxst: tya + and #%00001100 + ora dumy + tax + lda STTab,x + bmi nyst + + bne yst + + dec YPosWrk + lda YPosWrk + cmp #255 + bne nyst + dec YPosWrk+1 + jmp nyst + +yst: inc YPosWrk + bne nyst + inc YPosWrk+1 + +; store old readings + +nyst: tya + and #%00000011 + asl + asl + sta dumx + tya + and #%00001100 + lsr + lsr + sta dumy + +.elseif .defined (AMIGA_MOUSE) + +; Amiga mouse version + + lsr + and #%00000101 + ora dumx + tax + lda AmiTab,x + bmi nxami + + bne xiami + + dec XPosWrk + lda XPosWrk + cmp #255 + bne nxami + dec XPosWrk+1 + jmp nxami + +xiami: inc XPosWrk + bne nxami + inc XPosWrk+1 + +nxami: tya + + and #%00000101 + ora dumy + tax + lda AmiTab,x + bmi nyami + + bne yiami + + dec YPosWrk + lda YPosWrk + cmp #255 + bne nyami + dec YPosWrk+1 + jmp nyami + +yiami: inc YPosWrk + bne nyami + inc YPosWrk+1 + +; store old readings + +nyami: tya + and #%00001010 + sta dumx + tya + and #%00000101 + asl + sta dumy + +.elseif .defined (TRAK_MOUSE) + +; trakball version + + eor oldval + and #%00001000 + beq horiz + + tya + and #%00000100 + beq mmup + + inc YPosWrk + bne horiz + inc YPosWrk+1 + bne horiz + +mmup: dec YPosWrk + lda YPosWrk + cmp #255 + bne horiz + dec YPosWrk+1 + +horiz: tya + eor oldval + and #%00000010 + beq mmexit + + tya + and #%00000001 + beq mmleft + + inc XPosWrk + bne mmexit + inc XPosWrk+1 + bne mmexit + +mmleft: dec XPosWrk + lda XPosWrk + cmp #255 + bne mmexit + dec XPosWrk+1 + +mmexit: sty oldval + +.endif + + pla + tax + pla + tay +.ifdef __ATARIXL__ + rts +.else + pla + rti +.endif diff --git a/libsrc/atari/mou/atrtrk.s b/libsrc/atari/mou/atrtrk.s new file mode 100644 index 000000000..699d12a0d --- /dev/null +++ b/libsrc/atari/mou/atrtrk.s @@ -0,0 +1,2 @@ +TRAK_MOUSE = 1 +.include "atrst.s" diff --git a/libsrc/atari/mouse.s_ b/libsrc/atari/mouse.s_ deleted file mode 100644 index 9c722b49c..000000000 --- a/libsrc/atari/mouse.s_ +++ /dev/null @@ -1,576 +0,0 @@ -;-------------------------------------------------------------------- -; Atari 8-bit mouse routines -- 05/07/2000 Freddy Offenga -; Some changes by Christian Groessler, Ullrich von Bassewitz -; -; The following devices are supported: -; - Atari trak-ball -; - ST mouse -; - Amiga mouse -; -; Mouse checks are done in the timer 1 IRQ and the mouse arrow is -; drawn in player 0 during the vertical blank -;-------------------------------------------------------------------- - - .export _mouse_init, _mouse_done, _mouse_box - .export _mouse_show, _mouse_hide, _mouse_move - .export _mouse_buttons, _mouse_pos, _mouse_info - .constructor initmouse,27 - - .import popax - .importzp ptr1 - - .include "atari.inc" - -TRAK_BALL = 0 ; device Atari trak-ball -ST_MOUSE = 1 ; device ST mouse -AMIGA_MOUSE = 2 ; device Amiga mouse -MAX_TYPE = 3 ; first illegal device type - -; the default values force the mouse cursor inside the test screen (no access to border) -defxmin = 48 ; default x minimum -defymin = 31 ; default y minimum -defxmax = 204 ; default x maximum -defymax = 211 ; default y maximum - -pmsize = 16 ; y size pm shape - -xinit = defxmin ; init. x pos. -yinit = defymin ; init. y pos. - -;-------------------------------------------------------------------- -; reserve memory for the mouse pointer - -initmouse: - lda APPMHI+1 - and #%11111000 ; make 2k aligned - sec - sbc #%00001000 ; reserve 2k - tax - adc #3 ; add 4 (C = 1) - sta mouse_pm0 - lda #0 - sta APPMHI - stx APPMHI+1 - rts - - -;-------------------------------------------------------------------- -; Initialize mouse routines -; void __fastcall__ mouse_init (unsigned char type); - -_mouse_init: - cmp #MAX_TYPE+1 ; Check for a valid type - bcc setup - -ifail: lda #0 ; init. failed - tax - rts - -setup: tax - lda lvectab,x - sta mouse_vec+1 - lda hvectab,x - sta mouse_vec+2 - - jsr pminit - - lda VTIMR1 - sta old_t1 - lda VTIMR1+1 - sta old_t1+1 - - lda #t1_vec - sta VTIMR1+1 - - lda #%00000001 - sta AUDCTL - - lda #0 - sta AUDC1 - - lda #15 - sta AUDF1 - sta STIMER - - sei - lda POKMSK - ora #%00000001 ; timer 1 enable - sta POKMSK - sta IRQEN - cli - - lda VVBLKI - sta vbi_jmp+1 - lda VVBLKI+1 - sta vbi_jmp+2 - - lda #6 - ldy #vbi - jsr SETVBV - - lda #$C0 - sta NMIEN - - ldx #0 - lda #1 - sta mouse_off - rts - -;-------------------------------------------------------------------- -; Finish mouse routines -; void mouse_done(void) - -_mouse_done: - sei - lda POKMSK - and #%11111110 ; timer 1 disable - sta IRQEN - sta POKMSK - cli - - lda old_t1 - sta VTIMR1 - lda old_t1+1 - sta VTIMR1+1 - - lda #$40 - sta NMIEN - - lda #6 - ldy vbi_jmp+1 - ldx vbi_jmp+2 - jsr SETVBV - - ldx #0 - stx GRACTL - stx HPOSP0 - inx - stx mouse_off - rts - -;-------------------------------------------------------------------- -; Set mouse limits -; void __fastcall__ mouse_box(int xmin, int ymin, int xmax, int ymax) - -_mouse_box: - sta ymax - jsr popax ; always ignore high byte - sta xmax - jsr popax - sta ymin - jsr popax - sta xmin - rts - -;-------------------------------------------------------------------- -; Set mouse position -; void __fastcall__ mouse_move(int xpos, int ypos) - -_mouse_move: - sta mousey ; always ignore high byte - jsr popax - sta mousex - rts - -;-------------------------------------------------------------------- -; Show mouse arrow -; void mouse_show(void) - -_mouse_show: - lda mouse_off ; Already on? - beq @L1 - dec mouse_off -@L1: rts - -;-------------------------------------------------------------------- -; Hide mouse arrow -; void mouse_hide(void) - -_mouse_hide: - inc mouse_off - rts - -;-------------------------------------------------------------------- -; Ask mouse button -; unsigned char mouse_buttons(void) - -_mouse_buttons: - ldx #0 - lda STRIG0 - bne nobut -; lda #14 -;??? sta COLOR1 - lda #1 - rts -nobut: txa - rts - -;-------------------------------------------------------------------- -; Get the mouse position -; void mouse_pos (struct mouse_pos* pos); - -_mouse_pos: - sta ptr1 - stx ptr1+1 ; Store argument pointer - ldy #0 - lda mousex ; X position - sta (ptr1),y - lda #0 - iny - sta (ptr1),y - lda mousey ; Y position - iny - sta (ptr1),y - lda #0 - iny - sta (ptr1),y - rts - -;-------------------------------------------------------------------- -; Get the mouse position and button information -; void mouse_info (struct mouse_info* info); - -_mouse_info: - -; We're cheating here to keep the code smaller: The first fields of the -; mouse_info struct are identical to the mouse_pos struct, so we will just -; call _mouse_pos to initialize the struct pointer and fill the position -; fields. - - jsr _mouse_pos - -; Fill in the button state - - jsr _mouse_buttons ; Will not touch ptr1 - ldy #4 - sta (ptr1),y - - rts - -;-------------------------------------------------------------------- -; Atari trak-ball check, A,Y = 4-bit port value - -trak_check: - eor oldval - and #%00001000 - beq horiz - - tya - and #%00000100 - beq mmup - - inc mousey - bne horiz - -mmup: dec mousey - -horiz: tya - eor oldval - and #%00000010 - beq mmexit - - tya - and #%00000001 - beq mmleft - - inc mousex - bne mmexit - -mmleft: dec mousex - -mmexit: sty oldval - rts - -;-------------------------------------------------------------------- -; ST mouse check, A,Y = 4-bit port value - -st_check: - and #%00000011 - ora dumx - tax - lda sttab,x - bmi nxst - - beq xist - dec mousex ; 1 = left - bne nxst -xist: inc mousex ; 0 = right - -nxst: tya - and #%00001100 - ora dumy - tax - lda sttab,x - bmi nyst - - bne yst - dec mousey ; 0 = up - bne nyst -yst: inc mousey ; 1 = down - -; store old readings - -nyst: tya - and #%00000011 - asl - asl - sta dumx - tya - and #%00001100 - lsr - lsr - sta dumy - rts - -;-------------------------------------------------------------------- -; Amiga mouse check, A,Y = 4-bit port value - -amiga_check: - - lsr - and #%00000101 - ora dumx - tax - lda amitab,x - bmi nxami - - bne xiami - dec mousex ; 0 = left - bne nxami -xiami: inc mousex ; 1 = right - -nxami: tya - - and #%00000101 - ora dumy - tax - lda amitab,x - bmi nyami - - bne yiami - dec mousey ; 0 = up - bne nyami -yiami: inc mousey ; 1 = down - -; store old readings - -nyami: tya - and #%00001010 - sta dumx - tya - and #%00000101 - asl - sta dumy - rts - -;-------------------------------------------------------------------- -; timer 1 IRQ routine - check mouse - -t1_vec: tya - pha - txa - pha - -.ifdef DEBUG - lda RANDOM - sta COLBK ; debug -.endif - - lda PORTA - tay - -mouse_vec: - jsr st_check ; will be modified; won't be ROMmable - - pla - tax - pla - tay - pla - rti - -;-------------------------------------------------------------------- -; VBI - check mouse limits and display mouse arrow - -vbi: lda mousex - cmp xmin - bcs ok1 ; xmin <= mousex - lda xmin - sta mousex - -ok1: lda mousey - cmp ymin - bcs ok2 ; ymin <= mousey - lda ymin - sta mousey - -ok2: lda xmax - cmp mousex - bcs ok3 ; xmax >= mousex - lda xmax - sta mousex - -ok3: lda ymax - cmp mousey - bcs ok4 ; ymax >= mousey - lda ymax - sta mousey - -ok4: jsr clrpm - - lda mouse_off - beq mon - lda #0 - sta HPOSP0 - beq moff - -mon: jsr drwpm - lda mousey - sta omy - - lda #3 -moff: sta GRACTL - -vbi_jmp: - jmp SYSVBV ; will be modified; won't be ROMmable - -;-------------------------------------------------------------------- -; initialize mouse pm - -pminit: lda mouse_pm0 - sta mpatch1+2 - sta mpatch2+2 - sta mpatch3+2 - - ldx #0 - txa -mpatch1: -clpm: sta $1000,x ; will be patched - inx - bne clpm - - lda mouse_pm0 - sec - sbc #4 - sta PMBASE - - lda #62 - sta SDMCTL - - lda #1 - sta GPRIOR - - lda #0 - sta PCOLR0 - sta SIZEP0 - rts - -;-------------------------------------------------------------------- -; draw new mouse pm - -drwpm: lda mousex - sta HPOSP0 - - lda mousey - tax - - ldy #0 -fmp2: lda mskpm,y -mpatch2: - sta $1000,x ; will be patched - inx - iny - cpy #pmsize - bne fmp2 - rts - -;-------------------------------------------------------------------- -; clear old mouse pm - -clrpm: lda omy - tax - - ldy #0 - tya -mpatch3: -fmp1: sta $1000,x ; will be patched - inx - iny - cpy #pmsize - bne fmp1 - rts - -;-------------------------------------------------------------------- - .rodata - -; mouse arrow - pm shape - -mskpm: .byte %00000000 - .byte %10000000 - .byte %11000000 - .byte %11000000 - - .byte %11100000 - .byte %11100000 - .byte %11110000 - .byte %11100000 - - .byte %11100000 - .byte %00100000 - .byte %00100000 - .byte %00110000 - - .byte %00110000 - .byte %00000000 - .byte %00000000 - .byte %00000000 - -; ST mouse lookup table - -sttab: .byte $FF,$01,$00,$01 - .byte $00,$FF,$00,$01 - .byte $01,$00,$FF,$00 - .byte $01,$00,$01,$FF - -; Amiga mouse lookup table - -amitab: .byte $FF,$01,$00,$FF - .byte $00,$FF,$FF,$01 - .byte $01,$FF,$FF,$00 - .byte $FF,$00,$01,$FF - -; Device vectors - -lvectab: - .byte trak_check, >st_check, >amiga_check - -; default values - -xmin: .byte defxmin -ymin: .byte defymin -xmax: .byte defxmax -ymax: .byte defymax - -mousex: .byte xinit -mousey: .byte yinit - -;-------------------------------------------------------------------- - .bss - -; Misc. vars - -old_t1: .res 2 ; old timer interrupt vector -oldval: .res 1 ; used by trakball routines -dumx: .res 1 -dumy: .res 1 -omy: .res 1 ; old y pos - -mouse_off: - .res 1 -mouse_pm0: - .res 1 diff --git a/libsrc/atari/mouse_stat_stddrv.s b/libsrc/atari/mouse_stat_stddrv.s new file mode 100644 index 000000000..55e29878b --- /dev/null +++ b/libsrc/atari/mouse_stat_stddrv.s @@ -0,0 +1,22 @@ +; +; Address of the static standard mouse driver +; +; Christian Groessler, 2014-01-02 +; +; const void mouse_static_stddrv[]; +; + + .export _mouse_static_stddrv + .ifdef __ATARIXL__ + .import _atrxst_mou + .else + .import _atrst_mou + .endif + +.rodata + + .ifdef __ATARIXL__ +_mouse_static_stddrv := _atrxst_mou + .else +_mouse_static_stddrv := _atrst_mou + .endif diff --git a/libsrc/atari/mouse_stddrv.s b/libsrc/atari/mouse_stddrv.s new file mode 100644 index 000000000..493c90d77 --- /dev/null +++ b/libsrc/atari/mouse_stddrv.s @@ -0,0 +1,18 @@ +; +; Name of the standard mouse driver +; +; Christian Groessler, 2014-01-02 +; +; const char mouse_stddrv[]; +; + + .export _mouse_stddrv + +.rodata + +_mouse_stddrv: + .ifdef __ATARIXL__ + .asciiz "ATRXST.MOU" + .else + .asciiz "ATRST.MOU" + .endif diff --git a/libsrc/atari/mul40.s b/libsrc/atari/mul40.s index b94ab5c52..96235bf6c 100644 --- a/libsrc/atari/mul40.s +++ b/libsrc/atari/mul40.s @@ -6,7 +6,7 @@ ; uses tmp4 .importzp tmp4 - .export mul40 + .export mul40,loc_tmp .proc mul40 diff --git a/libsrc/atari/shadow_ram_timerirq1.s b/libsrc/atari/shadow_ram_timerirq1.s new file mode 100644 index 000000000..f8a3e9b4d --- /dev/null +++ b/libsrc/atari/shadow_ram_timerirq1.s @@ -0,0 +1,81 @@ +; +; Atari XL shadow RAM timer IRQ #1 handler +; +; Christian Groessler, chris@groessler.org, 2014 +; + +;DEBUG = 1 + +.ifdef __ATARIXL__ + +SHRAM_HANDLERS = 1 + .include "atari.inc" + .include "romswitch.inc" + .export set_VTIMR1_handler + + +.segment "LOWBSS" + +VTIMR1_handler: .res 3 + + +.segment "BSS" + +old_VTIMR1_handler: + .res 2 + + +.segment "LOWCODE" + +; timer interrupt handler: +; disable ROM, call user handler, enable ROM again + +my_VTIMR1_handler: + disable_rom_quick + jsr VTIMR1_handler + enable_rom_quick + pla + rti + +.segment "CODE" + +; install or remove VTIMR1 handler +; input: CF - 0/1 for remove/install handler +; AX - pointer to handler (if CF=1) +; registers destroyed + +set_VTIMR1_handler: + + bcc @remove + +; install vector + + stx VTIMR1_handler+2 + sta VTIMR1_handler+1 ; save passed vector in low memory + lda #$4C ; "JMP" opcode + sta VTIMR1_handler + + lda VTIMR1 + sta old_VTIMR1_handler + lda VTIMR1+1 + sta old_VTIMR1_handler+1 + + lda #my_VTIMR1_handler + sta VTIMR1+1 + plp + rts + +@remove: php + sei + lda old_VTIMR1_handler + sta VTIMR1 + lda old_VTIMR1_handler+1 + sta VTIMR1+1 + plp + rts + +.endif ; .ifdef __ATARIXL__