Kein Videomodus 0x12 mehr bei qemu-KVM mit VGA verfügbar

rustyoldguy

Mitglied
Hallo Leute!

Eigentlich gehört diese Thema hier nicht rein, aber ich weis nicht, wen ich sonst fragen könnte. Leute, ich habe auf meinen
Suse LINUX tumbleweed qemu mit qemu-kvm als Emulator laufen. Damit kann ich meine alten Programme nehmen, ohne
viel herum arbeiten zu müssen.
Früher hat qemu-kvm bei der Emulation einer Standard-VGA-Grafik-Karte keine Zicken hinsichtlich der Grafikmodi gemacht.
Ärger machen nun die Modi 0x12, 0x10, 0xeh. Egal was ich für eine Grafik-Karte emuliere. Selbst wenn ich ein Bochs-Display
einbaue, geht nichts mehr. Der Modus 0x05 ist aber nicht betroffen. Eigentlich ist der Videomodus 0x12 mit 640x480 und 16
Farben Standard. Deshalb wundere ich mich darüber. Nur Trident-Karten hat man eine etwas schwierige Programmierung
nachgesagt. Davon war ich aber weniger betroffen.

Ich starte die jeweilige Emulation über den Aufruf von qemu-kvm von der Kommandozeile aus, etwa:

qemu-kvm -cdrom $HDDPFAD/FreeDos12CD.iso -m 64 -fda $HDDPFAD/144rwrd.img -hda $HDDPFAD/freedos13.img -cpu
phenom -device sb16 -usb -device usb-mouse -boot c -vga cirrus

Bis vor kurzem hatte ich das noch nicht. Gesetzt habe ich damals die Videomodi mit Int 10h Funktion 00h, ausgelesen mit
Int 10h Funktion 0fh oder mit einem Zeiger auf den damaligen BIOS-Bereich 449h.

Liest man bei DOS-Systemen mit dem Interrupt 10H Funktion 1bh die Graka aus, so werden bei ES und DI die Segment und
Offset-Adresse eines Puffer zurück gegeben bei dem
Byte 0 die Videomodi 0 bis 7h (Bit 0 bis 1) aufzeigen, wenn gesetzt dann verfügbar. Hier Bit 3,4,7 gesetzt, also Modus 3,4,7 verfügbar-
Seltsamer Weise ist aber Modus 5h verfügbar. Obwohl das Bit nicht gesetzt ist.
Byte 1 die Videomodi 8 bis fh (Bit 0 bis 1) aufzeigen, wenn gesetzt dann verfügbar. Hier Bit 5 gesetzt also Modus dh verfügbar.
Byte 2 die Videomodi 10 bis 17h (Bit 0 bis 1) aufzeigen, wenn gesetzt dann verfügbar. Hier nichts gesetzt.

Eigentlich dachte ich, das der Modus 12h zum Standard für VGA-Grafikkarten zählten, oder war das doch nicht so?
Ich hatte damals eine Reihe davon: Trident, ATI, NVidia, jedoch immer mit diesem Modus. Teilweise lungert das Zeugs heute
noch im Bastelkeller rum.

Das mainboard und die Graka auf dem tumbleweed läuft, ist das selbe.

Der selbe Fehler tritt bei der Emulation von Win98 SE auf.
Egal mit welchem Compiler ob jetzt der uralte QC25 oder DJGPP.
Bis vor kurzem hatte ich eine Reihe von emulierten Betriebssystemen: Noveldos7, MSDOS 6.22 mit Win3.11, Haiku, SUSE tumbleweed, OS2Warp3, BEOS, FREEBSD12, Win2000prf, Winxp, Win 7 prf.

Bis auf Freedos und win98se wurden alle in "Rente" geschickt.

Nur eine CD mit Sinix habe ich bis heute nie zum Laufen gebracht.

Weis jemand genaueres seit wann dies mit den Grafikmodi so ist?
 
Zuletzt bearbeitet:

rustyoldguy

Mitglied
Hab das Problemchen gelöst!
dosemu wurde installiert und emuliert den Grafikmodus 0x12 super.
Folgendes Beispiel wurde mit dem uralten qc25 Compiler mit dosemu compiliert:
Testbild.jpg

Ich hatte damals zur Arbeitserleichterung auf einer Fräsmaschine mit Heidenhain TNC 155 Steuerung
Kleine Rechenprogramme geschrieben. Aus nostalgischen Gründen habe ich diese wieder laufen lassen.
Fraesmaschine.jpg


Kleine Geschichte dazu:

Damals arbeitete ich in einer kleinen Firma mit 8 Mann. Mein damaliger Chef hatte eine Draht-Erodiermaschine mit
DIN-ISO Programmierung. Also mit G-Funktionen. Jedesmal wenn er einen Anschlusspunkt einer Kreisbahn haben wolle,
mußte ich die Fräsmaschine programmieren. Also Polarradius eingeben. Startwinkel und die Z-Achse auf die gewünschte
Position bringen. Danach notierte sich der Chef die Achsenpositionen. Da mir das dann auf den Senkel ging, programmierte
ich Ihm ein Programm das die Position errechnete. Das hätte er eigentlich mit dem Taschenrechner auch machen können.
Aber er lies sich von dieser Methode nicht abbringen. Vorher hatte ich in Amberg bei einem Zweigwerk eines Regensburger
Weltkonzerns gearbeitet, der Maschinen für die Getränkeindustrie herstellt. Das Zweigwerk wurde übrigens 1999 platt gemacht.
Dummerweise hatte ich gegenüber einem Meister einmal die Klappe zu weit aufgerissen als ich diesem im Gespräch entgegnete,
das man als Meister eigentlich die Dreiecksberechnung mit Sinus Cosinus und Tangens beherrschen sollte. Das hätte ich besser
bleiben lassen sollen.
Wie man in der Zerspanungstechnik Meister werden konnte ohne das zuletzt genannte zu können, ist mir heute noch ein Rätsel.
Aber Schwamm drüber. Ist 20 Jahre her. Was soll's.
Heute bin ich der Meinung das der Maschinenbau, auch Sondermaschinenbau und vor allem die Automobilindustrie inklusive der
gesamte Nutzfahrzeugbranche langfristig in Deutschland keine Zukunft mehr hat. Beispiel:

