# Assembler und Treiber



## FastProg (21. September 2003)

Hi Leute ich bin es wieder 

Ich interressiere mich jetzt für die maus Steuerung in Assembler an PS/2 und com1 com2, hat jemand bei spiele?

Wo gibt es eine Gute Assembler Seite wie man USB oder Com porte ansteuert?


----------



## chibisuke (21. September 2003)

wie alles funktioniert auch das über IO ports...

ich hab irgendwo noch den maustreiber von meinem letzten projekt rumliegen, hab auch bis vor kurzen an einem betriebssystem beschrieben, hatte nur in letzter zeit extrem wenig zeit...

geschrieben is das teil in C weil es einfach viel bequemer zum arbeiten is..

funktionieren tut das im prinzip indem du den PIC reprogrammierst so das er dir die maus IRQs übergibt die du dann mit einem interupt handler verarbeitest...

der treiber is zwar eigendlich für protected mode, aber sollte auch im realmode mit n paar kleinen modifikationen schön laufen,...


```
#define KEYB_PORT               0x60    /* keyboard port */
#define KEYB_CTRL               0x64    /* keyboard controller port */
#define KCTRL_ENABLE_AUX		0xA8	/* enable aux port (PS/2 mouse) */
#define KCTRL_WRITE_CMD_BYTE    0x60    /* write to command register */
#define KCTRL_WRITE_AUX			0xD4	/* write next byte at port 60 to aux port */
#define KCTRL_IRQ1              0x01	/* flags for KCTRL_WRITE_CMD_BYTE */
#define KCTRL_IRQ12             0x02
#define KCTRL_SYS               0x04
#define KCTRL_OVERRIDE_INHIBIT  0x08
#define KCTRL_DISABLE_KEYB      0x10
#define KCTRL_DISABLE_AUX       0x20
#define KCTRL_TRANSLATE_XT      0x40
#define KEYB_SET_LEDS			0xED	/* commands to keyboard */
#define KEYB_SET_SCANCODE_SET   0xF0
#define KEYB_IDENTIFY           0xF2
#define KEYB_SET_TYPEMATIC      0xF3
#define KEYB_ENABLE             0xF4
#define KEYB_RESET_DISABLE      0xF5
#define KEYB_ALL_TYPM_MAKE_BRK  0xFA
#define KEYB_ACK                "\xFA"	/* default ACK from keyboard following command */
#define AUX_INFORMATION			0xE9	/* commands to aux device (PS/2 mouse) */
#define AUX_ENABLE				0xF4
#define AUX_IDENTIFY			0xF2
#define AUX_RESET				0xFF



#define min(a, b)	((a) < (b) ? (a) : (b))
#define max(a, b)	((a) > (b) ? (a) : (b))

static short interrupts;

typedef struct Ps2Mouse Ps2Mouse;
struct Ps2Mouse {
	int has_wheel;
	int x, y, xmax, xmin, ymax, ymin, wheel;
	int buttons; 
};
extern int mouseclicked;


int first=1;

int in_isr = 0;
void ps2ISR();
int mouseclicked = 0;
Ps2Mouse* ctx;

void kbdWrite(short port, char data)
{
	int timeout;
	char stat;

	for (timeout = 500000L; timeout != 0; timeout--)
	{
		stat = inportb(KEYB_CTRL);

		if ((stat & 0x02) == 0)
			break;
	}

	if (timeout != 0)
		outportb(port, data);
}

char kbdRead()
{
	unsigned long Timeout;
	char Stat, Data;

	for (Timeout = 50000L; Timeout != 0; Timeout--)
	{
		Stat = inportb(KEYB_CTRL);

		if ((Stat & 0x01) != 0)
		{
			Data = inportb(KEYB_PORT);

			if((Stat & 0xC0) == 0)
				return Data;
		}
	}

	return -1;
}

char kbdWriteRead(short port, char data, const char* expect)
{
	int RetVal;

	kbdWrite(port, data);
	for (; *expect; expect++)
	{
		RetVal = kbdRead();
		if ((char) *expect != RetVal)
		{
			return RetVal;
		}
	}

	return 0;
}

static DEVICE_T dev_ps2maus = 
{
	{'P','S','2','M','a','u','s','\0','\0',},
	0,	
	{12,0},
	{0,0},
	{0x60, 0},
};

void InitPS2()
{
	static char s1[] = { 0xF3, 0xC8, 0xF3, 0x64, 0xF3, 0x50, 0 };
    const char* ch;
	char id;

	kbdWrite(KEYB_CTRL, KCTRL_ENABLE_AUX);

	for (ch = s1; *ch; ch++)
	{
		kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
		kbdWriteRead(KEYB_PORT, *ch, KEYB_ACK);
	}

	kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
	kbdWriteRead(KEYB_PORT, AUX_IDENTIFY, KEYB_ACK);
	id = kbdRead();

	ctx->has_wheel = id == 3;
	
	kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
	kbdWriteRead(KEYB_PORT, 0xF3, KEYB_ACK);
	kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
	kbdWriteRead(KEYB_PORT, 0xFF, KEYB_ACK);

	kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
	kbdWriteRead(KEYB_PORT, AUX_INFORMATION, KEYB_ACK);

	kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
	kbdWriteRead(KEYB_PORT, AUX_ENABLE, KEYB_ACK);

	set_vector(ps2ISR, M_VEC+12, D_PRESENT + D_INT + D_DPL3); /* IRQ12 Handler */
	enable_irq(12);

	ctx->xmin = ctx->ymin = 0;
	ctx->xmax = 640;
	ctx->ymax = 480;
	ctx->x = 320;
	ctx->y = 240;

}
char ps2AuxRead()
{
	char	Stat, Data;
	int		tmout = 1000;

	while (tmout)
	{
		Stat = inportb(KEYB_CTRL);
		if ((Stat & 0x01) != 0)
		{
			Data = inportb(KEYB_PORT);

			if((Stat & 0xC0) == 0)
				return Data;
		}
		
		tmout--;
	}

	return (char) -1;
}

void ps2Packet()
{
	int dx=0, dy=0, db0=0, db1=0;
	unsigned char buf[4];

	buf[0] = ps2AuxRead();
	if (buf[0] == (char) -1)
	{
		return;
	}

	buf[1] = ps2AuxRead();
	buf[2] = ps2AuxRead();

	if (ctx->has_wheel)
	{
		buf[3] = ps2AuxRead();
	}
	else
	{
		buf[3] = 0;
	}

	db0	=	(buf[0] & 0x01) << 2;					
	db1	=	(buf[0] & 0x02) >> 1;					
	dx	=	(buf[0] & 0x10) ?  (buf[1] - 256) :  buf[1];
	dy	=	(buf[0] & 0x20) ? -(buf[2] - 256) : -buf[2];



	call_syscall(SC_SETMOUSE,dx,dy);
	call_syscall(SC_MOUSEBUTTON, db0?1:0 + db1?2:0,0);
	db0 = db1;
	db0 = dx;
	db0 = dy;
	db0 = 1;
	
	mouseclicked = db0;

}

void ps2_Isr()
{
	char stat;
	
	stat=inportb(KEYB_CTRL);
	if ((stat & 0x01) != 0)
	{
		ps2Packet();
	}

	outportb(0xA0,0x20);
	outportb(0x20,0x20);
}

void _ps2ISR() {
   asm db 0x60
   asm call _ps2_Isr 
   asm db 0x61
   asm iret
}
```

