Discussion:
(DPMI - / DOS - ) API
(zu alt für eine Antwort)
Robert Hartmann
2010-07-20 13:15:29 UTC
Permalink
Hallo zusammen,

kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
unter C / C++ geben?

Danke.

Gruß Robert
Dirk Wolfgang Glomp
2010-07-20 17:50:58 UTC
Permalink
Post by Robert Hartmann
Hallo zusammen,
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
Ralf Browns Interrupt List(RBIL)->inter61c.zip->INTERRUP.N
http://www.pobox.com/~ralf
http://www.pobox.com/~ralf/files.html
ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/
Post by Robert Hartmann
unter C / C++ geben?
Upps mit C/ C++ kenne ich mich nicht aus und DPMI benutze ich selber auch
nicht. Ich verwalte den Speicher(bis 4GB) lieber selber und benutze dafür
den 16 Bit-Unrealmode.

Dirk
Robert Hartmann
2010-07-30 06:56:38 UTC
Permalink
Hallo Dirk,
Post by Dirk Wolfgang Glomp
Post by Robert Hartmann
Hallo zusammen,
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
Ralf Browns Interrupt List(RBIL)->inter61c.zip->INTERRUP.N
http://www.pobox.com/~ralf
http://www.pobox.com/~ralf/files.html
ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/
Danke für die URIs.

Gruß Robert
Dirk Wolfgang Glomp
2010-07-30 07:57:29 UTC
Permalink
Post by Robert Hartmann
Hallo Dirk,
Post by Dirk Wolfgang Glomp
Post by Robert Hartmann
Hallo zusammen,
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
Ralf Browns Interrupt List(RBIL)->inter61c.zip->INTERRUP.N
http://www.pobox.com/~ralf
http://www.pobox.com/~ralf/files.html
ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/
Für DOS-Programmiere ist RBIL unverzichtbar und selbst nach Jahren
finde ich dort immer wieder etwas Neues. Danke für dein Feedback.

Dirk
Stefan Reuther
2010-07-20 17:16:12 UTC
Permalink
Post by Robert Hartmann
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
unter C / C++ geben?
Was denn konkret? Die Interrupts befinden sich in Ralf's Liste. Da macht
man dann eben kleine Assemblerfunktiönchen draus oder hat gleich einen
Compiler, der einen direkt Interrupts aufrufen lässt, und das war's dann.


Stefan
Robert Hartmann
2010-07-30 08:02:03 UTC
Permalink
Hallo Stefan,
Post by Stefan Reuther
Post by Robert Hartmann
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
unter C / C++ geben?
Was denn konkret?
Ich versuche mir eine sehr beschränkte con_io.h / con_io.c
zu basteln, die direkt bei Win32 auf die Win32-API und bei DOS
auf die DOS-( ggf DPMI-API) zugreifen.

Grund: Herausfinden ob ich das hin bekomme und dabei etwas lernen.
Ein wenig hab ich auch bekommen (siehe unten) :-)

Nun stehe ich vor einem Verständnisproblem:

Ich würde gerne die aktuelle Cursor Position
und die maximal zulässige Position (d.h. die Anzahl der
Zeilen und Spalten, die ggf über config.sys mit MODE
verändert worden ist) herausfinden.

Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.

Auch würde ich gerne herausfinden, ob irgendeine Taste gedrückt wurde:

http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2ab4.htm

Aber wie komme ich an ZF dran?
Der scheint nicht in der Reg-Struktur (aus dos.h meines Compilers)
dabei zu sein.

Gruß Robert

/* =============C-code========================= */

#include<stddef.h>
#include<stdlib.h>
#include<stdio.h>

#ifdef __MSDOS__
#include <dos.h>
#elif __WIN32__
#include <windows.h>
#elif __unix__
#if !defined(__MSDOS__) && !defined(__WIN32__)
/* TODO: unix/linux header laden!*/
#endif /* nicht (MSDOS oder Win32) aber unix/linux */
#endif