Ich arbeite momentan in einer Firma als Leiharbeiter, in der Kunststoffteile hergestellt werden. Zum Beispiel für Geschirrspülmaschinen
einer sehr bekannten deutschen Marke, deren Name von den Franzosen teilweise als Spitzname für Deutsche verwendet wurde.
Die Form für die Teile wurden dabei nicht in Deutschland, auch nicht in Europa sondern in Neuseeland gefertigt(Boahh!!!).
Das sagt viel über die Zukunft des Metallgewerbes in Deutschand aus. Momentan geht in Nordbayern bei einer Firma nach der anderen das Licht aus.

Überlegt euch lieber besser was ihr später mal werden wollt. Man verzeihe mir jetzt die Veröffentlichung folgenden Links:
Da kann man vor der Bewerbung schon nachsehen, ob sich die selbe lohnt.....


Inständig hoffend, mit der letzten Bemerkung keinen auf die Zehen getreten zu haben.
 
Zuletzt bearbeitet:

rustyoldguy

Mitglied
Hab das Problemchen gelöst!
dosemu wurde installiert und emuliert den Grafikmodus 0x12 super.
Folgendes Beispiel wurde mit dem uralten qc25 Compiler mit dosemu compiliert:
Anhang anzeigen 161
Ich hatte damals zur Arbeitserleichterung auf einer Fräsmaschine mit Heidenhain TNC 155 Steuerung
Kleine Rechenprogramme geschrieben. Aus nostalgischen Gründen habe ich diese wieder laufen lassen.
Anhang anzeigen 162

Kleine Geschichte dazu:

Damals arbeitete ich in einer kleinen Firma mit 8 Mann. Mein damaliger Chef hatte eine Draht-Erodiermaschine mit
DIN-ISO Programmierung. Also mit G-Funktionen. Jedesmal wenn er einen Anschlusspunkt einer Kreisbahn haben wolle,
mußte ich die Fräsmaschine programmieren. Also Polarradius eingeben. Startwinkel und die Z-Achse auf die gewünschte
Position bringen. Danach notierte sich der Chef die Achsenpositionen. Da mir das dann auf den Senkel ging, programmierte
ich Ihm ein Programm das die Position errechnete. Das hätte er eigentlich mit dem Taschenrechner auch machen können.
Aber er lies sich von dieser Methode nicht abbringen. Vorher hatte ich in Amberg bei einem Zweigwerk eines Regensburger
Weltkonzerns gearbeitet, der Maschinen für die Getränkeindustrie herstellt. Das Zweigwerk wurde übrigens 1999 platt gemacht.
Dummerweise hatte ich gegenüber einem Meister einmal die Klappe zu weit aufgerissen als ich diesem im Gespräch entgegnete, das man als Meister eigentlich die Dreiecksberechnung mit Sinus Cosinus und Tangens beherrschen sollte. Das hätte ich besser bleiben lassen sollen.
Wie man in der Zerspanungstechnik Meister werden konnte ohne das zuletzt genannte zu können, ist mir heute noch ein Rätsel.
Aber Schwamm drüber. Ist 20 Jahre her. Was soll's.
Heute bin ich der Meinung das der Maschinenbau, auch Sondermaschinenbau und vor allem die Automobilindustrie inklusive der gesamte Nutzfahrzeugbranche langfristig in Deutschland keine Zukunft mehr hat. Überlegt euch lieber besser was ihr später mal werden wollt.
Inständig hoffend, mit der letzten Bemerkung keinen auf die Zehen getreten zu haben.
Unter anderem schrieb ich auch ein Programmchen, um die Sehnenlänge, also den Abstand von Bohrungsmitte zu Bohrungsmitte
zweier Bohrungen zu kalkulieren, die auf zwei verschiedenen Teilkreisen liegen, mit graphischer Ansicht der Bohrungslagen:
Qemu_W98SE_Grakik1.jpg

Ich habe mir Win98 SE auf Qemu geholt.
Mit einem kleinen Programm für MSDOS habe ich folgende Infos raus geholt:
Modus-Lesen_Qemu_Win98SE.jpg


Das zeigt das der Videomodus 12h über VESA bei SeaBIOS läuft.
Bei qemu habe ich -vga cirrus zur Emulation einer Cirrus Grafikkarte als Parameter eingegeben.

Für neugierige das DOS-Programmchen. Damals war ich übrigens noch Anfänger. Deswegen die Fehler im Aufbau der Source.
Nach der Liste für die unterstützten Vesa-Modi blinkt der Curso(zur Eingabe heute würde ich es anders schreiben) entweder drückte man die Taste ESC zum Programmabbruch oder der Videomodus wurde eingegeben, dann erschienen mehr Infos zu dem eingegebenen Grafikmodus.
Zuerst die Header, die ich damals verwendete:
include tete.h:
Code:
/* Include Datei tete.h beinhaltet stdio.h, conio.h, eigen.h */
#include <kopf.h>
#include <dos.h>
 void oldclpuf(void)
 {
 while (getc(stdin) != '\n')
    ;
 }

void clpuf(void)
{
union REGS r;
r.h.ah = 0x0c;   /*  Tastaturpuffer loeschen */
r.h.al = 0x00;
int86(0x21,&r ,&r);
}
Wie man gut sehen kann gab es bei DOS einen extra Interrupt, um den Tastaturpuffer zu löschen.
nun
#include autor.h:
Code:
* selbstgeschriebener Header autor.h zum ausgeben eines Programminfos
ber das Copyright und den Autor */
void AUTOR()
{
CLS();
printf("COPYRIGHT and all other Rights by the Author");
printf("        Josef Wismeth");
}
Der damalige bei MSVC 1.52 enthaltene Header dos.h wurde von mir frisiert:
Code:
/***
*dos.h - definitions for MS-DOS interface routines
*
*   Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*   Defines the structs and unions used for the direct DOS interface
*   routines; includes macros to access the segment and offset
*   values of far pointers, so that they may be used by the routines; and
*   provides function prototypes for direct DOS interface functions.
*
****/

#ifndef _INC_DOS