der code hier hatte mal so ähnlich funktioniert, ob er es noch tut weiß ich net 
ne also im prinzip funktioniert es so das du zuerst den controller dazu bringst die maus zu akzeprieren, ihn dann dazu bringst dir interupts zu schicken, dann brauchst du n interut handler der die daten von der maus liest, und an eine stelle im arbeitsspeichers schreibt wo du die abrufen kannst..


USB und com port werden ziemlich gleich angesprochen, beide über IO register die du mit out und in verabeitest...


----------



## FastProg (22. September 2003)

Für mich sieht das nach einen Teil von C aus! 

Mit welchen C oder C++ Compiler arbeitest du an deinen BetriebsSystem?
Wie kann ich C programmierte programme mit Assembler öffnen?
Denn Kompletten Quellcode von FDos, in dem ich ein paar verbesserungen vor nehmen möchte findest du unter http://www.visual-opal.de

Was muss bei FDos verändert werden damit es C/C++ Programmierte Programme öffnet?


----------



## chibisuke (22. September 2003)

eigendlich wollte ich dir damit nur die funktionsweise zeigen... das kannst du so eigenständig nicht kompilieren da es auf n die librarys meine betriebssystems zurückgreift...

sollte dir darstellen in welcher reihenfolge du was tun musst...