void clrscr() {
#if __MSDOS__
union REGS reg;

reg.x.ax=0x0600;
reg.h.bh=7;
reg.x.cx=0;
reg.x.dx=0x184F;
int86(0x10,&reg,&reg);

reg.h.ah=0x2;
reg.x.dx=0;
reg.h.bh=0;
int86(0x10,&reg,&reg);

#elif __WIN32__
COORD coordScreen = { 0, 0 }; /* upper left corner */
DWORD cCharsWritten;
DWORD dwConSize;
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;

GetConsoleScreenBufferInfo(hCon, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;


FillConsoleOutputCharacter(hCon, TEXT(' '), dwConSize, coordScreen,
&cCharsWritten);

GetConsoleScreenBufferInfo(hCon, &csbi);
FillConsoleOutputAttribute(hCon, csbi.wAttributes, dwConSize,
coordScreen, &cCharsWritten);


SetConsoleCursorPosition(hCon, coordScreen);

#elif defined(__unix__) && !defined(__MSDOS__) && !defined(__WIN32__)
/*
ANSI-Controll-Sequence:
http://ascii-table.com/ansi-escape-sequences.php
http://www.i8086.de/dos-befehle/ansi-sys.html

http://linux.die.net/man/4/console_codes
ESC [ 2 J: erase whole display.
*/
printf("\x1B[2J");

#else
perror("clrscr() – not implemented!!\n");
exit(1);
#endif
}

void gotoXY(int x, int y) {
#if __MSDOS__
/*
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o1c.htm */
union REGS regs;

regs.h.ah = 2; /* cursor position */
regs.h.dh = y;
regs.h.dl = x;
regs.h.bh = 0; /* vídeo page #0 */
int86(0x10, &regs, &regs);

#elif __WIN32__
COORD CurPos;
CurPos.X = x;
CurPos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), CurPos);

#elif defined(__unix__) && !defined(__MSDOS__) && !defined(__WIN32__)
/*
ANSI-Controll-Sequence:
http://ascii-table.com/ansi-escape-sequences.php

http://linux.die.net/man/4/console_codes
ESC [ G value: Move cursor to indicated column in current row.
ESC [ d value: Move cursor to the indicated row, current column.
*/
printf("\033[%ud\033[%uG", y, x);
#else
perror("gotoxy(unsigned int x, unsigned int y) – not implemented!!\n");
exit(1);
#endif

/* =============C-code========================= */
Dirk Wolfgang Glomp
2010-07-30 08:27:05 UTC
Permalink
Post by Robert Hartmann
Ich würde gerne die aktuelle Cursor Position
und die maximal zulässige Position (d.h. die Anzahl der
Zeilen und Spalten, die ggf über config.sys mit MODE
verändert worden ist) herausfinden.
RBIL->inter61a.zip->INTERRUP.A
--------V-101130-----------------------------
INT 10 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA)
AX = 1130h
BH = pointer specifier
00h INT 1Fh pointer
01h INT 43h pointer
02h ROM 8x14 character font pointer
03h ROM 8x8 double dot font pointer
04h ROM 8x8 double dot font (high 128 characters)
05h ROM alpha alternate (9 by 14) pointer (EGA,VGA)
06h ROM 8x16 font (MCGA, VGA)
07h ROM alternate 9x16 font (VGA only) (see #00021)
11h (UltraVision v2+) 8x20 font (VGA) or 8x19 font (autosync EGA)
12h (UltraVision v2+) 8x10 font (VGA) or 8x11 font (autosync EGA)
Return: ES:BP = specified pointer
CX = bytes/character of on-screen font (not the requested font!)
DL = highest character row on screen
Note: for UltraVision v2+, the 9xN alternate fonts follow the corresponding
8xN font at ES:BP+256N
BUG: the IBM EGA and some other EGA cards return in DL the number of rows
on
screen rather than the highest row number (which is one less).
SeeAlso: AX=1100h,AX=1103h,AX=1120h,INT 1F"SYSTEM DATA",INT 43"VIDEO DATA"

Format of alternate font table [array]:
Offset Size Description (Table 00021)
00h BYTE character to be replaced (00h = end of table)
01h N BYTEs graphics data for character, one byte per scan line
------------
Post by Robert Hartmann
Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
(Habe ich mir noch nicht angeschaut.)
Post by Robert Hartmann
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.
RBIL->inter61a.zip->INTERRUP.A
--------V-1003-------------------------------
INT 10 - VIDEO - GET CURSOR POSITION AND SIZE
AH = 03h
BH = page number
0-3 in modes 2&3
0-7 in modes 0&1
0 in graphics modes
Return: AX = 0000h (Phoenix BIOS)
CH = start scan line
CL = end scan line
DH = row (00h is top)
DL = column (00h is left)
Notes: a separate cursor is maintained for each of up to 8 display pages
many ROM BIOSes incorrectly return the default size for a color display
(start 06h, end 07h) when a monochrome display is attached
With PhysTechSoft's PTS ROM-DOS the BH value is ignored on entry.
SeeAlso: AH=01h,AH=02h,AH=12h/BL=34h,MEM 0040h:0050h,MEM 0040h:0060h
--------
Post by Robert Hartmann
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2ab4.htm
(Habe ich mir auch noch nicht angeschaut.)
Post by Robert Hartmann
Aber wie komme ich an ZF dran?
ZF = Zeroflag?
jz/je Sprung-Adresse
jnz/jne Sprung-Adresse

Dirk
Robert Hartmann
2010-08-02 09:05:07 UTC
Permalink
Hallo Dirk,
Post by Dirk Wolfgang Glomp
Post by Robert Hartmann
Ich würde gerne die aktuelle Cursor Position
und die maximal zulässige Position (d.h. die Anzahl der
Zeilen und Spalten, die ggf über config.sys mit MODE
verändert worden ist) herausfinden.
RBIL->inter61a.zip->INTERRUP.A
--------V-101130-----------------------------
INT 10 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA)
[...]
Post by Dirk Wolfgang Glomp
Post by Robert Hartmann
Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
(Habe ich mir noch nicht angeschaut.)
Post by Robert Hartmann
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.
RBIL->inter61a.zip->INTERRUP.A
--------V-1003-------------------------------
INT 10 - VIDEO - GET CURSOR POSITION AND SIZE
[...]
Post by Dirk Wolfgang Glomp
Post by Robert Hartmann
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2ab4.htm
(Habe ich mir auch noch nicht angeschaut.)
Post by Robert Hartmann
Aber wie komme ich an ZF dran?
ZF = Zeroflag?
jz/je Sprung-Adresse
jnz/jne Sprung-Adresse
Danke für Deine Hilfe.