#ifdef __cplusplus
extern "C" {
#endif

#if (_MSC_VER <= 600)
#define __cdecl     _cdecl
#define __far       _far
#define __interrupt _interrupt
#define __near      _near
#endif

#ifndef _REGS_DEFINED

/* word registers REGPACK is from TURBO-C++ V1.0 copied.
 * This is for the Function _intr. See Header intr.h */

struct  REGPACK {
    unsigned    r_ax, r_bx, r_cx, r_dx;
    unsigned    r_bp, r_si, r_di, r_ds, r_es, r_flags;
    };

struct _WORDREGS {
    unsigned int ax;
    unsigned int bx;
    unsigned int cx;
    unsigned int dx;
    unsigned int si;
    unsigned int di;
    unsigned int cflag;
    };

/* byte registers */

struct _BYTEREGS {
    unsigned char al, ah;
    unsigned char bl, bh;
    unsigned char cl, ch;
    unsigned char dl, dh;
    };

/* segment registers */

struct _SREGS {
    unsigned int es;
    unsigned int cs;
    unsigned int ss;
    unsigned int ds;
    unsigned int bp;
    };
 
/* general purpose registers union -
 *  overlays the corresponding word and byte registers.
 */

union _REGS {
    struct _WORDREGS x;
    struct _BYTEREGS h;
    struct _SREGS s;
    };
 
#ifndef __STDC__
/* Non-ANSI names for compatibility */

struct WORDREGS {
    unsigned int ax;
    unsigned int bx;
    unsigned int cx;
    unsigned int dx;
    unsigned int si;
    unsigned int di;
    unsigned int cflag;
    };

struct BYTEREGS {
    unsigned char al, ah;
    unsigned char bl, bh;
    unsigned char cl, ch;
    unsigned char dl, dh;
    };

struct SREGS {
    unsigned int es;
    unsigned int cs;
    unsigned int ss;
    unsigned int ds;
    unsigned int bp;
    };
 
union REGS {
    struct WORDREGS x;
    struct BYTEREGS h;
    struct SREGS s;
    };

#endif

#define _REGS_DEFINED
#endif


/* dosexterror structure */

#ifndef _DOSERROR_DEFINED
#pragma pack(2)

struct _DOSERROR {
    int exterror;
    char errclass;
    char action;
    char locus;
    };

#if ((!defined (__STDC__)) && (!defined (__cplusplus)))
/* Non-ANSI name for compatibility */
struct DOSERROR {
    int exterror;
    char class;
    char action;
    char locus;
    };
#endif

#pragma pack()
#define _DOSERROR_DEFINED
#endif


/* _dos_findfirst structure */

#ifndef _FIND_T_DEFINED
#pragma pack(2)

struct _find_t {
    char reserved[21];
    char attrib;
    unsigned wr_time;
    unsigned wr_date;
    long size;
    char name[13];
    };

#ifndef __STDC__
/* Non-ANSI name for compatibility */
#define find_t _find_t
#endif

#pragma pack()
#define _FIND_T_DEFINED
#endif


/* _dos_getdate/_dossetdate and _dos_gettime/_dos_settime structures */

#ifndef _DATETIME_T_DEFINED
#pragma pack(2)

struct _dosdate_t {
    unsigned char day;      /* 1-31 */
    unsigned char month;        /* 1-12 */
    unsigned int year;      /* 1980-2099 */
    unsigned char dayofweek;    /* 0-6, 0=Sunday */
    };

struct _dostime_t {
    unsigned char hour; /* 0-23 */
    unsigned char minute;   /* 0-59 */
    unsigned char second;   /* 0-59 */
    unsigned char hsecond;  /* 0-99 */
    };

#ifndef __STDC__
/* Non-ANSI names for compatibility */
#define dosdate_t _dosdate_t
#define dostime_t _dostime_t
#endif

#pragma pack()
#define _DATETIME_T_DEFINED
#endif


/* _dos_getdiskfree structure */

#ifndef _DISKFREE_T_DEFINED

struct _diskfree_t {
    unsigned total_clusters;
    unsigned avail_clusters;
    unsigned sectors_per_cluster;
    unsigned bytes_per_sector;
    };

#ifndef __STDC__
/* Non-ANSI name for compatibility */
#define diskfree_t _diskfree_t
#endif

#define _DISKFREE_T_DEFINED
#endif


/* manifest constants for _hardresume result parameter */

#define _HARDERR_IGNORE     0   /* Ignore the error */
#define _HARDERR_RETRY      1   /* Retry the operation */
#define _HARDERR_ABORT      2   /* Abort program issuing Interrupt 23h */
#define _HARDERR_FAIL       3   /* Fail the system call in progress */
                    /* _HARDERR_FAIL is not supported on DOS 2.x */

/* File attribute constants */

#define _A_NORMAL   0x00    /* Normal file - No read/write restrictions */
#define _A_RDONLY   0x01    /* Read only file */
#define _A_HIDDEN   0x02    /* Hidden file */
#define _A_SYSTEM   0x04    /* System file */
#define _A_VOLID    0x08    /* Volume ID file */
#define _A_SUBDIR   0x10    /* Subdirectory */
#define _A_ARCH     0x20    /* Archive file */

/* macros to break C "far" pointers into their segment and offset components
 */

#define _FP_SEG(fp) (*((unsigned __far *)&(fp)+1))
#define _FP_OFF(fp) (*((unsigned __far *)&(fp)))

/* macro to construct a far pointer from segment and offset values
 */

#ifndef _MK_FP
#define _MK_FP(seg, offset) (void __far *)(((unsigned long)seg << 16) \
    + (unsigned long)(unsigned)offset)
#endif
/* external variable declarations */

extern unsigned int __near __cdecl _osversion;


/* function prototypes */

#ifndef _MT
int __cdecl _bdos(int, unsigned int, unsigned int);
#ifndef _WINDOWS
void __cdecl _chain_intr(void (__cdecl __interrupt __far *)());
#endif
void __cdecl _disable(void);
#ifndef _WINDOWS
unsigned __cdecl _dos_allocmem(unsigned, unsigned *);
#endif
unsigned __cdecl _dos_close(int);
unsigned __cdecl _dos_commit(int);
unsigned __cdecl _dos_creat(const char *, unsigned, int *);
unsigned __cdecl _dos_creatnew(const char *, unsigned, int *);
unsigned __cdecl _dos_findfirst(const char *, unsigned, struct _find_t *);
unsigned __cdecl _dos_findnext(struct _find_t *);
#ifndef _WINDOWS
unsigned __cdecl _dos_freemem(unsigned);
#endif
void __cdecl _dos_getdate(struct _dosdate_t *);
void __cdecl _dos_getdrive(unsigned *);
unsigned __cdecl _dos_getdiskfree(unsigned, struct _diskfree_t *);
unsigned __cdecl _dos_getfileattr(const char *, unsigned *);
unsigned __cdecl _dos_getftime(int, unsigned *, unsigned *);
void __cdecl _dos_gettime(struct _dostime_t *);
void (__cdecl __interrupt __far * __cdecl _dos_getvect(unsigned))();
#ifndef _WINDOWS
void __cdecl _dos_keep(unsigned, unsigned);
#endif
unsigned __cdecl _dos_lock(int, int, unsigned long, unsigned long);
unsigned __cdecl _dos_open(const char *, unsigned, int *);
unsigned __cdecl _dos_read(int, void __far *, unsigned, unsigned *);
unsigned long __cdecl _dos_seek(int, unsigned long, int);
#ifndef _WINDOWS
unsigned __cdecl _dos_setblock(unsigned, unsigned, unsigned *);
#endif
unsigned __cdecl _dos_setdate(struct _dosdate_t *);
void __cdecl _dos_setdrive(unsigned, unsigned *);
unsigned __cdecl _dos_setfileattr(const char *, unsigned);
unsigned __cdecl _dos_setftime(int, unsigned, unsigned);
unsigned __cdecl _dos_settime(struct _dostime_t *);
#ifndef _WINDOWS
void __cdecl _dos_setvect(unsigned, void (__cdecl __interrupt __far *)());
#endif
unsigned __cdecl _dos_write(int, const void __far *, unsigned, unsigned *);
int __cdecl _dosexterr(struct _DOSERROR *);
void __cdecl _enable(void);
#ifndef _WINDOWS
void __cdecl _harderr(void (__far __cdecl *)(unsigned, unsigned,
    unsigned __far *));
