Announcement

Collapse

Forum Rules and Etiquette

Our mission ...

This forum is part of our mission to promote the preservation of vintage computers through education and outreach. (In real life we also run events and have a museum.) We encourage you to join us, participate, share your knowledge, and enjoy.

This forum has been around in this format for over 15 years. These rules and guidelines help us maintain a healthy and active community, and we moderate the forum to keep things on track. Please familiarize yourself with these rules and guidelines.


Rule 1: Remain civil and respectful

There are several hundred people who actively participate here. People come from all different backgrounds and will have different ways of seeing things. You will not agree with everything you read here. Back-and-forth discussions are fine but do not cross the line into rude or disrespectful behavior.

Conduct yourself as you would at any other place where people come together in person to discuss their hobby. If you wouldn't say something to somebody in person, then you probably should not be writing it here.

This should be obvious but, just in case: profanity, threats, slurs against any group (sexual, racial, gender, etc.) will not be tolerated.


Rule 2: Stay close to the original topic being discussed
  • If you are starting a new thread choose a reasonable sub-forum to start your thread. (If you choose incorrectly don't worry, we can fix that.)
  • If you are responding to a thread, stay on topic - the original poster was trying to achieve something. You can always start a new thread instead of potentially "hijacking" an existing thread.



Rule 3: Contribute something meaningful

To put things in engineering terms, we value a high signal to noise ratio. Coming here should not be a waste of time.
  • This is not a chat room. If you are taking less than 30 seconds to make a post then you are probably doing something wrong. A post should be on topic, clear, and contribute something meaningful to the discussion. If people read your posts and feel that their time as been wasted, they will stop reading your posts. Worse yet, they will stop visiting and we'll lose their experience and contributions.
  • Do not bump threads.
  • Do not "necro-post" unless you are following up to a specific person on a specific thread. And even then, that person may have moved on. Just start a new thread for your related topic.
  • Use the Private Message system for posts that are targeted at a specific person.


Rule 4: "PM Sent!" messages (or, how to use the Private Message system)

This forum has a private message feature that we want people to use for messages that are not of general interest to other members.

In short, if you are going to reply to a thread and that reply is targeted to a specific individual and not of interest to anybody else (either now or in the future) then send a private message instead.

Here are some obvious examples of when you should not reply to a thread and use the PM system instead:
  • "PM Sent!": Do not tell the rest of us that you sent a PM ... the forum software will tell the other person that they have a PM waiting.
  • "How much is shipping to ....": This is a very specific and directed question that is not of interest to anybody else.


Why do we have this policy? Sending a "PM Sent!" type message basically wastes everybody else's time by making them having to scroll past a post in a thread that looks to be updated, when the update is not meaningful. And the person you are sending the PM to will be notified by the forum software that they have a message waiting for them. Look up at the top near the right edge where it says 'Notifications' ... if you have a PM waiting, it will tell you there.

Rule 5: Copyright and other legal issues

We are here to discuss vintage computing, so discussing software, books, and other intellectual property that is on-topic is fine. We don't want people using these forums to discuss or enable copyright violations or other things that are against the law; whether you agree with the law or not is irrelevant. Do not use our resources for something that is legally or morally questionable.

Our discussions here generally fall under "fair use." Telling people how to pirate a software title is an example of something that is not allowable here.


Reporting problematic posts

If you see spam, a wildly off-topic post, or something abusive or illegal please report the thread by clicking on the "Report Post" icon. (It looks like an exclamation point in a triangle and it is available under every post.) This send a notification to all of the moderators, so somebody will see it and deal with it.

If you are unsure you may consider sending a private message to a moderator instead.


New user moderation

New users are directly moderated so that we can weed spammers out early. This means that for your first 10 posts you will have some delay before they are seen. We understand this can be disruptive to the flow of conversation and we try to keep up with our new user moderation duties to avoid undue inconvenience. Please do not make duplicate posts, extra posts to bump your post count, or ask the moderators to expedite this process; 10 moderated posts will go by quickly.

New users also have a smaller personal message inbox limit and are rate limited when sending PMs to other users.


Other suggestions
  • Use Google, books, or other definitive sources. There is a lot of information out there.
  • Don't make people guess at what you are trying to say; we are not mind readers. Be clear and concise.
  • Spelling and grammar are not rated, but they do make a post easier to read.
See more
See less

AT&T 6300 (Olivetti M24) mouse software compatibility query

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 1ST1
    replied
    Just by comparing the signals... Each of these mice have two x and two y signals plus two mouse buttons. They all need 5V and gnd. I have posted in this forum the pinout of all the three mouseports. But until now I haven't made adapters for myself.

    Leave a comment:


  • freakedenough
    replied
    Hey AlG,

    Ive found your thread via Google and I would like to know how to rewire an Atari ST or Amiga mouse to fit my M24SP.

    Thank you!

    Leave a comment:


  • Simone2013
    replied
    Originally posted by Trixter View Post
    If you provide the source, maybe I or someone can add 6300/M24 support. Or, maybe just the source for your int09-regrabbing code so I can see how you did it, and then maybe I can RE the 6300 mouse driver and add just that section.

    Interestingly the 6300 Mouse driver MOUSE.DOC warns about not taking over the keyboard (and also confirms the mouse and driver were OEM Logitech):
    Of course:
    If you need the txt file, PM to me!

    Code:
    ;*****************************************************************************
    ;*	   		  .-= MOUSE PC1 Project =-.			     *
    ;* Int33h mouse hook for PC1 - NECV40 0.97 by Simone Riminucci (C) 2016	     *
    ;* Started: 29.11.2016							     *
    ;* Last updated 21.02.2017						     *
    ;* Tested on: OLIVETTI PRODEST PC1 (NEC V40 XT, 512/640kB)		     *
    ;*	     								     *
    ;* Only 1904 byte Resident!						     *
    ;* Compile with NASM (186 code)						     *
    ;* Hardware Mouse pointer using YAMAHA V6335D special registers !	     *
    ;*****************************************************************************
    
    CPU 186 			;code compatability
    
    ;%define DEBUG
    ;%define CALL_OLD_INT33
    BIOS_DATA_SEG	EQU 40h
    driverversion	equ 303h	;imitated Microsoft driver version
    
    %include "constant.inc"    ; Stuff that never changes.
    
    %macro TEST1 2	;test 1 bit (n. CL). ZF is set if bit is zero.
    		; out CY=0 V=0, ZF as needed
    	%ifn %2=CL
    	   %error "Only CL as second parameter"
    	%endif
    
    	db 0Fh
    
    	%if %1=AL
    	  db 10h
    	  db 0C0h
    	%elif %1=AX 
    	  db 11h
    	  db 0C0h 
    	%else 
        	  %error "Invalid Parameter" 
    	%endif
    %endmacro
    
    %macro SET1 2	;set 1 bit (n. CL). if ZF is set the bit go to zero.
    	%ifn %2=CL
    	   %error "Only CL as second parameter"
    	%endif
    
    	db 0Fh
    
    	%if %1=AL
    	  db 14h
    	  db 0C0h
    	%elif %1=AH 
    	  db 14h
    	  db 0C4h 
    	%elif %1=AX 
    	  db 15h
    	  db 0C0h 
    	%else 
        	  %error "Invalid Parameter" 
    	%endif
    %endmacro
    
    ;************** Program header ***************************************************
    
    	ORG	100h		;use if compiling .COM file
    	jmp	start
    
    cmdlineflags	db 0
    
    KeyStatus       db 0
    Old_INT08       dd 0                    	;old INT
    Old_INT09       dd 0  				;old INT
    
    %ifdef CALL_OLD_INT33
    Old_INT33       dd 0  				;old INT
    %endif
    
    Old_INT09_MONK	dd 0                    	;old INT
    Already_in_user	db 0
    Cursor_Flag	db 0FFh
    MIN_HRange	dw 0
    MAX_HRange	dw 639
    MIN_VRange	dw 0
    MAX_VRange	dw 199
    Hor_Ratio	dw 8
    Vert_Ratio	dw 8
    X_Mult_Ratio    dw 8
    Y_Mult_Ratio    dw 8 
    CenterX		dw 15
    CenterY		dw 15
    H_Mickey_Count	dw 0
    V_Mickey_Count	dw 0
    Max_speed_D2    dw 2
    Max_Speed_D     dw 35h
    Button_Status		dw 0
    LB_Count_press		dw 0
    LB_PosX_last_press 	dw 0
    LB_PosY_last_press 	dw 0
    LB_Count_releases 	dw 0
    LB_PosX_last_release 	dw 0
    LB_PosY_last_release 	dw 0
    RB_Count_press		dw 0
    RB_PosX_last_press 	dw 0
    RB_PosY_last_press 	dw 0
    RB_Count_releases 	dw 0
    RB_PosX_last_release 	dw 0
    RB_PosY_last_release 	dw 0
    shift_X_Pos		db 1
    shift_ratioX		db 0
    shift_ratioY		db 0
    MouseX_Sum		dw 160
    MouseY_Sum		dw 100
    Cursor_attribute	db 0F0h
    Last_mask		db 0	
    User_Event_Mask		db 0	; Changed: Cursor pos,left press, left rel, right press, right rel
    Event_Handler_Addr 	dd 63620000h
    ORG_AX		dw 0
    ORG_BX		dw 0
    ORG_CX		dw 0
    ORG_DX		dw 0
    ORG_DI		dw 0
    ORG_SI		dw 0
    ORG_ES		dw 0
    
    screenmask	dw 0011111111111111b	; 0
    		dw 0001111111111111b	; 2
    		dw 0000111111111111b	; 4
    		dw 0000011111111111b	; 6
    		dw 0000001111111111b	; 8
    		dw 0000000111111111b	; 10
    		dw 0000000011111111b	; 12
    		dw 0000000001111111b	; 14
    		dw 0000000000111111b	; 16
    		dw 0000000000011111b	; 18
    		dw 0000000000001111b	; 20
    		dw 0000000011111111b	; 22
    		dw 0001000011111111b	; 24
    		dw 0111100001111111b	; 26
    		dw 1111100001111111b	; 28
    		dw 1111110001111111b	; 30	
    
    cursormask	dw 0000000000000000b	; 0
    		dw 0100000000000000b	; 2
    		dw 0110000000000000b	; 4
    		dw 0111000000000000b	; 6
    		dw 0111100000000000b	; 8
    		dw 0111110000000000b	; 10
    		dw 0111111000000000b	; 12
    		dw 0111111100000000b	; 14
    		dw 0111111110000000b	; 16
    		dw 0111111111000000b	; 18
    		dw 0111111000000000b	; 20
    		dw 0100011000000000b	; 22
    		dw 0000011000000000b	; 24
    		dw 0000001100000000b	; 26
    		dw 0000001100000000b	; 28
    		dw 0000000000000000b	; 30
    
    Int33_sub_index	dw Fun_00	; Reset/Query driver Presence
    		dw Fun_01	; Display Pointer
    		dw Fun_02	; Hide Pointer
    		dw Fun_03	; Query	Position & Buttons
    		dw Fun_04	; Move Pointer
    		dw Fun_05	; Query	Button Pressed count
    					; BX = 0  left button
    					;      1  right	button
    					;
    					;
    					;	  on return:
    					;	  BX = count of	button presses (0-32767), set to zero after call
    					;	  CX = horizontal position at last press
    					;	  DX = vertical	position at last press
    					;	  AX = status:
    					;		  |F-8|7|6|5|4|3|2|1|0|	 Button	Status
    					;		    |  | | | | | | | `---- left	button (1 = pressed)
    					;		    |  | | | | | | `----- right	button (1 = pressed)
    					;		    `------------------- unused
    		dw Fun_06	; Get Mouse Button Release Information
    					;
    					; BL=Button
    					;
    					; on return:
    					;	  BX = count of	button releases	(0-32767), set to zero after call
    					;	  CX = horizontal position at last release
    					;	  DX = vertical	position at last release
    					;	  AX = status
    		dw Fun_07	; Set Horizontal range
    					; CX = minimum H pos
    					; DX = maximum H pos
    		dw Fun_08	; Set Vertical range
    					; CX = minimum V pos
    					; DX = maximum V pos
    		dw Fun_09	; Set graphic pointer shape
    					; BX = horizontal hot spot (-16	to 16)
    					; CX = vertical	hot spot (-16 to 16)
    					; ES:DX	= pointer to screen and	cursor masks (16 byte bitmap)
    		dw Fun_0A	; Set text pointer mask
    		dw Fun_0B	; Query	last motion distance
    		dw Fun_0C	; Set Event Handler
    		dw no_fun	; Enable Light Pen Emulation
    		dw no_fun	; Disable Light	Pen Emulation
    		dw Fun_0F	; Set Pointer Speed
    					; CX= Horizontal Ratio
    					; DX= Vertical Ratio
    		dw no_fun	; Set Exclusion	Area
    		dw Fun_11	; GET NUMBER OF BUTTONS (special PC1 MOUSE procedure)
    		dw no_fun
    		dw Fun_13	; Set max for Speed Doubling
    		dw Fun_14	; Exchange Event Handler
    
    INT_08:
    	pusha
    	push	ds
    	
    	push 	cs		;variable segment!
    	pop	ds
    	mov     byte [Last_mask], 0
    	call	read_M_delta_coord
    	cmp	bl, 00h			; Value	00h or FFh = WAS MOVED!
    	jz	go3
    	cmp	byte [Cursor_Flag], 0	; default -1 (FF) not visible
    					; visible=0
    	jnz	go2
    update_cur:
    	cli
    	mov	dx, 3DDh
    	mov	al, 60h+80h		;sistemiamo solo lo sprite per ora...
    	out	dx, al
    	inc	dx
    	mov     ax, [MouseX_Sum]
    	shr	ax, 1
    	add	ax, [CenterX]
    	xchg	al, ah
    	out	dx,al
    	xchg	al, ah
    	out	dx,al
    	mov     ax, [MouseY_Sum]
    	add	ax, [CenterY]
    	xchg	al, ah
    	out	dx,al
    	xchg	al, ah
    	out	dx,al
    	sti
    	cmp	bl, 0Fh			;me lo posso permettere perch ho eliminato MOV mem,imm e CMP mem,imm -> CMP reg,imm
    	jz	return_to_fun04		;adjust_cursor was on-going
    go2:	or      byte [Last_mask], 1	; signal cursor movement to mask
    
    	push    es
    	call    Call_User	; there is X or Y movement!
    	pop     es
    
    
    go3:	pop	ds
    	popa
    
    	jmp	far [cs:Old_INT08]
    
    %macro CHECK_THRES 0	;test for AX < [Max_speed_D2] in valore assoluto SENZA jump! (prima ce ne erano 2!!!)
    		; AX shifted if |AX| > [Max_speed_D2] - CX Corrupted - speed optimized
    	push	AX
    	mov	CX, AX
    	SHR	CX, 0Fh
    	xor	AX, CX
    	sub	AX, CX
    	cmp	ax, [Max_speed_D2]	;carry set if Below [Max_speed_D2]
    	cmc				;set if Higher of [Max_speed_D2]
    	xor	cl, cl
    	rcl	cl, 1		;cl=1 if carry set, 0 otherwise
    	pop	ax		;tiriamo fuori il valore originale
    	shl	ax, cl
    %endmacro
    
    read_M_delta_coord:		; (BL) lo uso come "was moved!"
    	mov	BL, 0		; was moved = no
    	mov	al, 10h		; load CTRC register
    	out	0D4h,al
    	in 	al, 0D5h
    	cmp	al, 0
    	je	rm2		; non  cambiata la "X"
    	cbw                     ; Converts byte in AL to word Value in AX by extending sign of AL throughout register AH.
    	neg 	ax		; negative! la X  sepre negativa, non so perch
    	dec	BX
    	add     [H_Mickey_Count], ax		;here the mickey are NOT doubled!
    	CHECK_THRES
    	mov	CL, byte [shift_ratioX]		;shifting is better than IMUL/IDIV 50+34=84 Clock!!! 
    	shl	ax, cl
    	add     ax, [MouseX_Sum]
    	call	Verify_in_HRange
    	mov     [MouseX_Sum], ax
     rm2:	mov	al, 11h		; load CTRC register
    	out	0D4h,al
    	in 	al, 0D5h
    	cbw
    	cmp	ax, 0
    	je	rm4
    	dec	BX		; was moved = s pi corto ancora: 1 solo byte
    	CHECK_THRES
     rm3:	add     [V_Mickey_Count], ax		;here the mickey are NOT shifted
    	mov	CL, byte [shift_ratioY]		;shifting is better than IMUL/IDIV 50+34=84 Clock!!! 
    	shl	ax, cl
    	add     ax, [MouseY_Sum]
    	call	Verify_in_VRange
    	mov     [MouseY_Sum], ax
    return_to_fun04: 	;s  pulcioso, si risparmia un'altro byte se  meno lontano di 127 byte!
    rm4:	ret
    
    ; NOTA: non uso pushf/popf perch sono gi salvate da INT09 procedure
    
    INT_09bis:	push	ax		
    		call	Has_been_pressed_a_Mkey
    		or	al, al
    		jnz	pressed
    		pop	ax
    		jmp	far [cs:Old_INT09_MONK]
    
    INT_09:		push	ax
    		call	Has_been_pressed_a_Mkey
    		or	al, al
    		jz	GoTo_OldInt
    pressed:	pusha
    		push	es
    		push	ds
    		push	cs	;RIGHT SEGMENT FOR DATA
    		pop	ds
    		;mov	bx, cs
    		;mov	ds, bx
    		;mov	es, bx
    		mov	ah, [KeyStatus]
    		test	al, 4
    		jnz	short loc_DE6
    		test	al, 80h
    		jnz	short loc_DE0
    		or	ah, 2
    		jmp	short loc_DF3
    
    loc_DE0:				
    		and	ah, 1
    		jmp	short loc_DF3
    
    loc_DE6:	test	al, 80h
    		jnz	short loc_DF0
    		or	ah, 1
    		jmp	short loc_DF3
    
    loc_DF0:	and	ah, 2
    
    loc_DF3:	and	ah, 3
    		mov	[KeyStatus], ah
    		mov	al, ah
    		mov	byte [Last_mask], 0
    		call    Update_keyCount
    		call	Call_User
    		pop	ds
    		pop	es
    		popa
    		pop	ax	;pre-interrupt AX preserved!
    		iret
    ; 
    
    GoTo_OldInt:	pop	ax
    		jmp	far [cs:Old_INT09]
    
    ;  S U B	R O U T	I N E 
    
    ;corrupt only AX!
    Has_been_pressed_a_Mkey:
    		in	al, 64h		; AT Keyboard controller 8042.
    		and	al, 0D0h
    		jz	short loc_1C2C
    		xor	ax, ax
    		ret
    
    loc_1C2C:	in	al, 60h		; AT Keyboard controller 8042.
    		mov	ah, al
    		cli
    		mov	al, 61h		; Ok, key processed!
    		out	20h, al		; Interrupt controller,	8259A.
    		sti
    		mov	al, ah
    no_fun:		ret
    
    no_user_fun:	
    		retf
    
    ;  S U B	R O U T	I N E 
    
    Update_keyCount:		;AL= xxxxxLxR
    
    		mov	bx, [Button_Status]
    		mov	byte [Button_Status],	al
    
    		xor	cx, cx	;azzeriamo  CH  CL - CH tiene i bit RRLL, CL il numero di shift da fare
    		xor	al, bl
    		shr	al, 1	;tasto SX: Carry =1 se cambiato =0 se non cambiato rispetto al vecchio status
    		rcr	ch, 1	;inseriamo questo valore nel byte, al primo posto (+ significativo)
    		shr	ah, 1	; Carry =1 se Pressed =0 se released
    		rcl	cl, 1	; Qui CL diventa 1 se il tasto  pressed!
    		shr	ch, cl	; Se pressed  il quarto bit da mettere a 1, quindi lo spingo ancora avanti tipo "01000000"
    				; finito con il tasto sinistro = CH="LL000000"
    		mov	cl, 0
    		shr	ah, 1	; Carry =1 se Pressed =0 se released
    		cmc		; Toggles (inverts) the Carry Flag
    		rcl	cl, 1	; Qui CL diventa 1 se il tasto  released!
    		shr	ch, cl	; aggiungiamo uno zero se  released -> "0LL0000", altrimenti invariato
    
    		shr	al, 1	; tasto DX: Carry =1 se cambiato =0 se non cambiato rispetto al vecchio status
    		rcr	ch, 1	; lo aggiungiamo al solito a sx: adesso abbiamo: "RLL00000" o "RRLL0000"
    		xor	cl, 1	; Inverto CL: se era 0 diventa 1 e viceversa
    		shr	ch, cl	; quindi aggiungiamo uno zero se  pressed -> "0RLL0000", altrimenti invariato
    
    		shr	ch, 4   ;adesso abbiamo in CH i 4 bit 0000RRLL
    		mov	dh, ch
    		mov	dl, ch
    		shl	dl, 1	;DL  pronto per andare in [last_mask] '000RRLL0'
    
    		mov	si, [MouseX_Sum]
    		mov	di, [MouseY_Sum]
    		
    		xor	bx, bx
    		mov	cl, 4	;4 passaggi LB_Press, LB_Release, RB_Press, RB_Release
    .next		shr	dh, 1
    		jc	.updatePR
    .cont		add	bx, LB_Count_releases-LB_Count_press
    		loop	.next
    
    		mov	byte [Last_mask], dl
    		ret
    
    .updatePR	inc	word [LB_Count_press+bx]
    		mov	word [LB_PosX_last_press+bx], si
    		mov	word [LB_PosY_last_press+bx], di
    		jmp 	.cont
    
    ; 
    
    INT_33:
    %ifdef CALL_OLD_INT33
    	or      ah, ah
    	jnz     call_old33_if_exist
    %endif
    	sti        
    	call    Call_Subfun
    end_int33:	
    	iret
    
    call_old33_if_exist:
    %ifdef CALL_OLD_INT33
    	cmp     word [cs:Old_INT33+2], 0
    	jz      end_int33
    	jmp     far [cs:Old_INT33]
    %endif
    
    ; 
    
    Install_INT09_MONK:
    	cli
    	mov     ax, 3509h
    	int     21h             ; DOS - 2+ - GET INTERRUPT VECTOR
    				; AL = interrupt number
    				; Return: ES:BX = value of interrupt vector
    	mov     word [Old_INT09_MONK], bx
    	mov     word [Old_INT09_MONK+2], es
    	mov     dx, INT_09bis ; Int 09 (BIS) Entry Point
    	mov     ax, 2509h
    	int     21h             ; DOS - SET INTERRUPT VECTOR
    				; AL = interrupt number
    				; DS:DX = new vector to be used for specified interrupt
    	sti
    	ret
    
    ; 
    
    ;check for INT_09 hook!
    Check_INT09_MONK:
    		xor	ax, ax
    		mov	es, ax
    		mov	ax, cs
    		cmp     word [ES:09h*4+2], ax	;check for int09 data segment
    		je	allok
    		;SEMPLIFICO: se non  nel segmento la cambio altrimenti lascio stare!
    		;mov     ax, 3509h
    		;int     21h             ; DOS - 2+ - GET INTERRUPT VECTOR
    		;			; AL = interrupt number
    		;			; Return: ES:BX = value of interrupt vector
    		;mov	ax, cs
    		;mov	cx, es
    		;cmp     ax, cx		
    		;jne	install_newint	;qualcuno (monkey?) ha cambiato l'int 09
    		;mov	cx, INT_09
    		;cmp     cx, bx
    		;je	allok
    		;mov	cx, INT_09bis
    		;cmp     cx, bx
    		;je	allok
    install_newint:	call	Install_INT09_MONK
    		
    allok:		ret
    
    ;  S U B	R O U T	I N E 
    
    Reset_pointer_and_var:
    		xor	ax, ax				;mov mem, ax  pi veloce e occupa meno di mov mem,0
    		mov	bx, 8				;per i valori da 8
    		mov     word [MouseX_Sum], 320
    		mov     word [MouseY_Sum], 100
    		mov     word [Hor_Ratio], bx
    		mov     word [Vert_Ratio], bx
    		mov     byte [Already_in_user], al
    		mov	byte [User_Event_Mask], al
    		mov	word [Event_Handler_Addr+2], cs
    		mov	dx, no_user_fun
    		mov	word [Event_Handler_Addr], dx
    		mov     word [H_Mickey_Count], ax ; horizontal mickey count (-32768 to 32767)
    		mov     word [V_Mickey_Count], ax
    		mov     word [X_Mult_Ratio], bx
    		mov     word [Y_Mult_Ratio], bx
    		mov     byte [CenterX], 15
    		mov     byte [CenterY], 15
    		mov     byte [Max_speed_D2], 2
    		mov     byte [Max_Speed_D], 35h
    
    		mov     word [MIN_VRange], ax
    		mov     word [MIN_HRange], ax
    		mov	BYTE [shift_X_Pos], al
    
    		;check for INT_09 hook!
    		call	Check_INT09_MONK
    		
    		mov     ah, 0Fh
    		int     10h             ; - VIDEO - GET CURRENT VIDEO MODE
    					; Return: AH = number of columns on screen
    					; AL = current video mode
    					; BH = current active display page
    		mov     word [MAX_VRange], 199
    		mov     word [MAX_HRange], 639
    		cmp	al, 06h
    		je	cnt1
    		mov	BYTE [shift_X_Pos], 1
    
    cnt1:		lea     si, [screenmask]
    		call 	Copy_cursor_shape	; Copy cursor addressed by DS:SI 
    		call	TransMult
    		ret
    
    ;  S U B	R O U T	I N E 
    
    ; Reset/Query driver Presence
    
    Fun_00:		mov	[Cursor_Flag], byte 0
    		call	Fun_02
    		call	Reset_pointer_and_var
    		xor	ax,ax
    		mov	byte [User_Event_Mask], al ; Changed: Cursor pos,left press, left rel,	right press, right rel
    		dec	ax		;mov	ax, 0FFFFh	;INSTALLED
    		mov	[ORG_AX], ax
    		mov	ax, 2		;0FFFFh	;2 Buttons	
    		mov	[ORG_BX], ax
    		ret
    
    ;  S U B	R O U T	I N E 
    
    ; Display Pointer
    
    Fun_01		cmp	byte [Cursor_Flag], 0	; default -1 (FF) not visible
    						; visible=0
    		jz	end_fun_01		; gi visibile
    		inc	byte [Cursor_Flag]
    		jnz	end_fun_01
    
    		mov	ah, byte [Cursor_attribute]	
    		mov 	al, 68h+80h
    		out	0DDh,AX		;DD->AL DE->AH
    		jmp 	adjust_cur		
    
    end_fun_01:	ret
    
    
    ;  S U B	R O U T	I N E 
    
    ; Hide Pointer
    
    Fun_02		dec	byte [Cursor_Flag]
    		;cmp	byte [Cursor_Flag], 0FFh	; default -1 (FF) not visible
    							; visible=0
    		;jnz	end_fun_02			; always HIDE!
    
    		mov 	al, 68h+80h
    		mov	ah, 0Fh		;cursor transparent
    		out	0DDh,AX		;DD->AL DE->AH
    
    end_fun_02:	ret
    
    
    ;  S U B	R O U T	I N E 
    
    ; Query	Position & Buttons
    
    Fun_03:		;pushf			; out:
    					; CX = Horizontal (X) position
    					; DX = Vertical	(Y) position
    					; BX = Button Status (bit 0-1=L-R)
    		mov	ax, [Button_Status]
    		mov	[ORG_BX], ax
    		mov	ax, [MouseX_Sum]
    		mov	[ORG_CX], ax
    		mov	ax, [MouseY_Sum]
    		mov	[ORG_DX], ax
    		;popf
    		;check for INT_09 hook!
    		call	Check_INT09_MONK
    		ret
    
    
    ;  S U B	R O U T	I N E 
    
    ; Move Pointer
    
    Fun_04:		mov	ax, dx
    		call	Verify_in_VRange ; Verify if pointer in	Vertical Range
    					; if not then move
    		mov	bx, ax
    		mov	ax, cx
    		call	Verify_in_HRange ; Verify if pointer in	Horizontal Range
    					 ; if not then move
    		mov	[MouseX_Sum],	ax
    		mov	[MouseY_Sum],	bx
    
    		cmp	byte [Cursor_Flag], 0	; default -1 (FF) not visible
    						; visible=0
    		jnz	endfun4
    		
    adjust_cur	mov	BL, 0Fh			;usede to call/ret on update_cursor ^^
    		call 	update_cur
    			
    endfun4:
    		ret
    
    ;  S U B	R O U T	I N E 
    
    ; Query	Button Pressed count
    ; BX = 0  left button
    ;      1  right	button
    ;
    ;
    ;	  on return:
    ;	  BX = count of	button presses (0-32767), set to zero after call
    ;	  CX = horizontal position at last press
    ;	  DX = vertical	position at last press
    ;	  AX = status:
    ;		  |F-8|7|6|5|4|3|2|1|0|	 Button	Status
    ;		    |  | | | | | | | `---- left	button (1 = pressed)
    ;		    |  | | | | | | `----- right	button (1 = pressed)
    ;		    `------------------- unused
    
    Fun_05:		cmp	bx, 1
    		ja	Fun05_end
    		jb	Fun_05Out
    		mov	bx, RB_Count_press-LB_Count_press	;0=SX o delta=DX
    Fun_05Out:	xor	ax, ax
    		xchg	ax, [LB_Count_press+BX]		;cos azzero anche COUNT con un'unica istruzione, veloce!
    		mov	[ORG_BX],	ax
    		mov	ax, [LB_PosX_last_press+BX]
    		mov	[ORG_CX],	ax
    		mov	ax, [LB_PosY_last_press+BX]
    		mov	[ORG_DX],	ax
    		mov	ax, [Button_Status]
    		mov	[ORG_AX],	ax
    Fun05_end:	ret
    
    
    ; Get Mouse Button Release Information
    ;
    ; BL=Button
    ;
    ; on return:
    ;	  BX = count of	button releases	(0-32767), set to zero after call
    ;	  CX = horizontal position at last release
    ;	  DX = vertical	position at last release
    ;	  AX = status
    
    Fun_06:
    		cmp	bx, 1
    		ja	Fun05_end
    		jb	.phase2		;se bx=0 don't add L/R offset
    		mov	bx, RB_Count_press-LB_Count_press
    .phase2		add	bx, LB_Count_releases-LB_Count_press
    		jmp	Fun_05Out
    
    
    ;  S U B	R O U T	I N E 
    
    ; Set Horizontal range
    ; CX = minimum H pos
    ; DX = maximum H pos
    
    Fun_07:		call	Invert		; Invert CX/DX if necessary (DX<CX)
    		;pushf
    		cli
    		mov	[MIN_HRange], cx
    		mov	[MAX_HRange], dx
    		mov	ax, [MouseX_Sum]
    		call	Verify_in_HRange ; Verify if pointer in	Horizontal Range
    					 ; if not then move
    		mov	[MouseX_Sum],	ax
    		;popf
    		jmp	adjust_cur
    
    
    ;  S U B	R O U T	I N E 
    
    ; Set Vertical range
    ; CX = minimum V pos
    ; DX = maximum V pos
    
    Fun_08		call	Invert		; Invert CX/DX if necessary (DX<CX)
    		;pushf
    		cli
    		mov	[MIN_VRange], cx
    		mov	[MAX_VRange], dx
    		mov	ax, [MouseY_Sum]
    		call	Verify_in_VRange ; Verify if pointer in	Vertical Range
    					; if not then move
    		mov	[MouseY_Sum],	ax
    		;popf
    		jmp	adjust_cur
    
    ;  S U B	R O U T	I N E 
    
    ; Set graphic pointer shape
    ; BX = horizontal hot spot (-16	to 16)
    ; CX = vertical	hot spot (-16 to 16)
    ; ES:DX	= pointer to screen and	cursor masks (16 byte bitmap)
    
    Fun_09:		cli
    		neg	bx
    		add	bx, 16
    		mov	[CenterX], bx
    		neg	cx
    		add	cx, 16
    		mov	[CenterY], cx
    		push	ds
    		mov	si, dx
    		mov	ax, [ORG_ES]
    		mov	ds, ax
    		pop	es
    		call	Copy_cursor_shape
    		push	es
    		pop	ds
    		sti
    		jmp	adjust_cur		; cambiato il centro!
    		;ret
    
    
    ;  S U B	R O U T	I N E 
    
    ; Copy cursor addressed by DS:SI 
    
    Copy_cursor_shape:		
    	mov	dx, 0DDh		;sistemiamo lo sprite...
    	xor	ax, ax
    	out	dx, al
    	inc	dx
    	cld
    
    	mov     cx, 20h		;32 valori word (64 byte)
    .copy_next:
    	lodsw                   ; Load Cursor value
    	cmp	cx, 10h		; if first 32 byte
    	jbe	.ok		; also slow down a little the procedure: too fast in a "0-wait-state" PC1!
    	not	ax		; invert it -> also is some byte less (8 byte!)
    .ok:	xchg	ah,al
    	out 	dx, al
    	xchg	ah,al
    	out 	dx, al
    	loop    .copy_next       ; Load Values
    
    	ret
    
    ;  S U B R O U T I N E 
    
    ; Normally Set text pointer mask
    ; but in this special driver set the graphics cursor color attribute
    ; BX = FF , then CX = AND/XOR attribute. F0 = white/black not trasparent.
    ; DX = 1 -> blink
    
    Fun_0A:		cmp     bl, 0FFh 
    		jnz     endfun
    		mov 	byte [Cursor_attribute], cl
    		mov	al, 64h+80h		;register 64h
    		out	0DDh, al
    		xchg	al, dl
    		or	al, 110b	;set mask/and/xor = ON
    		out	0DEh, al
    		dec	byte [Cursor_Flag]
    		jmp 	Fun_01
    ;endfun0A:	ret
    
    ;  S U B	R O U T	I N E 
    
    ; Query	last motion distance
    
    Fun_0B:		;pushf
    		cli
    		xor	ax, ax			;cos azzeriamo in un passaggio solo!
    		xchg	ax, [H_Mickey_Count] ; horizontal	mickey count (-32768 to	32767)
    		mov	[ORG_CX],	ax
    		xor	ax, ax
    		xchg	ax, [V_Mickey_Count] ; vertical mickey count (-32768 to 32767)
    		mov	[ORG_DX],	ax
    		;popf
    endfun:		ret
    
    ;  S U B	R O U T	I N E 
    
    ; Set Event Handler
    
    Fun_0C:		;pushf
    		cli
    		mov	word [Event_Handler_Addr], dx
    		mov	dx, [ORG_ES]
    		mov	word [Event_Handler_Addr+2], dx
    		and	cl, 7Fh		; exclude high bit (7)
    		mov	byte [User_Event_Mask], cl ; Changed: Cursor pos,left press, left rel,	right press, right rel
    		;popf
    		sti
    		ret
    
    ;Fun_0D:		ret
    ;Fun_0E:		ret
     
    ;  S U B R O U T I N E 
    
    ; Set Pointer Speed
    ; CX= Horizontal Ratio
    ; DX= Vertical Ratio
    
    Fun_0F: 	;cmp	cx,0
    		;je	EndFun10	;una divisione per /0 avrebbe esiti funesti!
    		;cmp	dx,0
    		;je	EndFun10
    		;mov     [Hor_Ratio], cx
    		;mov     [Vert_Ratio], dx
    
    		xchg	ax, cx		;se porto tutto su AX risparmio 1 byte ogni operazione!
    		cmp	ax, word 0000h
    		je	.skipHor	;una divisione per /0 avrebbe esiti funesti!
    		mov     [Hor_Ratio], ax
    .skipHor	xchg	ax, dx
    		cmp	ax, word 0000h		;una divisione per /0 avrebbe esiti funesti!
    		je	EndFun		;pulcioso, ma risparmio 1 byte
    		mov     [Vert_Ratio], ax
    		jmp	TransMult	
    
    ;Fun_10:		ret
    
    ;  S U B R O U T I N E 
    
    ; Get driver type
    ; return_ AX= 33h
    Fun_11:		mov	ax, 33h		;Special PC1 mouse driver
    		mov	[ORG_AX], ax
    		mov	al, 2
    		mov	[ORG_BX], ax	;number of buttons
    EndFun:		ret
    
    ;Fun_12:		ret
    
    ;  S U B R O U T I N E 
    
    ; Set max for Speed Doubling
    
    Fun_13:		xchg    ax, dx
    		mov     [Max_Speed_D], ax
    		add     ax, 11h
    		mov     bx, 23h
    		xor     dx, dx
    		div     bx
    		mov     [Max_speed_D2], ax
    		ret
    
    
    ;  S U B	R O U T	I N E 
    
    ; Exchange Event Handler
    
    Fun_14:		;pushf
    		cli
    		mov	ax, word [Event_Handler_Addr]
    		mov	[ORG_DX],	ax
    		mov	word [Event_Handler_Addr], dx
    		mov	dx, [ORG_ES]
    		mov	ax, word [Event_Handler_Addr+2]
    		mov	[ORG_ES],	ax
    		mov	word [Event_Handler_Addr+2], dx
    		xor	ax, ax
    		mov	al, byte [User_Event_Mask] ; Changed: Cursor pos,left press, left rel,	right press, right rel
    		mov	[ORG_CX],	ax
    		and	cl, 7Fh
    		mov	byte [User_Event_Mask], cl ; Changed: Cursor pos,left press, left rel,	right press, right rel
    		sti
    		;popf
    EndFun14:	ret
    
    ;Fun_15:		ret
    ;Fun_16:		ret
    ;Fun_17:		ret
    ;Fun_18:		ret
    ;Fun_19:		ret
    
     ;  S U B R O U T I N E 
    
    ; Transform multiplier in SHIFT-LEFT
    ; me ne sbatto dei risultati che hanno un rapporto Mult/Ratio < 1 anche perch il mouse  gi lento cos di suo
    ; [shift_X_Pos] gi considerato!
    
    TransMult:	mov 	al, byte [shift_X_Pos]		;parto da questo valore
    		mov	byte [shift_ratioX], al
    		mov     ax, [X_Mult_Ratio]
    		xor	dx, dx
    		div	word [Hor_Ratio]
    .redo1:		shr	AX, 1
    		cmp	ax, 0
    		je	.ok1
    		inc	byte [shift_ratioX]
    		jmp	.redo1
    		
    .ok1:		mov	byte [shift_ratioY], 0
    		mov     ax, [Y_Mult_Ratio]
    		xor	dx, dx
    		div	word [Vert_Ratio]
    .redo2:		shr	AX, 1
    		cmp	ax, 0
    		je	EndFun14	;.ok2 - pulcioso ma risparmio!
    		inc	byte [shift_ratioY]
    		jmp	.redo2
    ;.ok2:		ret
    
     ;  S U B R O U T I N E 
    
    ; Set mouse sensivity
    ;         BX = horizontal coordinates per pixel
    ;         CX = vertical coordinates per pixel
    ;         DX = double speed threshold
    
    Fun_1A:		shr	bx, 2
    		mov     [X_Mult_Ratio], bx
    		shr	cx, 2
    		mov     [Y_Mult_Ratio], cx
    		call	TransMult
    		jmp     Fun_13          ; Set max for Speed Doubling
    
    ;  S U B R O U T I N E 
    
    ;adjust_mult:	mov     bl, 0Ah
    ;		div     bl
    ;		xor     ah, ah
    ;		cmp     al, 0Ah
    ;		jbe     short loc_B9B
    ;		mov     al, 0Ah
    ;loc_B9B:	mov     bx, moltiplic
    ;		;add     bx, ax
    ;		;mov     al, [bx]	;qui uso XLAT = mov al, [BX+AL]
    ;		XLAT
    ;		ret
    ; ---------------------------------------------------------------------------
    ;moltiplic       db 1, 2, 3, 4, 6, 8, 0Ah, 0Eh, 12h, 16h, 1Eh
    
    
    ;  S U B R O U T I N E 
    
    ; Query Mouse Sensivity
    
    Fun_1B:		;mov     ax, [Hor_CoordXPixel]
    		mov     ax, [X_Mult_Ratio]
    		shl	ax, 2
    		mov     [ORG_BX], ax
    		;mov     ax, [Ver_CoordXPixel]
    		mov     ax, [Y_Mult_Ratio]
    		shl	ax, 2
    		mov     [ORG_CX], ax
    		mov     ax, [Max_Speed_D]
    		mov     [ORG_DX], ax
    		ret
    
    ;Fun_1C:		ret
    
    ;Fun_1D:	mov     [CRT_page_num], bx
    ;		ret
    
    ;Fun_1E:	mov     ax, [CRT_page_num]
    ;             	mov    [ORG_BX], ax
    ;		ret
    
    ;Fun_1F:		ret
    ;Fun_20:		ret
    ;Fun_21:		ret
    ;Fun_22:		ret
    
    ; LANGUAGE = ITA!!! :)
    Fun_23:		mov     word [ORG_BX], 08h
    		ret
    
    ; 24 - Get software version, mouse type and IRQ
    ; Out:	[AX] = 24h/FFFFh	(installed/error)
    ;	[BX]			(version)
    ;	[CL]			(IRQ #/0=PS/2)
    ;	[CH] = 1=bus/2=serial/3=InPort/4=PS2/5=HP (mouse type)
    ; Use:	driverversion
    Fun_24:		mov     word [ORG_BX], driverversion
    		mov	word [ORG_CX], 0309h	;inport, IRQ=09
    		ret
    
    ;  S U B	R O U T	I N E 
    
    ; Call INT 33 subfunction in AX
    
    Call_Subfun:	push	bp
    		push	ds
    		push	cs	;right segment!
    		pop	ds
    		mov	[ORG_AX], ax
    		mov	[ORG_BX], bx
    		mov	[ORG_CX], cx
    		mov	[ORG_DX], dx
    		mov	[ORG_DI], di
    		mov	[ORG_SI], si
    		mov	[ORG_ES], es
    		push	ds
    		pop	es
    		cmp	ax, 14h
    		ja	short OtherFuns	; other functions!
    		push	si
    		mov	si, ax
    		shl	si, 1
    		mov	ax, [Int33_sub_index+si]
    		pop	si
    call_it:	call	ax
    		jmp	short loc_6F5
    
    ; 
    ; 2A - Get cursor hot spot
    ; Out:	[AX]			(cursor visibility counter)
    ;	[BX]			(hot spot X)
    ;	[CX]			(hot spot Y)
    ;	[DX] = 1=bus/2=serial/3=InPort/4=PS2/5=HP (mouse type)	
    ;		cmp	al, 2Ah
    ;		jnz	short Fun_4D
    ;		mov	ax, [Cursor_Flag]
    ;		mov	[ORG_AX], AX
    ;		mov	ax, 16
    ;		sub	ax, [CenterX]
    ;		mov	[ORG_BX], AX
    ;		mov	ax, 16
    ;		sub	ax, [CenterY]
    ;		mov	[ORG_CX], AX
    ;		mov	word [ORG_DX], 3	;inport mouse
    ;		jmp	short loc_6F5
    
    Fun_4D:		; Pointer to Microsoft Label!
    		mov	word [ORG_DI], Copyright1983
    		mov	[ORG_ES], cs
    		ret
    
    Fun_6D:		jnz	short loc_6F5
    		mov	[ORG_DI], word magicnumber ;word 204h
    		mov	[ORG_ES], cs
    		ret
    
    execute:	shl	bx,1
    		call	[CS:other_address+bX]
    		jmp	short loc_6F5	
    
    OtherFuns:	mov	bx, 4
    more:		cmp 	al, [other_num+bx]
    		jz	execute
    		dec	bx
    		jnz	more
    
    loc_6F5:
    		mov	ax, [ORG_ES]
    		mov	es, ax
    		mov	si, [ORG_SI]
    		mov	di, [ORG_DI]
    		mov	dx, [ORG_DX]
    		mov	cx, [ORG_CX]
    		mov	bx, [ORG_BX]
    		mov	ax, [ORG_AX]
    		pop	ds
    		pop	bp
    		ret
    
    other_address: 	dw Fun_1A, Fun_1B, Fun_23, Fun_24, Fun_4D, Fun_6D
    other_num	db 1Ah, 1Bh, 23h, 24h, 4Dh, 6Dh
    
    ;  S U B	R O U T	I N E 
    
    
    Call_User:
    		cmp	byte [Already_in_user], 0FFh
    		jz	endend
    		mov	byte [Already_in_user], 0FFh
    		xor	ax,ax
    		mov	al, byte [Last_mask]
    		and	al, byte [User_Event_Mask] ; Changed: Cursor pos,left press, left rel,	right press, right rel
    		mov	bp, Event_Handler_Addr ;	   Custom Event Handler
    		jz	no_sub
    		call	CALL_FUN_AT_BP	; call function	(save all registers)
    					; @ BasePointer
    no_sub:		mov	byte [Already_in_user], 0
    
    endend:		ret
    
    ;  S U B	R O U T	I N E 
    
    ; call function	(save all registers)
    ; @ BasePointer
    
    CALL_FUN_AT_BP:	
    		mov	bx, [Button_Status]
    		mov	cx, [MouseX_Sum]
    		mov	dx, [MouseY_Sum]
    		mov	si, word [H_Mickey_Count] ; horizontal	mickey count (-32768 to	32767)
    		mov	di, word [V_Mickey_Count] ; vertical mickey count (-32768 to 32767)
    		;pushf
    		sti
    		call	far [cs:bp]
    		;popf
    		PUSH	CS		;return to my DS segment
    		POP	DS
    		ret
    
    
     ;  S U B R O U T I N E 
    
     ; Invert CX/DX if necessary (DX<CX)
    
    Invert:		cmp     cx, dx
    		jl      short locret_D05
    		xchg    cx, dx
    locret_D05: 	ret
    
    
    ;  S U B	R O U T	I N E 
    
    ;Input:     AX=Vertical Pos
    ; Verify if pointer in Vertical	Range
    ; if not then move
    ; Corrupt AX, DX
    
    Verify_in_VRange:
    		;push	dx
                    mov     dx, [CS:MIN_VRange]
    		cmp	ax, dx
    		jl	short .set
                    mov     dx, [CS:MAX_VRange]
    		cmp	ax, dx
    		jle	short .skip
    
    .set:
    		mov	ax, dx
    
    .skip:		;pop	dx
    		ret
    
    ;  S U B	R O U T	I N E 
    
    ;Input:     AX=Horizontal Pos
    ; Verify if pointer in Horizontal Range
    ; if not then move
    ; Corrupt AX, DX
    
    Verify_in_HRange:
    		;push	dx
                    mov     dx, [CS:MIN_HRange]
    		cmp	ax, dx
    		jl	short set2
                    mov     dx, [CS:MAX_HRange]
    		cmp	ax, dx
    		jle	short skip3
    
    set2:
    		mov	ax, dx
    
    skip3:		;pop 	dx
    		ret
    
    ;************** Constants / Costanti ****************************************
    Copyright1983 db 'Copyright 1983 Microsoft ***'
    magicnumber db 55h, 64h
    ; ========================== END OF RESIDENT PART =========================
    
    notresident:
    db '*** This is a PC1 mouse driver by Riminucci Simone (c) 2016, but some software expect here the upper string!'
    welcome DB      ' MOUSE-PC1 Driver ver. 0.97 - Simone Riminucci (C) 2016',0Dh,0Ah,'$'
    already	DB	'۲     Un driver Š gi… installato     ',0Dh,0Ah,'$'
    EGAVGA	DB	'۲ EGA/VGA Patch installata (funz. avanzate disab.) ',0Dh,0Ah,'$'
    ForceIn db 	'F: Il driver sar… installato sopra uno esistente',0Dh,0Ah,'$'
    SiamoSpiacenti  db 'Non Š stato possibile installare il driver del mouse',0Dh,0Ah
    		db 'Questo mouse driver funziona solo su OLIVETTI PRODEST PC1. ',0Ah, 0Dh,'$'
    aSpiacentiIlMou db '۲     Attenzione:  il mouse NON Š connesso.     ',0Ah,0Dh,'$'
    
    helpmsg	db	0Ah,0Dh,"Parametri:",0Ah,0Dh
    	db	0Ah,0Dh
    	db	"/I - Non verificare se su Olivetti Prodest PC1",0Ah,0Dh
    	db	"/M - Mostra subito il cursore in DOS",0Ah,0Dh
    	db	"/F - Forza l'installazione anche su driver esistente",0Ah,0Dh
    	db	"/E - Forza l'installazione della Patch EGA/VGA",0Ah,0Dh
    	db	"$"
    
    Equipment_Addr 	dw 0A1h
    
    start:
    	push	cs
    	pop	ds
    	lea     dx, [welcome] ; "Benvenuti"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING	
    
    	call    process_cmdline         ; grab switches, etc
    
    	test	byte [cmdlineflags], help
    	jnz	display_help
    
    	test	byte [cmdlineflags], nocheck
    	jnz	skipcheck
    
    	call	check_for_PC1
    	or      ax, ax
    	jz      not_PC1
    
    skipcheck:	
    	mov 	AX,0000h	;intallation check if already installed
    	int	33h
    	cmp	AX,0FFFFh
    %ifndef DEBUG
    	jne	cont0
    	test	byte [cmdlineflags], forceinst
    	jz	terminate
    	lea     dx, [ForceIn] ; ">Forced!"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING
    %endif
    
    cont0:	
    	cli
    	call    set_mouse_keyb			; Set keyboard chip 8042
    						; to respond to mouse click -> scancode
    						; Left Button   77h
    						; Middle Button 78h
    						; Right Button  79h
    	or      al, al
    %ifndef DEBUG
    	jz      short print_mouse_non_connesso
    %endif
    	call    Install_INT08
    	call    Install_INT09
    	call    Install_INT33
    	
    	call	reset_V6355D
            call    Reset_pointer_and_var
    	
    	test	byte [cmdlineflags], showcurs
    	jz	skipshow
            call    Fun_01
    
    skipshow:
            STI
    
    terminate_but_stay_resident:
    
    cont3:		
    	mov     ah, 51h         ;Get application's PSP address
            int     21h		;we get it in bx
    	mov     es, bx
    	mov     es, [es:2Ch]    ;Get address of environment block.
    	mov     ah, 49h         ;DOS deallocate block call.
    	int     21h		;get rid of PSP!
    
    	mov	dx, notresident		; only resident part will be saved
    
    	mov	cl, 4
    	shr	dx, cl			; paragraph to keep
    	inc	dx			; 1 paragraph more... safer for roundings
    
    	MOV	AX, 3100h	;
    	INT 	21h		;stay resident and exit
    
    terminate:
    	lea     dx, [already] ; "Gi installato!"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING
    error:
    	MOV 	AX, 4C01h	;AH 4C = Exit to DOS, ERRORLEVEL AL 01
    	INT	21h
    
    print_mouse_non_connesso:
    	lea     dx, [aSpiacentiIlMou] ; "Non connesso!"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING
    	MOV 	AX, 4C02h	;AH 4C = Exit to DOS, ERRORLEVEL AL 02
    	INT	21h
    
    reset_V6355D:
    	cli
    	;mov 	dx, 3DDh
    	;mov 	al, 65h+80h
    	;out	dx, al
    	;inc	dx
    	;mov	al, 89h		;mouse enable
    	;out	dx, al
    	push	ds
    	mov     bx, [Equipment_Addr]                               
    	mov     ax, BIOS_DATA_SEG
    	mov     ds, ax
    	mov     al, [bx]
    	pop	ds
    	test	byte [cmdlineflags], forceEGA
    	jnz	.force
    	test	al, 1
    	jz	.cont
    .force	and     al, 0FEh        ; azzera l'ultimo bit
    	;;;;mov     [bx], al	; lo riscrivo indietro in modo che non venga pi cambiato!?!?
    	or      byte [cmdlineflags], forceEGA  ; mi segno che era quello!
    	out     68h, al         ; cos "accende" lo schermo V6355D e il counter del mouse
    	in	al, 0D1h
    	cmp	al, 0FFh	; questo controllo  utile solo per computer non-pc1
    	jnz	.wmsg
    	test	byte [cmdlineflags], nocheck
    	jz	not_PC1
    .wmsg	lea     dx, [EGAVGA] ; "EGA/VGA Patch installed"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING	
    
    .cont	mov 	dx, 3DDh
    	mov 	al, 64h+80h
    	out	dx, al
    	inc	dx
    	mov	al, 6h		;mouse AND & XOR enable
    	out	dx, al
    	sti
            ret
    
    check_for_PC1:
    
    PC1_Equipment_Addr 	EQU 89h
    PC1HD_Equipment_Addr 	EQU 0A1h
    
    	push    bx
    	push    ds
    	mov     ax, 0F000h
    	mov     ds, ax
    	mov     bx, 0FFFDh      ; penultimi due byte del BIOS
    	mov     ax, [bx]
    	pop	ds
    	mov	bl, PC1HD_Equipment_Addr
    	cmp     ax, 0FE44h      ; PC1 - Floppy
    	jz      short pc1dd
    	cmp     ax, 0FE49h      ; PC1 - Unknown
    	jz      short loc_2B1C
    	cmp     ax, 0FE4Ah      ; PC1 - HD
    	jnz     short loc_2B22
    
    pc1dd:	mov	bl, PC1_Equipment_Addr
    
    loc_2B1C:                               
    	mov     ax, 0FFh
    	jmp     short loc_2B25
    
    loc_2B22:                               
    	mov     ax, 0
    
    loc_2B25:                                                          
    	mov	[Equipment_Addr],bl   
    	pop     bx
    	ret
    
    not_PC1:
    	lea     dx, [SiamoSpiacenti] ; "Siamo spiacenti di non poter installare"...
    	mov     ah, 9
    	int     21h             ; DOS - PRINT STRING
    				; DS:DX -> string terminated by "$"
    	jmp	error
    
    Value_for_8042  db 12h, 77h, 78h, 79h, 1	;valori dei tre tasti del mouse: 77h 78h 79h
    
    set_mouse_keyb:
    	cli
    	mov     al, 12h
    	push    ax
    	mov     dx, 64h
    wait_8042:
    	in      al, dx          ; AT Keyboard controller 8042.
    	and     al, 2
    	jnz     short wait_8042
    	pop     ax
    	out     dx, al          ; AT Keyboard controller 8042.
    wait_8042f:
    	in      al, 64h         ; AT Keyboard controller 8042.
    	and     al, 1
    	jz      short wait_8042f
    	in      al, 60h         ; AT Keyboard controller 8042.
    	and     al, 1
    	jnz     short skip
    	push    si
    	lea     si, [Value_for_8042]
    	mov     cx, 5
    	cld
    load_next:
    	lodsb                   ; Load Value: 12h 77h 78h 79h 01
    	push    ax
    	mov     dx, 64h
    wait_8042g:
    	in      al, dx          ; AT Keyboard controller 8042.
    	and     al, 2
    	jnz     short wait_8042g
    	pop     ax
    	mov     dx, 60h
    	out     dx, al          ; AT Keyboard controller 8042.
    	loop    load_next       ; Load Value: 12h 77h 78h 79h 01
    	mov     ax, 0FFh
    	pop     si
    	sti
    	ret
    skip:	xor	ax, ax
    	sti
    	ret
    
    ;===========================================================================
    ;Procedure: ucase
    ;Purpose:   Converts character in AL to uppercase.
    ;           
    ;Input:     AL=character
    ;           
    ;Output:    AL=uppercase character (if a-z)
    ;           All other registers preserved.  (flags too)
    ;
    ;Processing: test valid range (a-z), set to upper, exit
    ;---------------------------------------------------------------------------
    ucase:
    	pushf
    	cmp al,"a"                  ;if  it's not a-z, skipit
    	jb noupper
    	cmp al,"z"
    	ja noupper
    	and al,5fh                  ;strip off a few bits to make it upper
    noupper:        
    	popf
    	ret
    
    ;##################### start cmd line interpret ####################
    
    ; command line flags
    help		EQU	BIT0		; help requested
    nocheck		EQU	BIT1		; don't check for PC1
    showcurs	EQU	BIT2		; show cursor at loading
    forceinst	EQU	BIT3		; forced install over an existing driver
    forceEGA	EQU	BIT4		; force EGA/VGA book
    debug		EQU	BIT5		; debug bit
    koverride	EQU	BIT5		; debug bit
    writeprotect	EQU	BIT6		; write protected bit
    noint10		EQU	BIT7		; light INT10 hook (composit)
    
    
    process_cmdline:
    
            push    ds
            push    bx
            push    si
    
            mov     ah, 51h
            int     21h
            mov     ds, bx
    	mov 	cx, bx
    
            mov     si, 80h
    	mov 	bh, 0
    	mov	bl, byte [si]
            add     si, bx
            inc     si
    
            mov     byte [si], NULL             ;zero terminate
    
            mov     si, 81h
    
    cmdlineloop:
    	mov	ds,cx
            lodsb			;Transfers string element addressed by DS:SI to the accumulator
    	push	cs
    	pop	ds
            cmp     al, " "                 ; found a space?
            jz      cmdlineloop
            cmp     al, NULL                ; found end of line?
            jz      exitpc
            cmp     al, "-"                 ; found a flag?
            jz      checkflags
            cmp     al, "/"                 ; found a flag?
            jz      checkflags
    
            ; unknow skip but show help
    	or      byte [cmdlineflags], help
    	jmp 	cmdlineloop
    exitpc: pop     si
            pop     bx
            pop     ds
            
            ret
    
    checkflags:
    	mov	ds,cx
            lodsb			;Transfers string element addressed by DS:SI to the accumulator
    	push	cs
    	pop	ds
            cmp     al, " "                 ; false flag
            jz      cmdlineloop
            cmp     al, NULL                ; found end of line?
            jz      exitpc
            cmp     al, "-"                 ; found a double flag?
            jz      checkflags
            cmp     al, "/"                 ; found a double flag?
            jz      checkflags
    
            ; must be a flag
    
    	call	ucase
    
    	cmp	al, "?"
    	jz	sethelp
    
    	cmp	al, "H"
    	jz	sethelp
    
    	cmp	al, "I"
    	jz	setignorenotPC1
    
    	cmp	al, "M"
    	jz	setshowcursor
    
    	cmp	al, "F"
    	jz	setforceinst
    
    	cmp	al, "E"
    	jz	setforceEGA
    
    	jmp     cmdlineloop             ; nothing we care about, continue
                                            ; could jump to help msg
    sethelp:
            or      byte [cmdlineflags], help
            jmp     checkflags              ; allows flags to be stacked
    
    setignorenotPC1:
            or      byte [cmdlineflags], nocheck
            jmp     checkflags              ; allows flags to be stacked
    
    setshowcursor:
            or      byte [cmdlineflags], showcurs
            jmp     checkflags              ; allows flags to be stacked
    
    setforceinst:
            or      byte [cmdlineflags], forceinst
            jmp     checkflags              ; allows flags to be stacked
    
    setforceEGA:
            or      byte [cmdlineflags], forceEGA
            jmp     checkflags              ; allows flags to be stacked
    
    ;##################### end cmd line interpret ####################
    
    
    Install_INT08:
    	cli
    	mov     ax, 3508h
    	int     21h             ; DOS - 2+ - GET INTERRUPT VECTOR
    				; AL = interrupt number
    				; Return: ES:BX = value of interrupt vector
    	mov     word [Old_INT08], bx
    	mov     word [Old_INT08+2], es
    	mov     dx, INT_08 ; Int 08 Entry Point
    	mov     ax, 2508h
    	int     21h             ; DOS - SET INTERRUPT VECTOR
    				; AL = interrupt number
    				; DS:DX = new vector to be used for specified interrupt
    	sti
    	ret
    
    
    Install_INT09:
    	cli
    	mov     ax, 3509h
    	int     21h             ; DOS - 2+ - GET INTERRUPT VECTOR
    				; AL = interrupt number
    				; Return: ES:BX = value of interrupt vector
    	mov     word [Old_INT09], bx
    	mov     word [Old_INT09+2], es
    	mov     dx, INT_09 ; Int 09 Entry Point
    	mov     ax, 2509h
    	int     21h             ; DOS - SET INTERRUPT VECTOR
    				; AL = interrupt number
    				; DS:DX = new vector to be used for specified interrupt
    	sti
    	ret
    
    Install_INT33:
    	cli
    %ifdef CALL_OLD_INT33
    	push    ds
    	xor     ax, ax
    	mov     ds, ax
    	mov     si, 0CCh
    	mov     bx, [si]
    	mov     cx, [si+2]
    	pop     ds
    	mov     [Old_INT33], bx
    	mov     [Old_INT33+2], cx
    %endif
    	lea     dx, [INT_33]      ; Int33 Entry Point
    	mov     al, 33h
    	mov     ah, 25h		; DOS - SET INTERRUPT VECTOR
    	int     21h             ; AL = interrupt number
    	ret			; DS:DX = new vector to be used for specified interrupt
    
    
    display_help:
    
    	mov	ah, 9
    	lea	dx, [helpmsg]			; display help message
    	int	21h
    	
    exit	mov	ax, 4c02h			; end
    	int	21h
    
    END:
    Sorry but I made some comment in Italian...

    if can help there are two subs that take the problem:

    ;

    Install_INT09_MONK:
    cli
    mov ax, 3509h
    int 21h ; DOS - 2+ - GET INTERRUPT VECTOR
    ; AL = interrupt number
    ; Return: ES:BX = value of interrupt vector
    mov word [Old_INT09_MONK], bx
    mov word [Old_INT09_MONK+2], es
    mov dx, INT_09bis ; Int 09 (BIS) Entry Point
    mov ax, 2509h
    int 21h ; DOS - SET INTERRUPT VECTOR
    ; AL = interrupt number
    ; DSX = new vector to be used for specified interrupt
    sti
    ret

    ;

    ;check for INT_09 hook!
    Check_INT09_MONK:
    xor ax, ax
    mov es, ax
    mov ax, cs
    cmp word [ES:09h*4+2], ax ;check for int09 data segment
    je allok
    ;SEMPLIFICO: se non nel segmento la cambio altrimenti lascio stare!
    ;mov ax, 3509h
    ;int 21h ; DOS - 2+ - GET INTERRUPT VECTOR
    ; ; AL = interrupt number
    ; ; Return: ES:BX = value of interrupt vector
    ;mov ax, cs
    ;mov cx, es
    ;cmp ax, cx
    ;jne install_newint ;qualcuno (monkey?) ha cambiato l'int 09
    ;mov cx, INT_09
    ;cmp cx, bx
    ;je allok
    ;mov cx, INT_09bis
    ;cmp cx, bx
    ;je allok
    install_newint: call Install_INT09_MONK

    allok: ret


    Check_INT09_MONK is called from mouse reset function and resolved Monkey problem (the sub's name hint it)
    But Lemmings needed a supplemental check, and I called it from "Fun 03: Query Position & Buttons". I lost some cycle but Solved the problem.
    Last edited by Simone2013; February 24, 2017, 08:31 AM.

    Leave a comment:


  • Trixter
    replied
    If you provide the source, maybe I or someone can add 6300/M24 support. Or, maybe just the source for your int09-regrabbing code so I can see how you did it, and then maybe I can RE the 6300 mouse driver and add just that section.

    Interestingly the 6300 Mouse driver MOUSE.DOC warns about not taking over the keyboard (and also confirms the mouse and driver were OEM Logitech):

    **Notice to System Programmers**


    System programmers who intercept the keyboard hardware interrupt
    (int 9) or the video i/o software interrupt (int 10h) should
    exercise utmost care, and note the following:


    The mouse driver itself intercepts these two interrupts.


    The mouse driver expects to receive all the codes which are
    relevant for the mouse from the keyboard. If a program which
    intercepts the keyboard interrupt is loaded after the driver the
    following codes from the keyboard should fall through and be
    left available for the mouse driver:




    -2-
    LOGITECH - mouse.doc for AT&T v.1.0 2/85



    77h, 78h, 79h, F7h, F8h, F9h
    7Ah, 7Bh, 7Ch, 7Dh, FAh, FBh, FCh, FDh,
    FEh and the next 2 codes which follow an
    occurrence of FEh (FEh is the prefix character
    for mouse movement reports).


    Codes 74h, 75h, 76h, F4h, F5h, F6h are reserved for future use
    by mouse software.


    All other codes are left by the mouse driver to the next
    interrupt handler on the chain (presumably the ROM resident
    keyboard interrupt handler).
    To check for the presence in memory of the LOGITECH mouse driver
    one should check for a "signature" at the offset 10h from the
    entry of software interrupt S1. The signature is the string
    "LOGITECH MOUSE DRIVER".

    Last edited by Trixter; February 22, 2017, 12:14 PM.

    Leave a comment:


  • Simone2013
    replied
    Originally posted by Trixter View Post
    Great sleuthing! I never thought about it before, but it makes perfect sense: Because the mouse is keyboard-based, if the keyboard interrupt is stolen by the game, then the mouse cannot work.

    Simone, did you ever make your rewritten driver available? I'd like to include it in public archives.
    Hi Trixter, here is the mouse driver with a test program I wrote in TP7: https://www.dropbox.com/s/gib1bau7cy...SEPC1.zip?dl=0

    However it works only with Olivetti Prodest PC1 because of its peculiar chips (is driven by video chip for cursor movement).
    And the difference from original driver is that the cursor is painted by the graphic card itself (hardware sprite) so also in textmode we have a graphic cursor:
    16114682_1852790014939412_6096858600287420564_n.jpg

    or better in this video: https://www.youtube.com/watch?v=-8K9...ature=youtu.be

    AIG: I rewrote the driver to use less ram (it was 10k and mine is 2k) and gain some speed from the graphic cursor... then I find those two games that have problem (monkey is one of my favourite) and adjusted the driver to get it work. basically I checked int09 and get it twice but with a different entry preserving original call address when returning to dos to avoid problems.

    The "bug" was originated because none of the modern mouse driver uses int09 anymore...

    Leave a comment:


  • AlG
    replied
    Thanks for all the informative replys.

    Its good to know its not a wide spread issue and it only affects a few bits of software. Its typical that I chose to use those two pieces of software to test the mouse .

    Simone, its interesting to know the technical reason for the mouse not working. Im assuming it also explains why the mouse doesnt work using its non-driver functionality in these pieces of software. Out of interest, did you rewrite the Prodest PC1 driver just for these pieces of software, or were you already doing it for something else?.
    - Al

    Leave a comment:


  • Trixter
    replied
    Great sleuthing! I never thought about it before, but it makes perfect sense: Because the mouse is keyboard-based, if the keyboard interrupt is stolen by the game, then the mouse cannot work.

    Simone, did you ever make your rewritten driver available? I'd like to include it in public archives.

    AIG, I've have mostly excellent compatibility with the mouse and its driver when used in period-appropriate environments (ie. anything made for the 6300's lifetime, like 1990 and earlier).

    Leave a comment:


  • Simone2013
    replied
    Originally posted by AlG View Post
    Hello, I've got a query about the compatibility of the keyboard connected mouse for the Olivetti M24/AT&T 6300. I was just wondering what other people experiences with it were.

    Following advice on this forum, I've re-wired an Atarti ST mouse to work with the AT&T6300 keyboard.
    Without a driver, it's working, and providing arrow key input and responding to button presses.
    With the mouse driver (AT&T version 1.0), it's also working, but only on a sub-set of programs. It works (as a full mouse) in the provided configuration program and Microsoft Works. But it doesn't work on lemmings or Monkey Island.
    Hi Alastair,
    From your description about the two game it seems that mouse is not working at all. I had a similar experience re-writing mouse driver for Olivetti Prodest PC1 (similar @ M24 keyboard mouse).
    The PC1 mouse uses keyboard scan codes for emulation mouse key. (I Think M24 uses scan codes also for movement).
    The problem with these two games (Monkey & Lemmings) is that thy hook int09 (keyboard interrupt) WITHOUT calling it back.
    So the original mouse driver cannot catch special scancode and (in my case) didn't operate mouse click. BAD programming indeed. Buy maybe they need all single MHz power from the processor.
    I re-wrote my driver to check hook int09 periodically and take it back if necessary.
    The good news is that they are the only games I found that have this problem!

    Leave a comment:


  • 1ST1
    replied
    I have the original Olivetti mouse, but signal wise it is exactly the same as Atari ST/PC (PC 1-3) or Commodore Amiga (just two wires swapped compared to ATARI) and even some Schneider Euro PC.

    It's running fine with Windows 1.0, 2.0 and GEM when I select there the Olivetti Keyboard mouse driver (it's independent from the dos driver). The DOS driver works fine with Norton Commander and PC-Tools, but until yet I haven't tryed some games using the mouse.

    As basically your mouse adapter works, I don't think you have done something wrong. Don't forget, that mouse driver is very old and that mouse was not very common even on M24/6300, maybe it's incompatible in some way to some newer software.

    Leave a comment:


  • AlG
    started a topic AT&T 6300 (Olivetti M24) mouse software compatibility query

    AT&T 6300 (Olivetti M24) mouse software compatibility query

    Hello, I've got a query about the compatibility of the keyboard connected mouse for the Olivetti M24/AT&T 6300. I was just wondering what other people experiences with it were.

    Following advice on this forum, I've re-wired an Atarti ST mouse to work with the AT&T6300 keyboard.
    Without a driver, it's working, and providing arrow key input and responding to button presses.
    With the mouse driver (AT&T version 1.0), it's also working, but only on a sub-set of programs. It works (as a full mouse) in the provided configuration program and Microsoft Works. But it doesn't work on lemmings or Monkey Island.

    Is this expected behaviour, and if so is there a work-around? Is it just that the mouse has limited support?
    Are there any other drivers that work with the mouse?

    I'm running DOS 3.3 and BIOS version 1.36, if that makes any difference.

    Thanks,

    Alastair
Working...
X