Gruß Robert
Dirk Wolfgang Glomp
2010-08-02 21:54:40 UTC
Permalink
Post by Robert Hartmann
Danke für Deine Hilfe.
Gruß Robert
Gerne geschehen.

Dirk
Stefan Reuther
2010-07-30 17:35:36 UTC
Permalink
Post by Robert Hartmann
Ich würde gerne die aktuelle Cursor Position
und die maximal zulässige Position (d.h. die Anzahl der
Zeilen und Spalten, die ggf über config.sys mit MODE
verändert worden ist) herausfinden.
Für die maximale Größe komme ich spontan auf das hier:
int main()
{
union REGS r;
int rows, cols;

r.x.ax = 0x0F00;
int86(0x10, &r, &r);
cols = r.h.ah;

r.x.ax = 0x1130;
r.x.bx = 0x0000;
int86(0x10, &r, &r);
rows = r.h.dl + 1;
printf("%d x %d\n", cols, rows);

return 0;
}
Alternativ findet sich die Spaltenzahl im 16-bit-Wort an 0x0040:0x004A,
die Zeilenzahl im Byte an 0x0040:0x0084.
Post by Robert Hartmann
Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10, &r, &r);
printf("cursor an %d,%d\n", r.h.dh, r.h.dl);

Wo ist jetzt das Problem? Die Scanlines geben nur die Größe des Cursors an.
Post by Robert Hartmann
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2ab4.htm
Aber wie komme ich an ZF dran?
Der scheint nicht in der Reg-Struktur (aus dos.h meines Compilers)
dabei zu sein.
Das ist ein Bit im Flags-Register.

while (1) {
r.x.ax = 0x0100;
int86(0x16, &r, &r);
if ((r.x.flags & 0x40) == 0)
break;
}

Dass ZF den Wert 0x40 hat, findet man in der Interrupt-Liste in OPCODES.LST.