void __cdecl _hardresume(int);
void __cdecl _hardretn(int);
#endif
int __cdecl _intdos(union _REGS *, union _REGS *);
int __cdecl _intdosx(union _REGS *, union _REGS *, struct _SREGS *);
int __cdecl _int86(int, union _REGS *, union _REGS *);
int __cdecl _int86x(int, union _REGS *, union _REGS *, struct _SREGS *);
#endif

void __cdecl _segread(struct _SREGS *);

#ifndef __STDC__
/* Non-ANSI names for compatibility */

#define FP_SEG     _FP_SEG
#define FP_OFF     _FP_OFF
#ifndef MK_FP
#define MK_FP      _MK_FP
#endif
#ifndef _MT
int __cdecl bdos(int, unsigned int, unsigned int);
int __cdecl intdos(union REGS *, union REGS *);
int __cdecl intdosx(union REGS *, union REGS *, struct SREGS *);
int __cdecl int86(int, union REGS *, union REGS *);
int __cdecl int86x(int, union REGS *, union REGS *, struct SREGS *);
void  _cdecl intr(int __intno, struct REGPACK *__preg);
#ifndef __cplusplus
int __cdecl dosexterr(struct DOSERROR *);
#endif
#endif
void __cdecl segread(struct SREGS *);

#endif

#ifdef __cplusplus
}
#endif

#define _INC_DOS
#endif
Um die in QBASIC enthaltenen Funktionen peeke und poke zu nutzen, schrieb ich mir einen "Header". Eigentlich eine Sünde, Funktionen direkt in einen Header zu packen. Aber ich war damals Anfänger.
nun
#include peekpoke.h:
Code:
/* Selbstgeschriebener Header peekpoke.h fr die Funktionen
 * peekx, peekw, peekdw */
#ifndef PepoSik
#define PepoSik 1
#endif
#if PepoSik == 1
#ifndef _MK_FP
#define _MK_FP(seg, offset) (void __far *)(((unsigned long)seg << 16) \
    + (unsigned long)(unsigned)offset)
#endif
#ifndef MK_FP
#define MK_FP(seg,offset) ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(offset)))
#endif

void poke(unsigned segm, unsigned offs, unsigned int value)
{
    *((unsigned int far *) MK_FP(segm, offs)) = value;
}

int peek(unsigned segm, unsigned offs)
{
    return *((int far *) MK_FP(segm, offs));
}
void pokeb(unsigned segm, unsigned offs, unsigned char value)
{
    *((unsigned char far *) MK_FP(segm, offs)) = value;
}

unsigned char peekb(unsigned segm, unsigned offs)
{
unsigned long addresse, segment, offset;
unsigned char rewer = 0;
segment = (unsigned long)segm;
offset =  (unsigned long)offs;
segment <<= 16;
addresse = segment | offset;
rewer = *(unsigned char far *)(addresse);
return(rewer);
}

unsigned long peekx(unsigned segm, unsigned offs, int laenge)
{
unsigned long addresse, rewer = 0;
if ((laenge  != 1) && (laenge != 2) && (laenge != 4))
 goto finito;
addresse = ((unsigned long)(segm << 16) | (unsigned long)offs);
if (laenge == 1) rewer = *(unsigned char far *)(addresse);
if (laenge == 2) rewer = *(unsigned int far *) (addresse);
if (laenge == 4) rewer = *(unsigned long far *)(addresse);
finito: return(rewer);
}


unsigned int peekw(unsigned segm, unsigned offs)
{
unsigned long addresse, segment, offset;
unsigned int rewer = 0;
segment = (unsigned long)segm;
offset =  (unsigned long)offs;
segment <<= 16;
addresse = segment | offset;
rewer = *(unsigned int far *)(addresse);
return(rewer);
}

unsigned long peekdw(unsigned segm, unsigned offs)
{
unsigned long addresse, segment, offset;
unsigned long rewer = 0;
segment = (unsigned long)segm;
offset =  (unsigned long)offs;
segment <<= 16;
addresse = segment | offset;
rewer = *(unsigned long far *)(addresse);
return(rewer);
}

unsigned char peekb_add(unsigned long adresse)
{

unsigned char wert;
wert = *(unsigned char far *)(adresse);
return(wert);
}

void pokeb_add(unsigned long adresse, unsigned char value)
{
    *(unsigned char far *)(adresse) = value;
}

#undef PepoSik
#define PepoSik 2
#endif
hier der header
kopf.h:
Code:
#include <stdio.h>
#include <conio.h>
#include <eigen.h>
schliesslich eigen.h:
Code:
/* Headerdatei eigen.h fuer Bildschirmloeschen und Cursorpositionierung */
#ifndef KoheKon
#define KoheKon 1
#endif
#if KoheKon == 1

#include <conio.h>
#include <graph.h>
#include <skako.h>

/*
 *  _GCLEARSCREEN    löscht den gesamten Grafikbildschirm
 *  _GVIEWPORT        löscht das aktuelle (Grafik-) Zeichenfenster
 *  _GWINDOW        das aktuelle Textfenster
 */