aber solltest du es trotzdem versuchen wollen, das ding läst sich mit turbo C programmieren von borland (kostenload auf der boarland HP zu finden, bei den antiquitäten)
und am besten du kompilierst das zu einer .obj datei und setzt dann einen relocator oder linker darauf an um es direkt in das OS rein zu bauen...


aber wie gesagt eigendlich wollte ich nur zeigen, was du in welcher reihenfolge tun musst um die PS/2 schnittstelle zu initialisieren, den PIC zu reprogrammieren so das er die interupts verarbeitet und einen interupt handler zu installieren, und was dieser tun muss...


also du sagtest dos..
in dem fall musst du diese stelle hier
	set_vector(ps2ISR, M_VEC+12, D_PRESENT + D_INT + D_DPL3); /* IRQ12 Handler */
	enable_irq(12);
 verändern damit du es kompilieren kannst
das set_vector macht im prinzip nix anderes als einen interupt vektor zu erstellen...
im enfeffekt schreibt er die addresse von ps2ISR nach 0000:0030 
und das enable_irq programmiert den PIC so das er IRQ12 verarbeitet


naja und mein betriebssystem is in C geschrieben.. CJGPP kompiler eigendlich aber hier n stück in TC


----------



## FastProg (10. Oktober 2003)

Hi Leute

Ich Frage mich, hat jemand vieleich ein Beispiel Programm was nur in Assembler geschrieben ist, wie man mit der Maus arbeitet?
1.Man soll den Maus Zeiger auf dem Bildschirm sehen 
2.Man sollte auf einen Text oder einen Pixel drücken und es soll etwas passieren

Ach so, es sind keine Maus Treiber Installiert und es sollte im Realmode sein, falls es dort unterschiede gibt!


----------



## chibisuke (11. Oktober 2003)

nun das ist schwer zu realisieren nur in assembler... wenn du dir den code von oben anguckst, dann sollte dir klar sein das das das 10 fache an assembler code sein über alleine nur damit du zugriff auf die maus bekommst...

dann musst du die maus interupt handler so schreiben das sie die maus an der richten stelle im graphikspeicher zeichnen und so weiter wird also nicht ganz einfach....

mit maustreiber is es einfacher...wenn du n maustreiber installiert hast verweise ich auf int 33 außerdem verweise ich hier drauf http://www.ilook.fsnet.co.uk/x86/x86mice.htm


----------



## FastProg (11. Oktober 2003)

kann man das für eigene Programme nutzen?
Besser gesagt kann den jemand in NASM umwandeln?