Stefan
Robert Hartmann
2010-08-02 09:00:14 UTC
Permalink
Hallo Stefan,
Post by Stefan Reuther
Post by Robert Hartmann
Ich würde gerne die aktuelle Cursor Position
und die maximal zulässige Position (d.h. die Anzahl der
Zeilen und Spalten, die ggf über config.sys mit MODE
verändert worden ist) herausfinden.
int main()
{
union REGS r;
int rows, cols;
r.x.ax = 0x0F00;
int86(0x10,&r,&r);
cols = r.h.ah;
r.x.ax = 0x1130;
r.x.bx = 0x0000;
int86(0x10,&r,&r);
rows = r.h.dl + 1;
printf("%d x %d\n", cols, rows);
return 0;
}
Danke dir. Wieso steht bei der Bestimmung der rows
noch die Addition einer 1 ?
Post by Stefan Reuther
Alternativ findet sich die Spaltenzahl im 16-bit-Wort an 0x0040:0x004A,
die Zeilenzahl im Byte an 0x0040:0x0084.
Post by Robert Hartmann
Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
printf("cursor an %d,%d\n", r.h.dh, r.h.dl);
Wo ist jetzt das Problem? Die Scanlines geben nur die Größe des Cursors an.
Der Begriff "Scanline" muss wohl mein Problem gewesen sein.
Irgendwie hab ich das als Größenangabe der abscannbaren (Eingabe-) Linie
(=Zeile) interpretiert.
Post by Stefan Reuther
Post by Robert Hartmann
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2ab4.htm
Aber wie komme ich an ZF dran?
Der scheint nicht in der Reg-Struktur (aus dos.h meines Compilers)
dabei zu sein.
Das ist ein Bit im Flags-Register.
while (1) {
r.x.ax = 0x0100;
int86(0x16,&r,&r);
if ((r.x.flags& 0x40) == 0)
break;
}
Dass ZF den Wert 0x40 hat, findet man in der Interrupt-Liste in OPCODES.LST.
Du meinst sicher OPCODES.LST aus
http://www.cs.cmu.edu/~ralf/interrupt-list/inter61d.zip , oder ?
Dort habe ich die Information über ZF = 0x40 (also Bit 2^6) nicht
finden können.

Beim Abschnitt
[80x186 ,EA,EB,EC,XL] [8086/88 and all clones]
steht ZF auf Bit 2^8


Allerdings konnte ich die 0x40 für ZF hier wiederfinden:

http://www.compeng.dit.ie/staff/tscarff/8086_registers/8086_registers.html

http://home.comcast.net/~fbui/intel.html#flags

http://en.wikipedia.org/wiki/FLAGS_register_%28computing%29


Viele Grüße und Danke,
Robert
Stefan Reuther
2010-08-02 17:05:46 UTC
Permalink
Post by Robert Hartmann
Post by Stefan Reuther
r.x.ax = 0x1130;
r.x.bx = 0x0000;
int86(0x10,&r,&r);
rows = r.h.dl + 1;
printf("%d x %d\n", cols, rows);
Danke dir. Wieso steht bei der Bestimmung der rows
noch die Addition einer 1 ?
"is so". Das sind halt die Variablen, die der XT-BIOS-Schreiberling anno
1978 brauchte, irgendwie zugänglich gemacht, und kein sauber designtes
Interface.
Post by Robert Hartmann
Post by Stefan Reuther
Post by Robert Hartmann
Wenn ich
http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte6o34.htm
richtig verstehe,
dann soll das mit INT 10,3 gehen.
Aber die Rückgabe Werte verstehe ich noch nicht so ganz.
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
printf("cursor an %d,%d\n", r.h.dh, r.h.dl);
Wo ist jetzt das Problem? Die Scanlines geben nur die Größe des Cursors an.
Der Begriff "Scanline" muss wohl mein Problem gewesen sein.
Irgendwie hab ich das als Größenangabe der abscannbaren (Eingabe-) Linie
(=Zeile) interpretiert.
Bei der Programmierung unter DOS hilft es, zu wissen, wie die Hardware
funktioniert: Im Textmodus malt der Elektronenstrahl eben 400 mal je 720
Pixel, und das sind dann 400 Scanlines. Von den 400 Scanlines entfallen
16 auf jede Textzeile, und man kann nun angeben, auf welchen davon der
Cursor dargestellt wird. Man kann aber auch die Anzahl Scanlines pro
Textzeile ändern und kommt damit z.B. mit einem 8 Pixel hohen Font auf
50 Zeilen, mit einem 14 Pixel hohen Font auf 28 Zeilen. Beide Fonts hat
eine VGA noch im ROM, der Kompatibilität zu CGA und EGA wegen.
Post by Robert Hartmann
Post by Stefan Reuther
Post by Robert Hartmann
Aber wie komme ich an ZF dran?
Der scheint nicht in der Reg-Struktur (aus dos.h meines Compilers)
dabei zu sein.
Das ist ein Bit im Flags-Register.
while (1) {
r.x.ax = 0x0100;
int86(0x16,&r,&r);
if ((r.x.flags& 0x40) == 0)
break;
}
Dass ZF den Wert 0x40 hat, findet man in der Interrupt-Liste in OPCODES.LST.
Du meinst sicher OPCODES.LST aus
http://www.cs.cmu.edu/~ralf/interrupt-list/inter61d.zip , oder ?
Dort habe ich die Information über ZF = 0x40 (also Bit 2^6) nicht
finden können.
Beim Abschnitt
[80x186 ,EA,EB,EC,XL] [8086/88 and all clones]
steht ZF auf Bit 2^8
Dann hast du nicht richtig gezählt :-)