#ifdef __cplusplus
void CLS(short loeschart = _GCLEARSCREEN)
{
 _clearscreen( loeschart );
}
#else
void CLS(void)
{
 _clearscreen( _GCLEARSCREEN );
}
#endif

void LOCATE(int zeile, int spalte)
{
_settextposition( (short)zeile, (short)spalte );
}
/* Bedeutung der Farbwerte in den NON-Textmodi sind:
*
*  Name..........Hex.........dez......Binaer....................deutscher Name...Eingabewert für
*                                               |       |                         _settextcolor(index);
* _BLACK         0x000000L   0        000000000000000000000000  Schwarz          0
* _BLUE             0x2a0000L   2752512  001010100000000000000000  Blau             1
* _GREEN         0x002a00L   10752    000000000010101000000000  Gruen            2
* _CYAN             0x2a2a00L   2763264  001010100010101000000000  Zyan             3
* _RED             0x00002aL   42       000000000000000000101010  Rot              4
* _MAGENTA         0x2a002aL   2752554  001010100000000000101010  Violett          5
* _BROWN         0x00152aL   5418     000000000001010100101010  Braun            6
* _WHITE         0x2a2a2aL   2763306  001010100010101000101010  Weiss            7
* _GRAY             0x151515L   1381653  000101010001010100010101  Dunkelgrau       8
* _LIGHTBLUE     0x3F1515L   4134165  001111110001010100010101  Hellblau         9
* _LIGHTGREEN     0x153f15L   1392405  000101010011111100010101  Hellgruen        10
* _LIGHTCYAN     0x3f3f15L   4144917  001111110011111100010101  Hellzyan         11
* _LIGHTRED         0x15153fL   1381695  000101010001010100111111  Hellrot          12
* _LIGHTMAGENTA  0x3f153fL   4134207  001111110001010100111111  Hellviolett      13
* _YELLOW         0x153f3fL   1392447  001010100111111001111110  Hellbraun        14
* _BRIGHTWHITE   0x3f3f3fL   4144959  001111110011111100111111  Hellweiss        15
*
* Note: 101010Bin=42dez
*       010101Bin=21dez
*/
#ifdef __cplusplus
int FENSTERSAUBER( int ya, int xa, int ye, int xe, short farbe = -1)
 {
  struct _videoconfig vc;
  short urxa, urya, urye, urxe, letx, lety, filcol = 0, slei, oldcol;
  long hicol;
  long bkfarben[16] = {_BLACK, _BLUE, _GREEN,  _CYAN,\
                     _RED, _MAGENTA, _BROWN, _WHITE,\
                     _GRAY,_LIGHTBLUE, _LIGHTGREEN,_LIGHTCYAN,\
                     _LIGHTRED,_LIGHTMAGENTA,_YELLOW, _BRIGHTWHITE };

  _getvideoconfig( &vc );
  if ((vc.mode <= 3) || (vc.mode == 7))
   {
    _gettextwindow(&urya, &urxa, &urye, &urxe);
    _settextwindow((short)ya, (short)xa, (short)ye, (short)xe);
    _clearscreen(_GWINDOW);
    _settextwindow( urya, urxa, urye, urxe);
   }
  else
   {
    hicol = _getbkcolor();    /* Rckgabewert long */
    if (farbe < 0)
     {
      for (slei = 0; slei <= 15; slei++)
       if (hicol == bkfarben[slei] )
        filcol = slei;
     }
      else
       filcol = farbe;
    if (farbe >= vc.numcolors) goto finito;
    letx = vc.numxpixels / vc.numtextcols;
    lety = vc.numypixels / vc.numtextrows;
    urxa = (xa * letx) - letx;
    urxe = (xe * letx) - (short)1;
    urya = (ya * lety) - lety;
    urye = (ye * lety) - (short)1;
    oldcol = _setcolor(filcol);
    _rectangle(_GFILLINTERIOR, urxa, urya, urxe,urye);
    //_setcolor(oldcol);
   }
 
 finito: return(vc.mode);
 }
#else
 int FENSTERSAUBER( int ya, int xa, int ye, int xe)
 {
  struct _videoconfig vc;
  short urxa, urya, urye, urxe, letx, lety, filcol = 0, slei, oldcol, textfarbe;
  long hicol;
  long bkfarben[16] = {_BLACK, _BLUE, _GREEN,  _CYAN,\
                     _RED, _MAGENTA, _BROWN, _WHITE,\
                     _GRAY,_LIGHTBLUE, _LIGHTGREEN,_LIGHTCYAN,\
                     _LIGHTRED,_LIGHTMAGENTA,_YELLOW, _BRIGHTWHITE };

  _getvideoconfig( &vc );
  if ((vc.mode <= 3) || (vc.mode == 7))
   {
    _gettextwindow(&urya, &urxa, &urye, &urxe);
    _settextwindow((short)ya, (short)xa, (short)ye, (short)xe);
    _clearscreen(_GWINDOW);
    _settextwindow( urya, urxa, urye, urxe);
   }
  else
   {
    hicol = _getbkcolor();    /* Rckgabewert long */
    textfarbe = _gettextcolor();
    for (slei = 0; slei <= 15; slei++)
    if (hicol == bkfarben[slei] )  filcol = slei;
    letx = vc.numxpixels / vc.numtextcols;
    lety = vc.numypixels / vc.numtextrows;
    urxa = (xa * letx) - letx;
    urxe = (xe * letx) - (short)1;
    urya = (ya * lety) - lety;
    urye = (ye * lety) - (short)1;
    oldcol = _setcolor(filcol);
    _rectangle(_GFILLINTERIOR, urxa, urya, urxe,urye);
    _setcolor(oldcol);
    _settextcolor(textfarbe);
   }
 return(vc.mode);
 }
#endif
 
/*int OLD_FENSTERSAUBER( int ya, int xa, int ye, int xe)
  {
   short urxa, urya, urye, urxe;
   _gettextwindow(&urya, &urxa, &urye, &urxe);
   _settextwindow((short)ya, (short)xa, (short)ye, (short)xe);
   _clearscreen(_GWINDOW);
   _settextwindow( urya, urxa, urye, urxe);
  return 0;
  }
  */
 

int SCREEN(int modus)
{
int rewer;
rewer = _setvideomode((short)modus);
return(rewer);
}

int ZeilZahl(void)
{
 int rewe;
 char zeilenzahl = *((char far *)(unsigned long)0x484);
 rewe = ++zeilenzahl;
 return rewe;
}