```
;
; Microsoft kompatibler Maustreiber für den Textmode 0x03
;
; Copyright (c) 1997 by Michael Neumann
;
; Assemblieren und Linken: TASM msmaus.asm   -->   TLINK msmaus.obj
;

.386P
LOCALS @@
COM1INTR  EQU  0Ch
COM1PORT  EQU  03F8h
MIRQ      EQU  04h


CODE SEGMENT USE16
ASSUME CS:CODE,DS:CODE
START:          JMP     BEGIN


; Daten
bytenum  DB 0           ; nummer des bytes, welches gerade übertragen wurde
combytes DB 3 DUP(0)    ; byte buffer, für die 3 empfangenen bytes
mousek   DB 0           ; mousekey - gedrückte maustaste
relx     DW 0
rely     DW 0
mousex   DW 0           ; mousex
mousey   DW 0           ; mousey
oldmx    DW 0           ; oldx
oldmy    DW 0           ; oldy
showm    DB 0           ; showmouse? 0=nicht 1=zeigen
oldoff   DW 0           ; alter Bld-offset
oldmousehandler DD 0    ; alter maushandler
inbyte   DB 0           ; nimmt in al,dx auf
VID_OFFS     DW 0
VID_SEG      DW 0b800h

MouseHandler PROC FAR
		PUSH    AX
		PUSH    BX
		PUSH    DX
		PUSH    DS
		MOV     AX,CS
		MOV     DS,AX


		MOV     DX,COM1PORT
		IN      AL,DX
		MOV     [inbyte],al
		AND     AL,64
		CMP     AL,64
		JNE     NOT64
		MOV     [bytenum],0                

NOT64:          XOR     AX,AX
		MOV     AL,[bytenum]
		MOV     BX,AX
		ADD     BX,OFFSET combytes
		MOV     AL,[inbyte]
		MOV     [BX],al
		INC     [bytenum]
		CMP     [bytenum],3
		JNE     NOT3
		MOV     AL,[combytes]
		AND     AL,3
		SHL     AL,6
		ADD     AL,[combytes+1]
		CBW
		
		CMP     AX,128
		JL      NOT_B128_X
		SUB     AX,256
NOT_B128_X:     ADD     [mousex],AX
		MOV     AL,[combytes]
		AND     AL,12
		SHL     AL,4
		ADD     AL,[combytes+2]
		CBW
		CMP     AX,128
		JL      NOT_B128_Y
		SUB     AX,256
NOT_B128_Y:     ADD     [mousey],AX
		MOV     AL,[combytes]
		AND     AL,32
		OR      AL,AL
		SETNZ   AL
		MOV     [mousek],al
		MOV     AL,[combytes]
		AND     AL,16
		OR      AL,AL
		SETNZ   AL
		SHL     AL,1                         
		ADD     [mousek],AL
		MOV     [bytenum],0






		CMP     [mousex],0
		JGE     @@WEIT1
		MOV     [mousex],0
@@WEIT1:        CMP     [mousex],639
		JLE     @@WEIT2
		MOV     [mousex],639
@@WEIT2:        CMP     [mousey],0
		JGE     @@WEIT3
		MOV     [mousey],0
@@WEIT3:        CMP     [mousey],399
		JLE     @@WEIT4
		MOV     [mousey],399
@@WEIT4:
		CMP     [showm],0
		JE      NOT3
		CALL    REDRAWCURSOR;oldmx,oldmy
		MOV     AX,[mousex]
		MOV     [oldmx],AX
		MOV     AX,[mousey]
		MOV     [oldmy],AX
		CALL    REDRAWCURSOR

NOT3:
		MOV     AL,20H
		OUT     20H,AL
		POP     DS
		POP     DX
		POP     BX
		POP     AX
		IRET
MouseHandler ENDP

 ;0Ch = COM1
 ;0Dh = COM2

InitMouse PROC NEAR
   ; DTR - Data Transfer Ready auf 1
   ; warten, wenn Datenleitungen = 'M'

	   CLI
	   IN       AL,21h
	   JMP      $+2
	   JMP      $+2

	   AND      AL, NOT 2 SHL (MIRQ-1)	; Maus-IRQ aktivieren
	   OUT      21h, AL

	   MOV      dx, COM1PORT+3
	   MOV      AL, 80h                	; Baudrate auf 1200 setzen
	   OUT      DX, AL
	   SUB      DX, 3
	   MOV      AX, 115200 / 1200
	   OUT      DX, AL
	   INC      DX
	   MOV      AL, AH
	   OUT      DX, AL

	   ADD      DX, 2
	   MOV      AL, 2
	   OUT      DX, AL                 

	   SUB      DX, 2
	   MOV      AL, 1
	   OUT      DX, AL                 	; Interrupts aktivieren

	   ADD      DX, 3
	   MOV      AL, 1 OR 2 OR 8        	; DTR, RTS, OUT2
	   OUT      DX, AL

	   SUB      DX, 4
	   IN       AL, DX                 	

	   MOV      AL, 20h                	; Interrupt beenden
	   OUT      20h, AL



   	   RET
InitMouse ENDP

InstallMouse PROC NEAR
   CALL InitMouse
   CLI
   XOR BX,BX
   MOV ES,BX
   MOV BX,(COM1INTR*4)
   MOV EAX,ES:[BX]
   MOV [oldmousehandler],EAX

   MOV AX,CS
   SHL EAX,16
   MOV AX,OFFSET MouseHandler
   MOV ES:[BX],EAX
   STI
   RET
InstallMouse ENDP

ResetMouse PROC NEAR
		CALL    HideMouse
		XOR     AX,AX
		MOV     [bytenum],AL
		MOV     [mousek],AL
		MOV     [mousex],AX
		MOV     [mousey],AX
		MOV     [oldmx],AX
		MOV     [oldmy],AX
		MOV     [showm],AL
		MOV     [oldoff],AX
		RET
ENDP
REDRAWCURSOR PROC NEAR

		MOV     BX,[oldmy]
		SHR     BX,4
		MOV     AX,160
		MUL     BX

		MOV     BX,[oldmx]
		SHR     BX,3
		SHL     BX,1
		ADD     BX,AX
		ADD     BX,[VID_OFFS]
		MOV     DX,ES  ;    XCHG
		MOV     AX,[VID_SEG]
		MOV     ES,AX
		MOV     AX,ES:[BX]
		ROL     AH,4
		MOV     ES:[BX],AX
		MOV     ES,DX
		RET
ENDP

HideMouse PROC NEAR
		CMP     [showm],1
		JNE     @@ENDE
		CALL    REDRAWCURSOR
		MOV     [showm],0
@@ENDE:         RET
ENDP

ShowMouse PROC NEAR
		CMP     [showm],0
		JNE     @@ENDE
		MOV     AX,[mousex]
		MOV     [oldmx],AX
		MOV     AX,[mousey]
		MOV     [oldmy],AX
		CALL    REDRAWCURSOR
		MOV     [showm],1
@@ENDE:         RET

ENDP

DeInstallMouse PROC NEAR   
   XOR BX,BX
   MOV ES,BX
   MOV BX,(COM1INTR*4)
   MOV EAX,[oldmousehandler]
   MOV ES:[BX],EAX
   RET
DeInstallMouse ENDP




BEGIN:
   MOV AX,CS
   MOV DS,AX
   MOV SS,AX
   MOV SP,20000

   CALL InstallMouse
   CALL  ResetMouse
   CALL  ShowMouse
@@again:

   MOV  AH,01
   INT  16H
   JZ   @@check

   CALL HideMouse
   MOV  AH,01
   INT  21h
   CMP  AL,13
   JNE @@ok
   MOV  AH,02
   MOV  DL,10
   INT  21H
   @@ok:
   CALL ShowMouse

   @@check:
   MOV AL,[mousek]
   OR AL,AL
   JZ @@again

   @@ende:
   CALL HideMouse
   CALL DeInstallMouse
   MOV ax,4c00h
   INT 21h

ENDS CODE
END START
```


