Probleme mit VESA auf neuen Rechnern.

Diskussion zum Thema Programmierung unter DOS (Intel x86)
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

@freecrac:
Naja, Deine bisherige Vorgehensweise geht davon aus, daß ein Rechner immer mehr als 64MB Speicher drin hat. Was bei DOS-Rechnern aber nicht Standard ist. (Meiner hat z.B. 16MB drin.)
Aber OK, andererseits muß man natürlich sagen, daß es im Falle von DOS relativ egal ist, weil es ja ein Singletask-OS ist. Wenn erstmal eins Deiner Programme läuft (im UnrealMode oder in welchem Mode auch immer), wird nachträglich ja ohnehin kein anderes Programm mehr angeschissen kommen und HIMEM.SYS um Speicher anbetteln oder sowas. Damit ein anderes Programm läuft, müßte das aktuell laufende ja ohnehin beendet werden...
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

DOSferatu hat geschrieben:@freecrac:
Naja, Deine bisherige Vorgehensweise geht davon aus, daß ein Rechner immer mehr als 64MB Speicher drin hat. Was bei DOS-Rechnern aber nicht Standard ist. (Meiner hat z.B. 16MB drin.)
Das wäre vorher über entsprechende BIOS-Funktionen abzuchecken.

Code: Alles auswählen

[RBIL->inter61a.zip->Interrup.c]
--------B-1588-------------------------------
INT 15 - SYSTEM - GET EXTENDED MEMORY SIZE (286+)
	AH = 88h
Return: CF clear if successful
	    AX = number of contiguous KB starting at absolute address 100000h
	CF set on error
	    AH = status
		80h invalid command (PC,PCjr)
		86h unsupported function (XT,PS30)
Notes:	TSRs which wish to allocate extended memory to themselves often hook
	  this call, and return a reduced memory size.	They are then free to
	  use the memory between the new and old sizes at will.
	the standard BIOS only returns memory between 1MB and 16MB; use AH=C7h
	  for memory beyond 16MB
	not all BIOSes correctly return the carry flag, making this call
	  unreliable unless one first checks whether it is supported through
	  a mechanism other than calling the function and testing CF
	Due to applications not dealing with more than 24-bit descriptors
	  (286), Windows 3.0 has problems when this function reports more
	  than 15 MB. Some releases of HIMEM.SYS are therefore limited to use
	  only 15 MB, even when this function reports more.