int SpaltenZahl(void)
{
 int rewe;
 char spaltenzahl = *((char far *)(unsigned long)0x44a);
 rewe = spaltenzahl;
 return rewe;
}

void TEILSAUBER(int beginn, int ende)
{
int spa, zeiz;
spa  = SpaltenZahl();
zeiz = ZeilZahl();
FENSTERSAUBER( beginn, 1, ende, spa);
}

void ZEILC(int zeile)
{
_settextposition((short)zeile, 1);
printf("\033[K");
}

void ZEILS(int zeile)
{
struct videoconfig bild;
_getvideoconfig( &bild );
_settextwindow( (short)zeile, 1, (short)zeile, bild.numtextcols);
_clearscreen(_GWINDOW);
_settextwindow( 1, 1, bild.numtextrows, bild.numtextcols);
}

#ifdef __cplusplus
void PROGENDE(int zeile = 0, int spalte = 0)
{
struct rccoord position;
if ( (zeile == 0) && (spalte == 0))
 {
  position = _gettextposition();
  _settextposition(position.row, 1);
 }
if (spalte == 0) LOCATE(zeile, 1);
 else            LOCATE(zeile,spalte);
 
printf("Programmende: Bitte Taste drcken");
getch();
}
#else
void PROGENDE(void)
{
struct rccoord position;
position = _gettextposition();
_settextposition(position.row, 1);
printf("Programmende: Bitte Taste drcken");
getch();
}
#endif
#ifdef __cplusplus
void HALT(int zeile = 0, int spalte = 0)
{
struct rccoord position;
if ( (zeile == 0) && (spalte == 0))
 {
  position = _gettextposition();
  _settextposition(position.row, 1);
 }
if (spalte == 0) LOCATE(zeile, 1);
 else            LOCATE(zeile,spalte);
 
printf("Zur Programmfortsetzung bitte Taste drcken");
getch();
}
#else
void HALT(void)
{
struct rccoord position;
position = _gettextposition();
_settextposition(position.row, 1);
printf("Zur Programmfortsetzung bitte Taste drcken");
getch();
}
#endif
#undef KoheKon
#define KoheKon 2
#endif

Darin war Header skako.h:
Code:
/*selbsgeschriebener Header skako.h zum ermitteln
des SCAN-Wertes einer gedrckten Taste */
/* Prototyp int FTASTE(void) */
/*
* selbsgeschriebener Header skako.h zum ermitteln
* des SCAN-Wertes einer gedrckten Taste
*/
/* Prototyp int FTASTE(void) */
#include <dos.h>

int FTASTE(void)
{
 int sca = 0;
 union REGS r;
 r.h.ah = 0;
 int86(0x16,&r,&r);
 sca = (int)r.h.ah;
return(sca);
}
 
/* Alte Version der Funktion FTEST(), die nur überprüfen sollte ob eine Taste
 * gedrückt wurde, wenn nicht, sollte Sie eine 0 zurückgeben, sonst den
 * SCAN-CODE der gedrückten Taste. Die Neue Version arbeitet mit den DOS-
 * Interrupt 21h, siehe untere Beschreibung.

*int FTEST(void)
*{
* int sca = 0;
* union REGS r;
* r.h.ah = 0x01;
* int86(0x16,&r,&r);
* sca = (int)r.h.ah;
* return(sca);
*}

 /* Prüft mit DOS-Interrupt 21h Funktions-Nummer 0bh,
 * ob eine Taste gedrückt wurde,wenn ja Rückgabe des
 * Scancodes der gedrückten Taste, sonst Null*/
#define FTEST() kbget();
int kbget(void)
{
 int sca = 0;
 union REGS r;
 r.h.ah = 0x0b; /* DOS-Interrupt, ob Zeichen im Speicher */
 int86(0x21,&r,&r);
 if ((r.h.ah) == 0)
  goto finito;

 r.h.ah = 0x00; /* BIOS-Interrupt, hole SCAN-CODE von Zeichen */
 int86(0x16,&r,&r);
 sca = (int)r.h.ah;
 
 finito: return(sca);
}

Hätte ich heute völlig anders geschrieben. Hab ich jetzt das alles hier mit rein gepackt, falls einer mit MSDOS experimentieren will.
Damals hatte ich folgende Compiler:
QB 4.5
QC25
MSVC 1.0
MSVC 1.52
MSVC 2.0
TC 1.0
Ferner hatte ich MASM 6.11 und Quick Pascal 1.0

Angefangen habe ich mit einen Shareware-Compiler Symantec 6.11.
Später dann Borland C 3.1 und Turbo-Pascal 5.5
Die Installations-Software hatte ich nach dem Kauf nie weggeworfen, sondern bis heute auf einer CD geparkt.
DOSEMU packt übrigens den Software-Uropa QC25 ganz gut.

Nun SCREEN1.C:
Code:
#include <tete.h>
#include <autor.h>
#include <dos.h>
#include <stdlib.h>
#include <peekpoke.h>

struct VGAInf
{
 int vimo;
 int zeilen;
 int spalten;
 int akseite;
 int seiten;
 int farben;
 int sidegreatinbyte;
 int vgainitverhalten;
 int monitorart;
 int displaycombinationcode;
 unsigned int windowsize;
 unsigned int wingranularity;
 unsigned long  curwindow;
 int breite;
 int hoehe;
} VGAgroessen;

unsigned long getnumtype(unsigned char *datfeld,\
             unsigned int datlen, unsigned int datpos)
{
 unsigned long dummy = 0;
 if ((datlen > 4) || (datlen < 1) || (datlen == 3)) goto finito;
 
 dummy = datfeld[datpos];
 if (datlen == 1) goto finito;
 dummy += ((unsigned long)datfeld[datpos + 1] << 8);
 if (datlen == 2) goto finito;
 dummy += ((unsigned long)datfeld[datpos + 2] << 16);
 dummy += ((unsigned long)datfeld[datpos + 3] << 24);
finito: return(dummy);
}

/*  setzen des Bildschirmmodus*/
void disp_setmode(int modus)
 {
 union REGS r;
 char modic = (char)modus;

 r.h.ah = 0;        /* Funktionsnummer               */
 r.h.al = modic;    /* Einzustellende Modusnummer    */
 int86(0x10,&r ,&r);
}

void disp_setactivepage(int seite)
 {
 union REGS r;
 
 r.h.ah = 0x05;        /* Funktionsnummer               */
 r.h.al = (char)seite; /* neue aktive Bildschirmsseite  */
 int86(0x10,&r ,&r);
}