----------



## chibisuke (11. Oktober 2003)

hmm das is MASM...

am einfachsten wird es sein wenn du das teil mit MASM kompilierst in deinem NASM modul die funktionen aus EXTERN definierst, und das ebenfalls kompilierst und dann alink oder jloc drüber laufen läst je nachdem ob du ne com oder exe haben willst...

ich hab auf die art und weise z.B. n C++ modul und n assembler modul
verbunden..
ein beispiel:

gcc myMasmFile.cpp -c -o myCppFile.o
nasm myAsmFile.cpp -fobj -o myAsmFile.o
alink -oEXE myAsmFile.o myCppFile.o

ähnlich funktioniert auch jloc, nur das jloc das ganze nur relocatet, also keinen startup code erzeugt, das solltest du unbedingt beachten wenn du jloc benutzen willst...

ansonsten wenn du das nicht hin bekommst, vieleicht find ich irgendwann die nächsten tage mal zeit es zu übersetzen


----------



## Thomas Kuse (11. Oktober 2003)

Als ich früher in Turbo-Pascal programmiert habe, brauchte ich natürlich auch ab und an die mouse!

Unter dem Link findest du verschiedene Assembler-Routinen die einfach in ein Pascal-Code eingebettet sind und von dort aufgerufen werden!

http://www.bsdg.org/swag/MOUSE/0048.PAS.html