[80x186 ,EA,EB,EC,XL] [8086/88 and all clones]
1 1 1 1 1 1
5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-------------------------------
O D I T S Z A P C
1 1 1 1 F F F F F F 0 F 0 F 1 F
-------------------------------
^
^ 2^6

(Natürlich wollen sowohl dieses Posting, als auch die Interruptliste,
mit einer Festbreitenschrift betrachtet werden.)


Stefan
Robert Hartmann
2010-08-03 09:35:03 UTC
Permalink
Hallo Stefan,
[...]
Post by Stefan Reuther
Post by Robert Hartmann
Du meinst sicher OPCODES.LST aus
http://www.cs.cmu.edu/~ralf/interrupt-list/inter61d.zip , oder ?
Dort habe ich die Information über ZF = 0x40 (also Bit 2^6) nicht
finden können.
Beim Abschnitt
[80x186 ,EA,EB,EC,XL] [8086/88 and all clones]
steht ZF auf Bit 2^8
Dann hast du nicht richtig gezählt :-)
[80x186 ,EA,EB,EC,XL] [8086/88 and all clones]
1 1 1 1 1 1
5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-------------------------------
O D I T S Z A P C
1 1 1 1 F F F F F F 0 F 0 F 1 F
-------------------------------
^
^ 2^6
(Natürlich wollen sowohl dieses Posting, als auch die Interruptliste,
mit einer Festbreitenschrift betrachtet werden.)
*Arg* Oh je, und ich dachte der Editor, der die LST Datei geöffnet
hatte, hätte Festbreitenschrift eingestellt gehabt, so wie meine
Thunderbirdinstallation. Hatte der aber nicht ... :-/

Gruß Robert
Markus Humm
2010-07-20 20:28:09 UTC
Permalink
Post by Robert Hartmann
Hallo zusammen,
kann mir jemand einen Hinweis zum Auffinden
von Informationen zur Benutzung der (DPMI - / DOS - ) API
unter C / C++ geben?
Danke.
Gruß Robert
Hallo,

je nach verwendetem C/C++ COmpiler sollte es dafür doch einen DOS
extender geben.
z.B. der Borland COmpiler hatte so etwas.

Gruß

Markus
Robert Hartmann
2010-08-02 14:29:26 UTC
Permalink
Hallo zusammen,



Von Ralfs Liste:
KEYBOARD - GET KEYBOARD FUNCTIONALITY [INT16/AH=09h]

http://www.ctyme.com/intr/rb-1769.htm