int _getDisplayCombinationCode(int (*disakkon) )
{
 union REGS einreg, ausreg;
 int rewer = 0;
 
  einreg.h.ah = 0x1a;              /* ah = Funktionsnummer */
  einreg.h.al = 0x00;              /* al = Unterfunktionsnummer */
  int86( 0x10, &einreg, &ausreg);  /* Displaykombination-code bestimmen */
 
  if (ausreg.h.ah != 0x1a)  rewer = 1;     /* AL = 1ah Funktion wird unterstuetzt */
 
    (*disakkon) = (int)ausreg.h.bl;  /* Displaycode des aktiven Adapters*/
  return(rewer);
}

int _getVesaModus(int modus, unsigned char puffer[])
{
union  REGS einreg, ausreg;
struct SREGS segreg;
unsigned segi, offi, rewer;
void _far *sct = &puffer[0];

segi = offi = rewer = 0;
/* Errechnet die Adresse des Lesepuffers */
segi = FP_SEG(sct);
offi = FP_OFF(sct);
 
 einreg.h.ah = 0x4f;              /* ah = Funktionsnummer */
 einreg.h.al = 0x01;              /* muss z.Z immer so gesetzt sein */
 einreg.x.cx = modus;
 segreg.es   = segi;              /* Segmentadresse des Puffers */
 einreg.x.di = offi;              /* Offsetadresse des Puffers */
 int86x( 0x10, &einreg, &ausreg, &segreg);  /* Status auslesen */
 if ((ausreg.h.al != 0x4f) || (ausreg.h.ah != 0))
 rewer = (int)ausreg.h.ah;         /* AL = 4f Funktion wird  unterstuetzt */
return(rewer);
}
int _getVideoStatus(unsigned char puffer[])
{
union  REGS einreg, ausreg;
struct SREGS segreg;
unsigned segi, offi;
int rewer = 0;
void _far *sct = &puffer[0];

segi = offi = rewer = 0;
/* Errechnet die Adresse des Lesepuffers */
segi = FP_SEG(sct);
offi = FP_OFF(sct);
 
 einreg.h.ah = 0x1b;              /* ah = Funktionsnummer */
 einreg.x.bx = 0x00;              /* muss z.Z immer so gesetzt sein */
 segreg.es   = segi;              /* Segmentadresse des Puffers */
 einreg.x.di = offi;              /* Offsetadresse des Puffers */
 int86x( 0x10, &einreg, &ausreg, &segreg);  /* Status auslesen */
 rewer = (int)ausreg.h.al;         /* AL = 1Bh Funktion wird  unterstuetzt */
return(rewer);
}

int _getVesaInfos(unsigned char puffer[])
{
union  REGS einreg, ausreg;
struct SREGS segreg;
int rewer = 0;
unsigned segi, offi;
void _far *sct = &puffer[0];

segi = offi = 0;
/* Errechnet die Adresse des Lesepuffers */
segi = FP_SEG(sct);
offi = FP_OFF(sct);
 
 einreg.h.ah = 0x04f;             /* ah = Funktionsnummer */
 einreg.h.al = 0x00;              /* muss z.Z immer so gesetzt sein */
 segreg.es   = segi;              /* Segmentadresse des Puffers */
 einreg.x.di = offi;              /* Offsetadresse des Puffers */
 int86x( 0x10, &einreg, &ausreg, &segreg);  /* Status auslesen */
 if ((ausreg.h.al != 0x4f) || (ausreg.h.ah != 0))
  rewer = (int)ausreg.h.ah;      /* AL = 4f Funktion wird  unterstuetzt, ah=0 bei Erfolg, sonst ah=01 */
 return(rewer);
}

void KartenName(unsigned long adresse, char kartenname[] )
{
  char slei;
 for (slei = 0; slei <=40; slei++)
  {
   kartenname[slei] = *(char far *)(adresse + slei);
    if ( kartenname[slei] == '\0') break;
  }
}

void Schlussinfo(void)
{
 printf("\nInfo: Laufwerk:\\>SCREEN /?");
 printf("\nZum beenden des Programms Taste drcken");
 getch();
}

void Hauptinfo(struct VGAInf VGAgroessen)
{
 int disakkon = VGAgroessen.displaycombinationcode;
 int vimo     =  VGAgroessen.vimo;
 printf("Videomodus-Daten:");
 printf("\nAktiver Modus: 0%xh aktive Seite: %u", VGAgroessen.vimo, VGAgroessen.akseite);
 printf("\nTextspalten: %4u   Textzeilen:  %u", VGAgroessen.spalten,     VGAgroessen.zeilen);
 printf("\nSeitenzahl:  %4u   Seitengráe: %u Byte", VGAgroessen.seiten, VGAgroessen.sidegreatinbyte);
 printf("\nFarben:      %d    ", VGAgroessen.farben);
 printf("Monitorart: ");
 
  if (VGAgroessen.monitorart == 0)  printf("Farbmonitor");
  else                              printf("Monochrommonitor");
 
    if(disakkon == 0x00)  printf("\nkein Adapter");
    if(disakkon == 0x01)  printf("\nMDA-Karte");
    if(disakkon == 0x02)  printf("\nCGA-Karte");
    if(disakkon == 0x04)  printf("\nEGA-Karte mit Farbmonitor");
    if(disakkon == 0x05)  printf("\nEGA-Karte mit monochromen Monitor");
    if(disakkon == 0x06)  printf("\nPGA-Karte");
    if(disakkon == 0x07)  printf("\nVGA-Karte mit monochromen Analogmonitor");
    if(disakkon == 0x08)  printf("\nVGA-Karte mit analogen Farbmonitor");
    if(disakkon == 0x0a)  printf("\nMCGA-Karte mit digitalen Monitor");
    if(disakkon == 0x0b)  printf("\nMCGA-Karte mit monochromen Analogmonitor");
    if(disakkon == 0x0c)  printf("\nMCGA-Karte mit analogen Farbmonitor");

 if (vimo == 4)  printf("\n320 x 200 color graphics");
 if (vimo == 5)  printf("\n320 x 200 B/W graphics");
 if (vimo == 6)  printf("\n640 x 200 B/W graphics");
 if (vimo == 7)  printf("\n80 x 25 B/W for mono display");
 if (vimo == 13) printf("\n320 x 200 16 color graphics");
 if (vimo == 14) printf("\n640 x 200 16 color graphics");
 if (vimo == 15) printf("\n640 x 350 4 color graphics for mono display");
 if (vimo == 16) printf("\n640 x 350 16 color graphics");

}