SeeAlso: AH=87h,AH=8Ah"Phoenix",AH=C7h,AX=DA88h,AX=E801h,AX=E820h
---------------------------------------------------------------------------
...
--------B-15C7-------------------------------
INT 15 - SYSTEM - later PS/2s - RETURN MEMORY-MAP INFORMATION
	AH = C7h
	DS:SI -> user supplied memory map table (see #00526)
Return: CF set on error
	CF clear if successful
Notes:	call AH=C0h and examine bit 4 of feature byte 2 to check if this
	  function is supported
	IBM classifies this function as optional
	Windows95 OSR2 reportedly does not support this function even though
	  INT 15/AH=C0h indicates that it is available (observed on several
	  different systems)
SeeAlso: AH=C0h,AH=C9h,AH=D1h,AX=E820h

Format of memory-map table structure:
Offset	Size	Description	(Table 00526)
 00h	WORD	length of table (excluding this word)
 02h	DWORD	local memory between 1M and 16M, in 1K blocks
 06h	DWORD	local memory between 16M and 4G, in 1K blocks
 0Ah	DWORD	system memory between 1M and 16M, in 1K blocks
 0Eh	DWORD	system memory between 16M and 4G, in 1K blocks
 12h	DWORD	cacheable memory between 1M and 16M, in 1K blocks
 16h	DWORD	cacheable memory between 16M and 4G, in 1K blocks
 1Ah	DWORD	1K blocks before start of non-system memory between 1M and 16M
 1Eh	DWORD	1K blocks before start of non-system memory between 16M and 4G
 22h	WORD	start segment of largest free block from C0000h-DFFFFh
 24h	WORD	size of largest free block
 26h	DWORD	reserved
---------------------------------------------------------------------------
...
----------15DA88-----------------------------
INT 15 U - AMI PCI BIOS - GET EXTENDED MEMORY SIZE
	AX = DA88h
Return: CF clear (successful)
	AX = 0000h
	CL:BX = extended memory size in KBytes
SeeAlso: AH=88h
---------------------------------------------------------------------------
...
[RBIL->inter61a.zip->Interrup.d]
--------b-15E801-----------------------------
INT 15 - Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
	AX = E801h
Return: CF clear if successful
	    AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
	    BX = extended memory above 16M, in 64K blocks
	    CX = configured memory 1M to 16M, in K
	    DX = configured memory above 16M, in 64K blocks
	CF set on error
Notes:	supported by the A03 level (6/14/94) and later XPS P90 BIOSes, as well
	  as the Compaq Contura, 3/8/93 DESKPRO/i, and 7/26/93 LTE Lite 386 ROM
	  BIOS
	supported by AMI BIOSes dated 8/23/94 or later
	on some systems, the BIOS returns AX=BX=0000h; in this case, use CX
	  and DX instead of AX and BX
	this interface is used by Windows NT 3.1, OS/2 v2.11/2.20, and is
	  used as a fall-back by newer versions if AX=E820h is not supported
	this function is not used by MS-DOS 6.0 HIMEM.SYS when an EISA machine
	  (for example with parameter /EISA) (see also MEM F000h:FFD9h), or no
	  Compaq machine was detected, or parameter /NOABOVE16 was given.
SeeAlso: AH=8Ah"Phoenix",AX=E802h,AX=E820h,AX=E881h"Phoenix"
---------------------------------------------------------------------------
...
--------b-15E820-----------------------------
INT 15 - newer BIOSes - GET SYSTEM MEMORY MAP
	AX = E820h
	EAX = 0000E820h
	EDX = 534D4150h ('SMAP')
	EBX = continuation value or 00000000h to start at beginning of map
	ECX = size of buffer for result, in bytes (should be >= 20 bytes)
	ES:DI -> buffer for result (see #00581)
Return: CF clear if successful
	    EAX = 534D4150h ('SMAP')
	    ES:DI buffer filled
	    EBX = next offset from which to copy or 00000000h if all done
	    ECX = actual length returned in bytes
	CF set on error
	    AH = error code (86h) (see #00496 at INT 15/AH=80h)
Notes:	originally introduced with the Phoenix BIOS v4.0, this function is
	  now supported by most newer BIOSes, since various versions of Windows
	  call it to find out about the system memory
	a maximum of 20 bytes will be transferred at one time, even if ECX is
	  higher; some BIOSes (e.g. Award Modular BIOS v4.50PG) ignore the
	  value of ECX on entry, and always copy 20 bytes
	some BIOSes expect the high word of EAX to be clear on entry, i.e.
	  EAX=0000E820h
	if this function is not supported, an application should fall back
	  to AX=E802h, AX=E801h, and then AH=88h
	the BIOS is permitted to return a nonzero continuation value in EBX
	  and indicate that the end of the list has already been reached by
	  returning with CF set on the next iteration
	this function will return base memory and ISA/PCI memory contiguous
	  with base memory as normal memory ranges; it will indicate
	  chipset-defined address holes which are not in use and motherboard
	  memory-mapped devices, and all occurrences of the system BIOS as
	  reserved; standard PC address ranges will not be reported
SeeAlso: AH=C7h,AX=E801h"Phoenix",AX=E881h,MEM xxxxh:xxx0h"ACPI"

Format of Phoenix BIOS system memory map address range descriptor:
Offset	Size	Description	(Table 00580)
 00h	QWORD	base address
 08h	QWORD	length in bytes
 10h	DWORD	type of address range (see #00581)

(Table 00581)
Values for System Memory Map address type:
 01h	memory, available to OS
 02h	reserved, not available (e.g. system ROM, memory-mapped device)
 03h	ACPI Reclaim Memory (usable by OS after reading ACPI tables)
 04h	ACPI NVS Memory (OS is required to save this memory between NVS
	  sessions)
 other	not defined yet -- treat as Reserved
SeeAlso: #00580
--------b-15E881-----------------------------
INT 15 - Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS (32-bit)
	AX = E881h
Return: CF clear if successful
	    EAX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
	    EBX = extended memory above 16M, in 64K blocks
	    ECX = configured memory 1M to 16M, in K
	    EDX = configured memory above 16M, in 64K blocks
	CF set on error
Notes:	supported by AMI BIOSes dated 8/23/94 or later
	this interface is used by Windows NT 3.1, OS/2 v2.11/2.20, and is
	  used as a fall-back by newer versions if AX=E820h is not supported
SeeAlso: AX=E801h"Phoenix",AX=E820h"Phoenix"
Ich nutze solange es geht immer die neuesten und schnellsten Rechner auch für DOS. Jetzt bin ich bei 4GB Ram angekommen, sehr lange hatte ich nur 1 GB eingebaut.
Gemäß dem Motto dieses Themas soll ja DOS und im speziellen VESA auch auf neuen Rechnern ermöglicht werden und genau hierbei Versuche ich Lösungswege aufzuzeigen.
Aber OK, andererseits muß man natürlich sagen, daß es im Falle von DOS relativ egal ist, weil es ja ein Singletask-OS ist. Wenn erstmal eins Deiner Programme läuft (im UnrealMode oder in welchem Mode auch immer), wird nachträglich ja ohnehin kein anderes Programm mehr angeschissen kommen und HIMEM.SYS um Speicher anbetteln oder sowas. Damit ein anderes Programm läuft, müßte das aktuell laufende ja ohnehin beendet werden...
Genau, wer zuerst kommt darf alles machen. Das ist einer der wichtigsten Aspekte bei DOS. Mit Linux-Anwendungen und dem dortigen eingeschränten Zugriff auf die Hardware ist das nur schwer zu vergleichen.

Dirk
Zuletzt geändert von freecrac am Do 29. Apr 2010, 10:50, insgesamt 4-mal geändert.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

Schnelle Linien-Routine für lineare Vesamodi mit 256 Farben. (Kann auch leicht auf 65526 Farben(2 Byte) oder Truecolor(4 Byte) geändert werden.)

Bild http://en.wikipedia.org/wiki/Computer_graphics
A 2D projection of a 3D projection of a 4D Pentachoron performing a double rotation about two orthogonal planes.
(Created by Jason Hise with Maya and Macromedia Fireworks.)

...

Aber es geht auch anders (leider nicht mit solchen durchsichtigen Flächen), dafür aber unter purem DOS und selbst entwickelt.

Ich benutze zur Berechnung von Linien den Bresenham-Algorithmus:
http://de.wikipedia.org/wiki/Bresenham-Algorithmus

Die Subroutinen müssen in eine Anwendung die in einen lineraren Vesamode schaltet eingebettet werden.

Code: Alles auswählen

START:
; ---- In einen linearen Vesamode schalten---
; Informationen über den verwendeten Vesamode(Modinfo) nach "VINF" holen!

;-------------------------
          call Pixoff       ; Es wird einmalig eine Tabelle der Zeilenanfänge des verwendeten linearen Frambuffers angelegt.
;-------------------------

;----Hauptschleife---

          mov ebx, X1 ; Hier gültige Koordinaten für X1+Y1 und X2+Y2 eintragen.
          mov esi, Y1
          mov cx, X2
          mov di,  X2
          call LINE       ; Linie zum Bildschirm

;----Programm Ende ---
;----------------------------------------------------------------------------
;   L I N I E   Anfangspunkt: EBX, ESI   Endpunkt: CX, DI   Farbe: AL
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Alignment
;----------------------------------------------------------------------------
LINE:     mov      dx, di
          sub      cx, bx
          jl  T0
          add      ebx, [esi*4]
          sub      dx, si
          jl  T1
          mov      si, [XMP1]
          cmp      cx, dx
          jl  T2
          add      dx, dx
          mov      bp, dx
          sub      dx, cx
          mov      di, dx
          sub      dx, cx
;-------------------------------------
M00:      mov      [ebx], al
          and      di, di
          jge short M01
          inc      ebx
          add      di, bp
          dec      cx
          jnz M00
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M01:      add      ebx, esi
          add      di, dx
          dec      cx
          jnz M00
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T0:       neg      cx
          add      ebx, [esi*4]
          sub      dx, si
          mov      si, [XMP1]
          jl  T01
          mov      si, [XMM1]
          cmp      cx, dx
          jl  short T21
          add      dx, dx
          mov      bp, dx
          sub      dx, cx
          mov      di, dx
          sub      dx, cx
;-------------------------------------
M02:      mov      [ebx], al
          and      di, di
          jge short M03
          dec      ebx    
          add      di, bp
          dec      cx
          jnz M02
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M03:      add      ebx, esi
          add      di, dx
          dec      cx
          jnz M02
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T21:      add      cx, cx
          mov      bp, cx
          sub      cx, dx
          mov      di, cx
          sub      cx, dx
;-------------------------------------
M04:      mov      [ebx], al
          and      di, di
          jge short M05
          add      ebx, DWORD PTR[XMAX]
          add      di, bp
          dec      dx
          jnz M04
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M05:      add      ebx, esi
          add      di, cx
          dec      dx
          jnz M04
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T01:      neg      dx
          cmp      cx, dx
          jl  short T22
          add      dx, dx
          mov      bp, dx
          sub      dx, cx
          mov      di, dx
          sub      dx, cx
;-------------------------------------
M06:      mov      [ebx], al
          and      di, di
          jge short M07
          dec      ebx
          add      di, bp
          dec      cx
          jnz M06
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M07:      sub      ebx, esi
          add      di, dx
          dec      cx
          jnz M06
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T22:      add      cx, cx
          mov      bp, cx
          sub      cx, dx
          mov      di, cx
          sub      cx, dx
;-------------------------------------
M08:      mov      [ebx], al
          and      di, di
          jge short M09
          sub      ebx, DWORD PTR[XMAX]
          add      di, bp
          dec      dx
          jnz M08
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M09:      sub      ebx, esi
          add      di, cx
          dec      dx
          jnz M08
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T1:       neg      dx
          mov      si, [XMM1]
          cmp      cx, dx
          jl  short T12
          add      dx, dx
          mov      bp, dx
          sub      dx, cx
          mov      di, dx
          sub      dx, cx
;-------------------------------------
M10:      mov      [ebx], al
          and      di, di
          jge short M11
          inc      ebx
          add      di, bp
          dec      cx
          jnz M10
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M11:      sub      ebx, esi
          add      di, dx
          dec      cx
          jnz M10
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T12:      add      cx, cx
          mov      bp, cx
          sub      cx, dx
          mov      di, cx
          sub      cx, dx
;-------------------------------------
M12:      mov      [ebx], al
          and      di, di
          jge short M13
          sub      ebx, DWORD PTR[XMAX]
          add      di, bp
          dec      dx
          jnz M12
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M13:      sub      ebx, esi
          add      di, cx
          dec      dx
          jnz M12
          ret
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
T2:       add      cx, cx
          mov      bp, cx
          sub      cx, dx
          mov      di, cx
          sub      cx, dx
;-------------------------------------
M14:      mov      [ebx], al
          and      di, di
          jge short M15
          add      ebx, DWORD PTR[XMAX]
          add      di, bp
          dec      dx
          jnz M14
          ret
;-------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
M15:      add      ebx, esi
          add      di, cx
          dec      dx
          jnz M14
          ret
;---------------------------------------------------------------------------
;               T a b e l l e   d e r   Z e i l e n - A n f ä n g e
;---------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16
;-------------------------------------
PIXOFF:   xor      ebx, ebx
          mov      si, OFFSET VINF
          mov      bx, ds
          mov      eax, [si+28h]      ; linearen Bild-Offset
          shl      ebx, 4
          xor      di, di                 ; Pointer auf Anfang des Datensegments
          sub      eax, ebx           ; lineare Bild-Adresse (ds:reg32)

          xor      edx, edx
          mov      dx, [si+10h]       ; Zeilen-Länge holen (Xmax)
          mov     DWORD PTR[XMAX], edx
          mov      bx, dx
          inc      bx
          mov      [XMP1], bx
          sub      bx, 2
          mov      [XMM1], bx

          xor      ecx, ecx
          mov      cx, [si+14h]       ; Ymax
          shl      cx, 2              ; Max_Y * 4

AGAIN:    mov      [di], eax
          add      di, 4
          add      eax, edx           ; plus Max_X
          cmp      di, cx             ;  schon (Max_Y * 4) ?
          jb  AGAIN
          ret

;---------------------------------------------------------------------------
; Beginn des Daten-Segments
;---------------------------------------------------------------------------
PIXTAB DD 1200+16 dup (0) ; Tabelle der Zeilen-Anfänge(lineare Adressen) (max. 1200 Bildzeilen)

VINF   DB 100h dup (0)        ; Video-Mode-Information

XMAX   DD 0 ; Xmax
XMP1   DW 0 ; Xmax + 1
XMM1   DW 0 ; Xmax - 1
(Einen Geschwindigkeitsvergleichstest mit anderen Linienroutinen über "rdtsc" habe ich noch nicht vorgenommen.)

Dirk
Zuletzt geändert von freecrac am Do 29. Apr 2010, 10:07, insgesamt 10-mal geändert.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

Ich hab mir das jetzt nicht ganz durchgelesen - ich tue mich immer etwas schwer, längeren Code anderer Leute zu lesen...

Ich weiß überhaupt nicht, ob der Algo, den ich benutze, um Linien zu ziehen, überhaupt einen Namen hat. Vielleicht isses der Bresenham, vielleicht nicht. Ich weiß nicht, wie der geht. Den Algo hier hab ich mir damals selber ausgedacht.

Ich benutze zum Linienziehen ZWEI Programme, eins für Linien, die eher "waagerecht" und eins für Linien, die eher "senkrecht" sind. Dabei mache ich mir zunutze, daß Linien in einer Grafik quasi immer aus "Treppen" bestehen (außer ganz waagerechte/senkrechte Linien). Ansonsten rechne ich den "Anstieg" aus - der ist immer kleiner oder gleich 1. (Bei Anstieg 1 ist die Linie genau 45°). Diese Berechnungen erfolgen in "Festkomma", also 32bit Zahl, mit 16bit vorkomma, 16bit Nachkomma.
Und dann kommt das: Wenn Linie "eher waagerecht", wird Y immer um 1 erhöht und X immer um den Anstieg (der auch negativ sein kann). Wenn Linie "eher senkrecht", wird X immer um 1 erhöht und Y immer um den Anstieg (der auch negativ sein kann). Ich tausche vorher die Koordinaten um, damit ich Linien immer nur "von oben nach unten" oder "von links nach rechts" zeichnen muß...
Man kann das Ganze natürlich noch toppen, indem man bei "waagerechten" Linien den Anstieg mit der Scanline multipliziert und bei "senkrechten" Linien den "Y-Adder" (also die 1) in die Scanline ändert.
Und man kann dann eben entweder eine generalisierte Pixelroutine benutzen (das ist im ersten Fall) - also immer Pixel(X,Y,Farbe)
oder, wenn man das mit den Scanlines macht, kann man auch gleich die richtige Adresse im Grafikspeicher benutzen und dort die Farbbytes reinschreiben.

Man sollte noch vorher abfangen, wenn die Linie ganz oder teilweise außerhalb der Bildschirmkoordinaten liegt - und die Koordinaten entsprechend anpassen (bis zum Bildrand)...

Naja, und so weiter...
elianda
DOS-Übermensch
Beiträge: 1150
Registriert: Mi 31. Jan 2007, 19:04
Wohnort: Halle
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von elianda »

Das interessante am Bresenham ist, dass es bewiesen ist, dass es der schnellste Algorithmus ist. Im Prinzip wird da vollständig auf Gleitkommaberechnung verzichtet, denn das Problem des Anstiegs kann man gerade beim Linienziehen vollständig durch Ganzzahlberechnung ersetzen.
Angenommen du hast eine Linie, die einen leichten Anstieg in Y hat. Dann ist von den Koordinaten (Y2-Y1) < (X2-X1), wenn man für X2 und Y2 jeweils die größeren Koordinaten nimmt.
Die Idee ist nun, dass man über den Weg der längeren Achse, also in dem Fall X eine Schleife laufen lässt und im richtigen Moment Y erhöht. Dazu kommt eine Hilfsvariable zum Einsatz, die mit 0 initialisiert wird.

Für jeden Schritt in X addiert man dY auf die Hilfsvariable, wenn die Hilfsvariable größer als dX wird, dann geht man einen Schritt in Y und subtrahiert dX von der Hilfsvariable. Das ganze läuft dann bis man bei X2 ankommt.

Je nach dX:dY Verhältnis kann auch Y die Laufvariable sein und ggf. subtrahiert, statt zu addieren.

Je nach Speicherlayout kann man dies noch geschickt anpassen, z.B. um Schreibzugriffe auf den Grafikkartenspeicher zu minimieren.
Diverse Retro-Computer vorhanden.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

Das klingt ja im Prinzip wie das, was ich mache. Da hatte ich wohl dieselbe Idee wie Herr Bresenham.
Ich benutze ja auch kein Gleitkomma, hab ich ja gesagt. Mit "Festkomma" meine ich ja Integer.
Ich benutze 32bit Integers, von denen die oberen 16bit dem "Vorkomma" entsprechen und die unteren 16bit dem "Nachkomma". Dieses "Nachkomma" wird ja nicht dargestellt (auf die Grafik kommt nur das, was im Vorkomma steht) - das "Nachkomma-Word" dient nur der Genauigkeit.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

DOSferatu hat geschrieben:Das klingt ja im Prinzip wie das, was ich mache. Da hatte ich wohl dieselbe Idee wie Herr Bresenham.
Ich benutze ja auch kein Gleitkomma, hab ich ja gesagt. Mit "Festkomma" meine ich ja Integer.
Ich benutze 32bit Integers, von denen die oberen 16bit dem "Vorkomma" entsprechen und die unteren 16bit dem "Nachkomma". Dieses "Nachkomma" wird ja nicht dargestellt (auf die Grafik kommt nur das, was im Vorkomma steht) - das "Nachkomma-Word" dient nur der Genauigkeit.
Meine Routine benutzt nur eine 16Bit-Genauigkeit. Die Spalten von" Xmax", "Xmax + 1" und "Xmax - 1" passen immer in ein 16Bit-Register. Für die 4GB-Adresse des Framebuffers wird jedoch ein 32Bit-Register benötigt um damit die Adressen der Zeilen aufzunehmen. Die Adressen der Zeilen werden einmalig vorweg in einer zweiten Routine berechnet und in einer Tabelle der Zeilenanfänge am Anfang des Datensegments abgelegt. Die jeweilige Y-Koordinate wird dann mit 4 multipliziert und dient dann als Zeiger innerhalb dieser Tabelle um die dortige 32Bit-Adresse der der Zeile jeweils herauszuholen. Zusammen addiert mit der X-Koorrdinate ergibt sich dann daraus die tatsächliche Adresse des Pixels innerhalb des Framebuffers.

Für eine vergleichbare Linienroutine die nur nach 0A0000h schreibt wären 16Bit-Register damit groß genug und völlig ausreichend.

Dirk
Zuletzt geändert von freecrac am Do 29. Apr 2010, 11:57, insgesamt 4-mal geändert.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

DOSferatu hat geschrieben:Ich hab mir das jetzt nicht ganz durchgelesen - ich tue mich immer etwas schwer, längeren Code anderer Leute zu lesen...
In diesen kleinen Fenster wo der Code enthalten ist kann ich nicht mal den Syntax meiner eigenen Routinen verfolgen. Ich empfehle den Inhalt herauszukopieren um ihn als Ganzes betrachten zu können.
Man sollte noch vorher abfangen, wenn die Linie ganz oder teilweise außerhalb der Bildschirmkoordinaten liegt - und die Koordinaten entsprechend anpassen (bis zum Bildrand)...
Uff stimmt, die Anfangskoordinaten werden in meiner Linienroutine nicht auf Gültigkeit überprüft.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

elianda hat geschrieben:Je nach Speicherlayout kann man dies noch geschickt anpassen, z.B. um Schreibzugriffe auf den Grafikkartenspeicher zu minimieren.
Das man Lesezugriffe auf den Grafikkartenspeicher möglichst vermeiden sollte wäre hierbei auch noch zu erwähnen. Lesezugriffe gestalten sich noch weitaus langsamer als Schreibzugriffe.

Anfänglich habe ich für eine Überblendroutine, wo ein Bild über die jeweiligen RGB-Farbwerte der Pixel stufenweise über ein anderes Bild eingeblendet wird, mit Lesezugriffe auf den Grafikkartenspeicher realisiert. Davon bin ich aber schnell wieder abgekommen und benutze nun lieber dafür reservierte Bereiche im Ram. Wenn eine Blendstufe(%-Atlbild + %-Neubild) fertig berechnet ist wird der betreffende Bereich in einem Stück in den Grafikkartenspeicher kopiert. Um geringfügige Abweichungen vom Zielbild am Ende der vollendeten Überblendung auszugleichen kopiere ich das Zielbild danach anschliessend noch einmal komplett zum Grafikkartenspeicher. Bevor die Überblendung beginnt wird vom Zielbild z.B 10% alle Farbwerte berechnet und als Blendstufe verwendet.

Dirk
Zuletzt geändert von freecrac am Do 29. Apr 2010, 15:12, insgesamt 1-mal geändert.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

@freecrac: So eine Tabelle mit Zeilenanfängen habe ich ebenfalls seit Jahren in meinen Grafik-Units.
Und meine neuere Unit, die 8it, 15bit, 16bit, 24bit und 32bit Grafik darstellen kann, benutzt als Bildbuffer den XMS. Ich habe dort auch so "Überblende" Dinge eingebaut - d.h. man kann mit 32bit Farben zeichnen, die unteren 3 Byte sind Blau,Grün,Rot - das oberste Byte ist "Alpha", also die Transparenz der Farbe, wobei bei mir 0=undurchsichtig und 255=maximale Transparenz ist. Wenn man in anderen Modi als 24bit/32bit zeichnet, wird das bei der Ausgabe heruntergerechnet - intern arbeitet das ganze Ding immer mit 32bit Farben. Ich habe dazu spezielle Subroutinen für jede der 5 Farbtiefen, die entsprechend zugewiesen werden, je nachdem, welchen Modus man einschaltet...

Und ja - in manchen Sachen, die ich programmiere, lese ich auch mal den Grafikspeicher aus. Ich weiß, daß das zwar langsamer ist als schreiben, aber wenn ich z.B. so etwas wie einen Mauspfeil benutze, rette ich eben dieses winzige Stück Grafik unterhalb des Mauszeigers in einen Puffer.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

DOSferatu hat geschrieben:@freecrac: So eine Tabelle mit Zeilenanfängen habe ich ebenfalls seit Jahren in meinen Grafik-Units.
Beginnend mit der Programmierung in Assembler auf dem C64er waren dort Fließpunktberechnungen ohne FPU extrem langsam so das sich so eine vorher berechnete Tabelle immer anbot wenn es schnell gehen sollte.
Heute Frage ich mich jedoch ob der relativ langsame Speichtzugriff auf die Tabelle nicht lagsamer ist als eine direckte Berechnung mit der FPU auch wenn es schnell gehen soll. Ich habe hier auch noch eine Integer-Sinustabelle in der Sammlung die dann bei Bedarf nachgeladen werden kann.
Und meine neuere Unit, die 8it, 15bit, 16bit, 24bit und 32bit Grafik darstellen kann, benutzt als Bildbuffer den XMS. Ich habe dort auch so "Überblende" Dinge eingebaut - d.h. man kann mit 32bit Farben zeichnen, die unteren 3 Byte sind Blau,Grün,Rot - das oberste Byte ist "Alpha", also die Transparenz der Farbe, wobei bei mir 0=undurchsichtig und 255=maximale Transparenz ist. Wenn man in anderen Modi als 24bit/32bit zeichnet, wird das bei der Ausgabe heruntergerechnet - intern arbeitet das ganze Ding immer mit 32bit Farben. Ich habe dazu spezielle Subroutinen für jede der 5 Farbtiefen, die entsprechend zugewiesen werden, je nachdem, welchen Modus man einschaltet...
Was meinst du genau mit 5 Farbtiefen?
Und ja - in manchen Sachen, die ich programmiere, lese ich auch mal den Grafikspeicher aus. Ich weiß, daß das zwar langsamer ist als schreiben, aber wenn ich z.B. so etwas wie einen Mauspfeil benutze, rette ich eben dieses winzige Stück Grafik unterhalb des Mauszeigers in einen Puffer.
Für einen kleinen Mouszeiger genügt das bestimmt.

Anmerkung:
Ich habe in meinem Vorstellungs-Beitrag neben dem Beispiel einer Tastaturabfrage auch noch ein Beispiel für eine PS2-Mousabfrage hinzugefügt.
http://www.dosforum.de/viewtopic.php?f= ... 163#p15163
Wie ich dort auch schon erwähnt habe kann ein damit verwendeter Mousezeiger beliebige Ausmaße und Formen besitzen und in einem 24Bit-Targa-Bild mit schwarzen Hintergrund bereitgestellt und verwendet werden.
Um die Mousezeiger-Routine etwas zu beschleunigen habe ich dort MMX-Befehle/Register für die Lese/Schreib-Operationen verwendet um die SIMD- und die Integer-Unit paralell zu benutzen. Das brachte schon sichtbare Erfolge.
(Das Laden des Targa-Bildes und das Aufbereiten zu einem Mouszeigers ist dort allerdings nicht im Beispiel enthalten, damit das Beispiel möglichst klein bleibt und damit hoffentlich etwas leichter zu verstehen ist.)

Wenn jedoch große Bereiche des Bildes fortlaufend flicker und ruckelfrei verändert werden sollen eignet sich Vesa hardware triple buffering. Die gewöhnliche Methode nur das Ende des Rasterstrahls abzufragen um dann im Grafikkartenspeicher die Änderungen direckt vorzunehmen stößt hier schnell an seine Grenzen. Schnell bewegte Objekte verschwinden im oberen Bildbereich und werden dort gar nicht mehr angezeigt, wenn unser Schreibvorgang zu lange dauert bis der nächste Rasterstrahl das Bild erneut zur Anzeige bringt. Mit dem triple buffering haben wir qausi drei komplette Bilder die wir zyklisch im Wechsel beschreiben müssen.

Für das Überblenden von einem Bild zu einem anderen Bild genügt es aber auch das Bild jeweils im Ram aufzubereiten und wenn fertig zum 'Grafikkartenspeicher zu kopieren.
(Getestet mit AMDK6-2@550mhz/MatroxMILL2(PCI,4MB) und Targa-Bildbetrachter unter Linux gebootet mit Framebuffer-Device(fb0) in 1024x768x32.)

Dirk
Zuletzt geändert von freecrac am Do 29. Apr 2010, 16:50, insgesamt 1-mal geändert.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

freecrac hat geschrieben:Was meinst du genau mit 5 Farbtiefen?
Na 8bit, 15bit, 16bit, 24bit und 32bit.
Obwohl 32bit und 24bit ja optisch gleich aussehen (nur in der Speicheranordnung besteht eben ein Unterschied). Weil auf den Grafikkarten bei 32bit ja nur die unteren 24bit für die Farben benutzt werden. Habe noch keine erlebt, wo es dann wirklich 32bit Farben waren (z.B. 1024 oder 2048 Stufen je Farbphase oder sowas).
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von freecrac »

DOSferatu hat geschrieben:
freecrac hat geschrieben:Was meinst du genau mit 5 Farbtiefen?
Na 8bit, 15bit, 16bit, 24bit und 32bit.
Obwohl 32bit und 24bit ja optisch gleich aussehen (nur in der Speicheranordnung besteht eben ein Unterschied). Weil auf den Grafikkarten bei 32bit ja nur die unteren 24bit für die Farben benutzt werden. Habe noch keine erlebt, wo es dann wirklich 32bit Farben waren (z.B. 1024 oder 2048 Stufen je Farbphase oder sowas).
Ach so, diese 5 Farbtiefen meinst du.

Ich glaube das im 3D-Mode zur Berechnung der Farben dort intern schon mehr als 8 Bits je Farbkanal von der GPU verwendet werden. Meine mathematischen Fähigkeiten würde ich aber als zu gering bezeichnen um vergleichbare Berechnungen vornehmen zu können. Bei Mathe kämpfe ich immer mit meinem Brett vor dem Kopf. Ein räumliches Vorstellungsvermögen habe ich auch noch nicht kennengelernt, was ist das überhaupt und wie kann man das besser kennenlernen?

Dirk
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von DOSferatu »

Diese 3-dimensionale räumliche Welt gibt es z.B, in diesem sogenannten "Draußen", von dem ich mal gehört habe. Das ist da, wo der Pizzabote herkommt. Ich war mal da - war aber langweilig, da bin ich wieder gegangen.
drzeissler
DOS-Gott
Beiträge: 3336
Registriert: Mo 8. Feb 2010, 16:59

Re: Probleme mit VESA auf neuen Rechnern.

Beitrag von drzeissler »

*ausgrab*

Dann mal eine Frage an die Experten: Welche neuere Grafikkarte (AGP4x/8x)unterstützt unter DOS die VESA Modes noch.
- Wie sieht es da bei ATI 9600/9800 aus ?

Im Moment habe ich eine GF6200A AGP verbaut, da ist der Dos-Vesa Support recht gut (Vesa 30)

Danke und Gruß
Doc
CPU: 486 DX2/66 MOBO: SNI-D882 RAM: 3x16MB - FDD: 3,5" 1,44MB HDD: 6,4GB Seagate ISA(1): Audican32Plus PCI(1): 3com TX 905 OS: MsDos622 - Win95a - WinNT 3.51
Antworten