----------



## chibisuke (11. Oktober 2003)

deine pascal routinen basieren auf dem von mir erwähnten int 33h und wenn du dir mal den link genau anguckst den ich gepostet hab und die codes vergleichst so sind die zweifelsfrei identisch, mit dem unterschied das das eine reine assembler routinen sind das andere aber pascal routinen in inline assembler sind wo der syntax nicht unbedingt passt ;-)

faszit: in beiden fällen ist ein maustreiber erforderlich, die forderung war aber ohne maustreiber entsprechend...


----------



## FastProg (12. Oktober 2003)

also heißt das dass ich erst einen Treiber Programmieren muss 
Leider kenne ich mich darin über haupt nicht aus!
Kannst du vieleich ein Beispiel Treiber zeigen

Danke


----------



## chibisuke (12. Oktober 2003)

der assembler code 3 oder 4 post weiter oben ist einer ;-)

ansonsten hab ich dos treiber für die maus hier zu duzenden rumliegen, kann dir gerne mal einen schicken...

du hast im prinzip 2 möglichkeiten... entweder du benutzt n fertigen treiber, den du entweder manuell oder von deinem progy laden läst.. einfach als exe mit auf die disk packen... oder du benutzt einen internen treiber, was aber einersets den nachteil hatt das der alte treiber gekickt werden muss vorher, anderersets is es ne menge programmieraufwand...

wie gesagt ohne maustreiber funktionierts nicht, es du nun den treiber extra (evt. von einem fremdhersteller) oder ob du nun den treiber als modul intern hast kommt aufs gleiche raus...aber ohne treiber geht gar nix..


----------



## FastProg (12. Oktober 2003)

Ich bin mir nicht sicher aber ich glaube das ich unter FDos keine EXE Dateien nutzen kann, ich weiß auch nicht ob es für MS-DOS programmierte programme geeignet ist!

Wie kann man so ein Treiber unter FDos nutzen?
Kann man keinen eigenen Treiber programmieren?
Kann man einen Treiber für FDOS tauglich machen?

Würde mich über jede Antwort freuen dir mir sagen konnte, wie man FDos Maus fähig macht!

Danke


----------



## chibisuke (12. Oktober 2003)

maustreiber sind meist com oder sys dateien... und meines wissens kannst du auch in fdos exe dateien ausführen 

Ich hab mir erlaubt den treiber den ich hauptsächlich benutze auf dos ebene mal als anhang anzuhängen...


----------



## FastProg (12. Oktober 2003)

Wie kann man unter FDos exe Dateien ausführen?

FDos ist ein selbst programmiertest OS 
FDOS >>> http://www.visual-opal.de  <<< Open Source

werde es mal mit den maus Treiber probieren


----------



## chibisuke (12. Oktober 2003)

achso muss ich mir angucken, sah für mich so aus als ob du FreeDOS meinst


----------



## FastProg (12. Oktober 2003)

Nein, FreeDos ist schon viel weiter als FDOS (Floppy Disk Operation system)  

Danke das du dir das mal anschaust


----------



## assembler (7. Oktober 2004)

*ah 08h, int 13h*

Ich weiss das man mit 

mov ah,08h
int 13h

testen kann welches diskettenlaufwerk vorhanden is. Die lösung steht dann in bl. Aber bei mir funktioniert das nicht. Kann mir vielleicht jemand helfen? Muss man etwas speziälles dazuschreiben?  

Danke! 

PS: Bitte nur schreiben wenn man es weiss!


----------



## cscorp18 (2. August 2005)

Unter welchem Windows führst du das Programm aus?

DENN:
Unter Windows NT,2000 und XP funktionieren die Int 13 nämlich nicht!
Das geht nur unter Windows 9x und ME.

*gg* und unter DOS natürlich auch..


----------