void main(int argc, char *argv[])
{

struct VGAInf VGAgroessen;
char versa[6] = { 's', 'e', 'i', 't', 'e', '\0' };
char habef[6] = { 'h', 'a', 'l', 't', '\0' };
char puffer[68], vesapuffer[256], vesamodepuffer[256],grcard[50];
int vimo, verhalten, seite, teza, duma, slei, vesamodi;
int wohin, vesmo, breite, hoehe, fehler, texgr; //, vesa_col[50];
unsigned int dummy,vesa_mode[100], modeart[100];
unsigned long adresse;

if (argc > 4)
 goto ausis;

    VGAgroessen.vimo    = peekb(0, 0x449);
    VGAgroessen.akseite = peekb(0, 0x462);
    VGAgroessen.spalten = peekb(0, 0x44a);
    VGAgroessen.zeilen  = (peekb(0, 0x484)) + 1;
 
    VGAgroessen.vgainitverhalten = peekb(0, 0x489);
    VGAgroessen.monitorart       = VGAgroessen.vgainitverhalten & 2;
    VGAgroessen.sidegreatinbyte  = peek(0, 0x44c);
           
    _getDisplayCombinationCode(&VGAgroessen.displaycombinationcode);
    fehler = _getVideoStatus(puffer);
 
   VGAgroessen.farben = puffer[0x27];
   VGAgroessen.farben += puffer[0x28] << 8;
   VGAgroessen.seiten = puffer[0x29];
 
 
 /*--------------------------Videomode setzen---------------------- */
  if ( (argc == 2) && ((strcmp(argv[1], "/?")) == 0))
   {
    AUTOR();
    printf("\nAufruf Laufwerk:\\>SCREEN /M....setze Bildschirmmodi");
    printf("\nAufruf Laufwerk:\\>SCREEN /p....setze aktive Bildschirmseite");
    printf("\nAufruf Laufwerk:\\>SCREEN Ausgabe der aktiven Parameter");
    goto ausis;
   }
 
  if ((argc == 3) || (argc == 4))
   {
   if ( ((strcmp(argv[1], "/M")) == 0) || ((strcmp(argv[1], "/m")) == 0) )
     {                                                  
      vimo = atoi(argv[2]);
      if ((vimo < 0) || (vimo > 19))  goto ausis;
      disp_setmode(vimo);   /* Videomodus setzen*/
     }
 
    if ( ((strcmp(argv[1], "/P")) == 0) || ((strcmp(argv[1], "/p")) == 0) )
     {
       seite = atoi(argv[2]);
       if (seite >= VGAgroessen.seiten) goto ausis;
       disp_setactivepage(seite); /* aktive Seite setzen: Nummer der neuen Seite*/
     }
    goto ausis;
   }
 
hauptmenue: CLS();
            Hauptinfo(VGAgroessen);
            printf("\nVesaVideomodus-Info...f1");
            printf("\nEnde..................Esc");

      for (teza = 0; teza < argc; teza++)
       {
        verhalten = strcmp(argv[teza], habef);
        if (verhalten == 0) goto finito;
       }
 

for (slei = 0; slei <=255; slei++)  vesapuffer[slei] = 0;
duma = _getVesaInfos(vesapuffer);
 if (duma != 0)
  {
   printf("\nFehler Bei VesaInfoauslesen: %d", duma);
   goto finito;
  }

printf("\nVesa Versionsnummer:....%d.%0.2d", vesapuffer[5], vesapuffer[4]);

adresse = getnumtype( vesapuffer, 4, 0x06);

KartenName(adresse, grcard);
printf("\nGraphikkarte:...........%s\n", grcard);


/* Unterstuetzte Vesa-Modi feststellen*/
adresse = getnumtype( vesapuffer, 4, 0x0e);
vesamodi = 0;
for (slei = 0; slei <= 160; slei+=2)
  {
   dummy = *(unsigned int far *)(adresse + slei);
   if ( dummy == 65535) break;
   vesa_mode[vesamodi++] = dummy;
  }
/* Unterstuetzte Vesa-Modi feststellen Ende */
/* Unterstuetzte Vesa-Modi anzeigen */

for (slei = 0; slei < vesamodi; slei++)
 {
   _getVesaModus(vesa_mode[slei], vesamodepuffer);
  texgr  = (int)getnumtype( vesamodepuffer, 2, 0x00);
  if ( (texgr & 16) )  modeart[slei] = 71; /* Grafikmodus */
   else                modeart[slei] = 84; /* Textmodus   */
 }

printf("\nUnterstuetzte Vesa-Modi: %d (G=Grafikmodus, T=Textmodus)\n", vesamodi);
for (slei = 0; slei < vesamodi; slei++)
  printf(" %4xh %c", vesa_mode[slei], modeart[slei]);
 

wouhi: wohin = FTASTE();
       if (wohin == 1)  goto ausis;
       if (wohin == 59) goto vesamodeinfo;
  goto wouhi;

finito: Schlussinfo();
        goto ausis;
   
vesamodeinfo: LOCATE(22,1);
              printf("Vesa-Mode: ");
              scanf("%x", &vesmo);
              _getVesaModus(vesmo, vesamodepuffer);
              breite = (int)getnumtype( vesamodepuffer, 2, 0x12);
              hoehe  = (int)getnumtype( vesamodepuffer, 2, 0x14);
              texgr  = (int)getnumtype( vesamodepuffer, 2, 0x00);
              LOCATE(22,1);
              printf("Vesamode: %x Breite: %d Hoehe: %d Fenstergroesse in kb: %d\n",\
                       vesmo, breite, hoehe, (int)getnumtype( vesamodepuffer, 2, 0x06) );
              if ( (texgr & 16) )  printf("Grafikmodus, ");
               else                printf("Textmodus, ");
              if ( (texgr & 8) )  printf("Farbvideomodus, ");
               else               printf("Momochrommodus, ");
              VGAgroessen.wingranularity = (unsigned int)getnumtype( vesamodepuffer, 2, 0x04);
              printf("Granularity: %d", VGAgroessen.wingranularity);
              getch();
              clpuf();
           goto hauptmenue;
ausis:       ;
}

Wie gesagt war ich damals ein Greenhorn.
 

Anhänge

  • Vesa-Grafik-Infos_auslesen.jpg
    Vesa-Grafik-Infos_auslesen.jpg
    155,2 KB · Aufrufe: 25
Zuletzt bearbeitet:
Oben Unten