This function is only available if bit 6 of the second feature byte
returned by INT 15/AH=C0h is set (see #00509)


Also habe ich bei INT 15/AH=C0h

http://www.ctyme.com/intr/rb-1594.htm

nachgesehen:

SYSTEM - GET CONFIGURATION (XT >1986/1/10,AT mdl 3x9,CONV,XT286,PS)
AH = C0h
Return:
CF set if BIOS doesn't support call
CF clear on success
ES:BX -> ROM table
AH = status
[...]

Format of ROM configuration table:
Offset Size Description (Table 0426)
00h WORD number of bytes following
02h BYTE model (see #0432)
03h BYTE submodel (see #0432)
04h BYTE BIOS revision:
0 for first release, 1 for 2nd, etc.
05h BYTE feature byte 1 (see #0427)
06h BYTE feature byte 2 (see #0428) <==== Darauf will ich zugreifen.
[...]


Bitfields for feature byte 2:

Bit(s) Description (Table 00511)
7 32-bit DMA supported
6 INT 16/AH=09h (keyboard functionality) supported (see #00585)
[...]


Nun versuche ich, den Wert des Bit 6 im 2. Feature-Byte zu bestimmen,
komme aber irgendwie weiter, da ich fast sicher bin, dass ich nicht
richtig auf ES:BX zugreife, sondern irgend etwas anderes lese.

void testKey{
int keyb_func_supp = 0;
union REGS regs;
struct SREGS sregs;

regs.x.ax = 0xC000;
int86(0x15, &regs, &regs);

if ((regs.h.ah == 0) && (!(r.x.flags & 0x01))){
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich */

/* Zugriff auf ES:BX ... nur wie? */

segread( &sregs );

/* und jetzt, wie weiter? */
/*Das ist sicher nicht richtig so, oder? */

keyb_func_supp = sregs.es & 0x4000 ; /* <<== ? */

if (keyb_func_supp){
regs.x.ax = 0x0900;
int86(0x16, &regs, &regs);
if(regs.h.al & 0x20) { /* enhanced keyboard support */

/* .... */

}
}

}

}

Danke,

Gruß Robert
Stefan Reuther
2010-08-02 17:08:50 UTC
Permalink
Post by Robert Hartmann
if ((regs.h.ah == 0) && (!(r.x.flags & 0x01))){
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich */
/* Zugriff auf ES:BX ... nur wie? */
Du musst halt aus ES und BX einen FAR-Zeiger basteln und kannst den dann
nach Belieben dereferenzieren.

Ungetestet:
unsigned char far* p = MK_FP(sregs.es, regs.x.bx);
unsigned char feature_byte = p[6];
if (feature_byte & (1 << 6)) { ... }


Stefan
Robert Hartmann
2010-08-03 09:48:46 UTC
Permalink
Hallo Stefan,
Post by Stefan Reuther
if ((regs.h.ah == 0)&& (!(r.x.flags& 0x01))){
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich */
/* Zugriff auf ES:BX ... nur wie? */
Du musst halt aus ES und BX einen FAR-Zeiger basteln und kannst den dann
nach Belieben dereferenzieren.
unsigned char far* p = MK_FP(sregs.es, regs.x.bx);
unsigned char feature_byte = p[6];
if (feature_byte& (1<< 6)) { ... }
Da ich ja auf das 6 Bit im 2ten Feature Byte zugreifen will
<Zitat>
This function is only available if bit 6 of the second feature byte
returned by INT 15/AH=C0h is set (see #00509)
</Zitat>

müsste es nach dir (und verifiziert mit [1] )

so gehen:

unsigned char far* p = (unsigned char far *) MK_FP(sregs.es, regs.x.bx);
unsigned char feature_byte = p[2]; /* zweites Featurebyte*/
if (feature_byte & (1<<6)) { /* sechstes Bit*/
...
}


Gruß und Danke,
Robert


[1] http://gd.tuwien.ac.at/languages/c/programming-bbrown/advcw1.htm
Stefan Reuther
2010-08-03 18:02:24 UTC
Permalink
Post by Robert Hartmann
Post by Stefan Reuther
unsigned char far* p = MK_FP(sregs.es, regs.x.bx);
unsigned char feature_byte = p[6];
if (feature_byte& (1<< 6)) { ... }
Da ich ja auf das 6 Bit im 2ten Feature Byte zugreifen will
<Zitat>
This function is only available if bit 6 of the second feature byte
returned by INT 15/AH=C0h is set (see #00509)
</Zitat>
Dass zweite Feature-Byte hat aber laut deinem Zitat Offset 6. Daher 'p[6]'.

Alternativ kannst du den Zeiger natürlich gleich mit 'regs.x.bx + 6'
bauen, dann wäre direkt '*p' das zweite Feature-Byte.


Stefan
Robert Hartmann
2010-08-04 10:17:49 UTC
Permalink
Hallo Stefan,
[...]
Post by Stefan Reuther
Dass zweite Feature-Byte hat aber laut deinem Zitat Offset 6. Daher 'p[6]'.
Du hast wieder Recht. Ein zweites Feature-Byte muss nicht bei Offset 2
liegen.

Vielleicht sollte ich beim Lesen nicht soviel denken/interpretieren :-)

Nun versuche ich das, was ich gebastelt habe, mit djgpp zu kompilieren.
Aber es scheitert unter Anderem am segread, da es nicht existiert.

Also habe ich verschiedene Stellen (s.u.) durchgelesen, insbesondere die
DJGPP-FAQ.

Dort bin ich dann auf Folgendes gestoßen:

<Zitat>
The function segread used by some real-mode compilers does not exist in
DJGPP. It is used in real-mode code to store the values of the CS, DS,
SS, and ES registers into a struct SREGS variable, when some service
that needs one of these registers is called from code written for small
and tiny memory models.

DJGPP has the functions _my_cs, _my_ds, and _my_ss for that purpose (ES
and DS always hold the same selector in code produced by GCC from a C or
C++ source, so you don't need a fourth function).

However, these will not be useful if the original real-mode code used
the segment registers to invoke DOS/BIOS services. For these cases, you
will need to rewrite the code so that it copies the data to/from the
transfer buffer and passes the transfer buffer address via __dpmi_int,
as described above.
</Zitat> [1]

Verstehe ich das Zitat richtig?

Nach Aufruf des INT15/AH=C0h mit der Funktion int86(...,...,...),
welches Ergebniswerte bei ES:BX nach Ralfs Interupt Liste [2] ablegt,
kann man in DJGPP eben nicht mit segread(...) an die Werte kommen (weil
DJGPP ein 32bit Compiler ist).

Auch den FAR Pointer kann man nicht mit MK_FP(sregs.es, regs.x.bx)
generieren, da weder FAR noch diese Funktion definiert ist.

Also kann man mit DJGPP den folgenden Code nicht compilieren:

/* ************************ */
#include<dos.h>
void test(){
union REGS regs;
struct SREGS sregs;
regs.x.ax = 0xC000;
int86(0x15, &regs, &regs);

if ((regs.h.ah == 0) && (!(r.x.flags & 0x01))){
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich */

/* Zugriff auf ES:BX*/

segread( &sregs );
unsigned char far* p = (unsigned char far *) MK_FP(sregs.es, regs.x.bx);
unsigned char feature_byte = p[6]; /* zweites Featurebyte ist bei
Offset 6*/
if (feature_byte & (1<<6)) { /* sechstes Bit*/

/* Code hier */

}
}
}

/* ************************ */

Stattdessen muss man segread und MK_FP ersetzen und weitere
Header-Dateien einbinden.

Hier nun mein Versuch der Portierung für DJGPP ( ob ich das richtig
gemacht habe? ).

/* ************************ */

#include<dos.h> /*int83(...,...,...) - union REGS - struct SREGS */
#include<sys/segments.h> /*_my_ds() */
#include<sys/farptr.h> /*_farpeekb(...,...)*/
#include<go32.h> /*_dos_ds */

void test(){
union REGS regs;
struct SREGS sregs;
regs.x.ax = 0xC000;
int86(0x15, &regs, &regs);

if ((regs.h.ah == 0) && (!(r.x.flags & 0x01))){
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich */

/* Zugriff auf ES:BX mit DJGPP */

/* Ersatz für:

segread( &sregs );
unsigned char far* p = (unsigned char far *) MK_FP(sregs.es,
regs.x.bx);
unsigned char feature_byte = p[6]; /* zweites Featurebyte ist bei
Offset 6*/
*/

/*
DJGPP has the functions _my_cs, _my_ds, and _my_ss
for that purpose (ES and DS always hold the same selector
in code produced by GCC from a C or C++ source,
so you don't need a fourth function).
*/

unsigned short ES = _my_ds();
unsigned char feature_byte = _farpeekb( _dos_ds, ES*16 + regs.x.bx + 6 );

if (feature_byte & (1<<6)) { /* sechstes Bit ist gesetzt*/


/* Code hier */

}
}
}

/* ************************ */

Wäre wieder toll, wenn ich Rückmeldungen bekomme.
Danke.

Beste Grüße,
Robert


URIs:
[1] http://www.delorie.com/djgpp/v2faq/faq18_2.html
[2] http://www.ctyme.com/intr/rb-1594.htm
[3] http://www.delorie.com/djgpp/v2faq/faq17_7.html
[4] http://www.delorie.com/djgpp/v2faq/faq18_4.html
[5] http://www.delorie.com/djgpp/doc/ug/dpmi/farptr-intro.html
[6] http://www.inversereality.org/tutorials/djgpp%20programming/pmode.html
Hans-Bernhard Bröker
2010-08-04 21:14:46 UTC
Permalink
Post by Robert Hartmann
Nun versuche ich das, was ich gebastelt habe, mit djgpp zu kompilieren.
Aber es scheitert unter Anderem am segread, da es nicht existiert.
Nein, es scheitert daran, dass dir nicht klar ist, warum es gar keinen
Sinn hat, in einem DJGPP-Programm sowas wie segread benutzen zu wollen.
Post by Robert Hartmann
Verstehe ich das Zitat richtig?
Nein.
Post by Robert Hartmann
Nach Aufruf des INT15/AH=C0h mit der Funktion int86(...,...,...),
... die funktioniert aber in DJGPP nun mal nicht so, wie es dein Code
erwartet.
Post by Robert Hartmann
welches Ergebniswerte bei ES:BX nach Ralfs Interupt Liste [2] ablegt,
Und das ist genau das, was DJGPP bei int86() ausdrücklich nicht
unterstützt (--> info libc alpha int86). Da müsstest du einiges an
Zusatzarbeit auf Basis von __dpmi_simulate_real_mode_interrupt() leisten.
Post by Robert Hartmann
Auch den FAR Pointer kann man nicht mit MK_FP(sregs.es, regs.x.bx)
generieren, da weder FAR noch diese Funktion definiert ist.
... was auch überhaupt keinen Sinn hätte, weil DJGPP nun mal kein
segmentiertes Speichermodell mit dem Potential, far pointer zu
benötigen, nutzt, sondern den 32-bittigen flat mode.
Robert Hartmann
2010-08-10 13:12:20 UTC
Permalink
Post by Hans-Bernhard Bröker
Post by Robert Hartmann
Nun versuche ich das, was ich gebastelt habe, mit djgpp zu kompilieren.
Aber es scheitert unter Anderem am segread, da es nicht existiert.
Nein, es scheitert daran, dass dir nicht klar ist, warum es gar keinen
Sinn hat, in einem DJGPP-Programm sowas wie segread benutzen zu wollen.
Post by Robert Hartmann
Verstehe ich das Zitat richtig?
Nein.
Post by Robert Hartmann
Nach Aufruf des INT15/AH=C0h mit der Funktion int86(...,...,...),
... die funktioniert aber in DJGPP nun mal nicht so, wie es dein Code
erwartet.
mhm ... vielleicht hast du Recht; jedoch funktioniert mein kleines
Test-Programm, wie ich dachte. :-)

Ob ich irgendwelche ungewollten Nebeneffekte drin habe, die sich erst
bei große Programmen zeigen, kann ich noch nicht ausschließen.
Post by Hans-Bernhard Bröker
Post by Robert Hartmann
welches Ergebniswerte bei ES:BX nach Ralfs Interupt Liste [2] ablegt,
Und das ist genau das, was DJGPP bei int86() ausdrücklich nicht
unterstützt (--> info libc alpha int86). Da müsstest du einiges an
Zusatzarbeit auf Basis von __dpmi_simulate_real_mode_interrupt() leisten.
Post by Robert Hartmann
Auch den FAR Pointer kann man nicht mit MK_FP(sregs.es, regs.x.bx)
generieren, da weder FAR noch diese Funktion definiert ist.
... was auch überhaupt keinen Sinn hätte, weil DJGPP nun mal kein
segmentiertes Speichermodell mit dem Potential, far pointer zu
benötigen, nutzt, sondern den 32-bittigen flat mode.
So geht es, zumindest bei mir:

void test(){
union REGS regs;
struct SREGS sregs;
unsigned short ZF = 0x40; /* Zerro-Flag bei 8086 und 80x86 */
unsigned short CF = 0x01; /* Carray-Flag bei 8086 und 80x86 */

#ifdef __TURBOC__
/*
Borlands Turbo C++ 3.0 erwartet zu Beginn einer
Funktion alle Variablen
*/
unsigned char far* p = NULL;
#endif /*TURBOC*/

unsigned char feature_byte = 0;

regs.x.ax = 0xC000;
int86(0x15, &regs, &regs);

if ((regs.h.ah == 0) && (!(regs.x.flags & CF))) {
/* AH ist 0 und CF ist nicht gesetzt : Anfrage erfolgreich*/
/*
Antwort bei ES:BX im sechsten Bit des zweiten
Feature-Byte, das hat Offset 6, steht die Tastatur-Funktionalität
*/


#ifdef __TURBOC__
segread( &sregs ); /* Lese Werte der Segment-Register */
p = (unsigned char far *) MK_FP(sregs.es, regs.x.bx);
feature_byte = p[6]; /* zweites Featurebyte hat Offset 6*/
#endif /*TURBOC */

#ifdef __DJGPP__
/*
DJGPP has the functions _my_cs, _my_ds, and _my_ss
for that purpose (ES and DS always hold the same selector
in code produced by GCC from a C or C++ source,
so you don't need a fourth function).
*/
unsigned short ES = _my_ds();
feature_byte = _farpeekb( _dos_ds, ES*16 + regs.x.bx + 6 );
#endif /*DJGPP*/

/* Prüfe 6. Bit vom zweiten Feature-Byte */
if (feature_byte & (1<<6)) {

....

}
}
}



Gruß Robert

Lesen Sie weiter auf narkive:
Loading...