TUI programmieren [C]

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

lol!

Jetzt schreibe ich viele Zeilen rein und TurboC++ kackt ab, weil die Datei zu lang ist...
das nervt xD
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:lol!

Jetzt schreibe ich viele Zeilen rein und TurboC++ kackt ab, weil die Datei zu lang ist...
das nervt xD
Das ist überaus ärgerlich. :-(
Meine Idee dazu ist es den Source-Code in zwei verschiedene Teile aufzuspalten und getrennt zu kompilieren, so das der zweite Teil von dem ersten Teil nachgeladen wird.
Möglicherweise genügt es nur den Datenbereich vom Code abzutrennen, so das nur die Daten von der Anwendung nachgeladen werden.
Sonst muss eben innerhalb der Anwendung ein zweites Programm gestartet werden um diesen Teil auch ausführen zu können.
Oder man überschreibt einen nicht mehr benötigten Codebereich der ersten Anwendung mit weiteren Opcodes die nachgeladen werden.

Vorher würde ich es allerdings versuchen den gesamten Source-Code von überflüssigen Dingen zu befreien und es dann noch einmal so zu probieren.
(Eine Kopie mit Kommentaren kann man ja behalten, um sich auch später wieder zu recht zu finden.)

Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ich werde es so machen:
Ich trenne den Header in ne .H und ne .C Datei. Der Header enthält dann die Deklarationen und Definitionen und der Sourc-Code in der .C-Datei den eigentichen Code. Wenn das nicht klappt, werde ich versuchen einige Sachen zu "komprimieren". Deine Antwort verstehe ich inhaltlich nicht, was wahrscheinlich daran liegt, dass ich mich mit assembler nicht soooo gut auskenne. Wenn die oben beschriebenen Maßnahmen keinen Erfolg aufweise kompilier ich das halt mit OpenWatcom auf meinem anderen PC. Das müsste dann klappen.

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

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Ich werde es so machen:Deine Antwort verstehe ich inhaltlich nicht, was wahrscheinlich daran liegt, dass ich mich mit assembler nicht soooo gut auskenne.
mfg
Ok, dann versuche ich es mal etwas näher zu erklären. Leider habe ich von C nur wenig Ahnung und so kann ich das Vorgehen nur anhand eines Assembler-Beispiels zeigen.

Ein Möglichkeit besteht darin einen Datenbereich zu laden. Hierfür müssen ggf. einige Änderungen im Codebereich vorgenommen werden und eine Möglichkeit eingebaut werden um Daten nachzuladen.
Wenn im Codebereich relative Adressangaben vorhanden sind die sich auf bestimmte Stellen im Datenbereich beziehen, dann gehen diese möglicherweise verloren.

Angenommen Im Codebereich befinden sich solche relativen Adressangaben die mit einem Label versehen sind um einen Bezug auf bestimmte Stellen im Datenbereich zu bekommen.
Unser Codebereich:
mov ax, Daten ; Adresse des Datensegments
mov ds, ax
mov si, OFFSET TABELLE1
mov di, OFFSET TABELLE2

Und in unserem Datenbereich(Segment-Anfang) sind bestimmte Bereiche so deklariert:
TABELLE1 DB 8 dup (88h) ; Hier wird ein Bereich von 8 Bytes reserviert
TABELLE2 DB 8 dup (44h) ; und hier auch

...

Wenn man nun das ganze assembliert, dann kommt letzendlcih so etwas dabei heraus:
mov si, 0 ; Die obere relative Adressangabe wird zu einer fixen Adressangabe
mov di, 8 ; hier auch
Datenbereich:
DB 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h
DB 44h, 44h, 44h, 44h, 44h, 44h, 44h, 44h

Wenn man nun diese Bytes im Datenbereich in eine gesonderte Datei speichert, dann kann man sie zur Laufzeit der Anwendung nachladen.
Durch die fixen Adressangaben im Codebereich erhält man aber trotzdem einen Zeiger auf die beiden Tabellen.
Die erste Tabelle im Datenbereich beginnt bei OFFSET 0 und die zweite TABELLE beginnt bei OFFSET 8.

...

Nun muss der Datenbereich zunächst in eine gesonderte Datei gespeichert werden.
Dafür trennen wir den Datenbereich von unserer Anwendung ab und schreiben ihn in eine neue Quelldatei und fügen dort in den Codebereich nur die Befehle ein, um den Datenbereich in eine gesonderte Datei zu speichern:
Unser Codebereich dafür:
mov ax, Daten
mov ds, ax
mov ah, 3Ch ; Datei erstellen
mov dx, OFFSET FILENAME
mov cx, 0 ; Datei Atribut
int 21h
mov bx, ax ; Datei-Handle
mov ah, 40h ; Datei beschreiben
mov dx, OFFSET TABELLE1
mov cx, Anzahl ; Anzahl Bytes
int 21h
mov ah, 3Eh ; Datei schliessen
int 21h

Unser Datenbereich:
TABELLE1 DB 8 dup (88h) ; Hier wird ein Bereich von 8 Bytes reserviert
TABELLE2 DB 8 dup (44h) ; und hier auch
Anzahl = ($-TABELLE1) ; Länge beider Tabellen ermitteln
FILENAME DB "DATEN.TAB", 0

Code: Alles auswählen

RBIL->inter61b.zip->INTERRUP.F
--------D-213C-------------------------------
INT 21 - DOS 2+ - "CREAT" - CREATE OR TRUNCATE FILE
	AH = 3Ch
	CX = file attributes (see #01401)
	DS:DX -> ASCIZ filename
Return: CF clear if successful
	    AX = file handle
	CF set on error
	    AX = error code (03h,04h,05h) (see #01680 at AH=59h/BX=0000h)
Notes:	if a file with the given name exists, it is truncated to zero length
	under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
	DR DOS checks the system password or explicitly supplied password at
	  the end of the filename against the reserved field in the directory
	  entry before allowing access
SeeAlso: AH=16h,AH=3Dh,AH=5Ah,AH=5Bh,AH=93h,INT 2F/AX=1117h

Bitfields for file attributes:
Bit(s)	Description	(Table 01401)
 0	read-only
 1	hidden
 2	system
 3	volume label (ignored)
 4	reserved, must be zero (directory)
 5	archive bit
 7	if set, file is shareable under Novell NetWare
--------D-2140-------------------------------
INT 21 - DOS 2+ - "WRITE" - WRITE TO FILE OR DEVICE
	AH = 40h
	BX = file handle
	CX = number of bytes to write
	DS:DX -> data to write
Return: CF clear if successful
	    AX = number of bytes actually written
	CF set on error
	    AX = error code (05h,06h) (see #01680 at AH=59h/BX=0000h)
Notes:	if CX is zero, no data is written, and the file is truncated or
	  extended to the current position
	data is written beginning at the current file position, and the file
	  position is updated after a successful write
	for FAT32 drives, the file must have been opened with AX=6C00h with
	  the "extended size" flag in order to expand the file beyond 2GB;
	  otherwise the write will fail with error code 0005h (access denied)
	the usual cause for AX < CX on return is a full disk
BUG:	a write of zero bytes will appear to succeed when it actually failed
	  if the write is extending the file and there is not enough disk
	  space for the expanded file (DOS 5.0-6.0); one should therefore check
	  whether the file was in fact extended by seeking to 0 bytes from
	  the end of the file (INT 21/AX=4202h/CX=0000h/DX=0000h)
	under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
SeeAlso: AH=28h,AH=3Fh"DOS",AH=93h,INT 2F/AX=1109h
--------D-213E-------------------------------
INT 21 - DOS 2+ - "CLOSE" - CLOSE FILE
	AH = 3Eh
	BX = file handle
Return: CF clear if successful
	    AX destroyed
	CF set on error
	    AX = error code (06h) (see #01680 at AH=59h/BX=0000h)
Notes:	if the file was written to, any pending disk writes are performed, the
	  time and date stamps are set to the current time, and the directory
	  entry is updated
	recent versions of DOS preserve AH because some versions of Multiplan
	  had a bug which depended on AH being preserved
SeeAlso: AH=10h,AH=3Ch,AH=3Dh,INT 2F/AX=1106h,INT 2F/AX=1227h
Im Sourcecode unserer Anwendung haben wir den Datenbereich nur reserviert aber keine Dekleration mehr für bestimmte Bereiche. Hier müssen wir jetzt dafür im Codebereich die Befehle ergänzen um Daten nachzuladen.

Unser Codebereich:
mov ax, DATEN
mov ds, ax
mov ah, 3Dh ; Datei öffnen
mov dx, OFFSET FILENAME
mov al, 0 ; nur lesen
int 21h
mov bx, ax ; Datei-Handle
mov ah, 3Fh ; Datei lesen
mov dx, 0 ; Anfang des Datenbereichs
mov cx, 16 ; Länge der Datei
int 21h
mov ah, 3Eh ; Datei schliessen
int 21h

Unser Datenbereich:
DB 16 dup (88h) ; Hier wird nun ein Bereich für beide Tabellen reserviert
FILENAME DB "DATEN.TAB", 0

Code: Alles auswählen

RBIL->inter61b.zip->INTERRUP.F
--------D-213D-------------------------------
INT 21 - DOS 2+ - "OPEN" - OPEN EXISTING FILE
	AH = 3Dh
	AL = access and sharing modes (see #01402)
	DS:DX -> ASCIZ filename
	CL = attribute mask of files to look for (server call only)
Return: CF clear if successful
	    AX = file handle
	CF set on error
	    AX = error code (01h,02h,03h,04h,05h,0Ch,56h) (see #01680 at AH=59h)
Notes:	file pointer is set to start of file
	if SHARE or a network is loaded, the file open may fail if the file
	  is already open, depending on the combination of sharing modes
	  (see #01403,#01404)
	file handles which are inherited from a parent also inherit sharing
	  and access restrictions
	files may be opened even if given the hidden or system attributes
	under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
	DR DOS checks the system password or explicitly supplied password at
	  the end of the filename (following a semicolon) against the reserved
	  field in the directory entry before allowing access
	sharing modes are only effective on local drives if SHARE is loaded
BUG:	Novell DOS 7 SHARE v1.00 would refuse file access in the cases in
	  #01403 marked with [1] (read-only open of a read-only file
	  which had previously been opened in compatibility mode); this was
	  fixed in SHARE v1.01 of 09/29/94
SeeAlso: AH=0Fh,AH=3Ch,AX=4301h,AX=5D00h,INT 2F/AX=1116h,INT 2F/AX=1226h

Bitfields for access and sharing modes:
Bit(s)	Description	(Table 01402)
 2-0	access mode
	000 read only
	001 write only
	010 read/write
	011 (DOS 5+ internal) passed to redirector on EXEC to allow
		case-sensitive filenames
 3	reserved (0)
 6-4	sharing mode (DOS 3.0+) (see #01403)
	000 compatibility mode
	001 "DENYALL" prohibit both read and write access by others
	010 "DENYWRITE" prohibit write access by others
	011 "DENYREAD" prohibit read access by others
	100 "DENYNONE" allow full access by others
	111 network FCB (only available during server call)
 7	inheritance
	if set, file is private to current process and will not be inherited
	  by child processes
SeeAlso: #01782,#01403

(Table 01403)
Values of DOS 2-6.22 file sharing behavior:
	  |	Second and subsequent Opens
 First	  |Compat  Deny	  Deny	 Deny	Deny
 Open	  |	   All	  Write	 Read	None
	  |R W RW R W RW R W RW R W RW R W RW
 - - - - -| - - - - - - - - - - - - - - - - -
 Compat R |Y Y Y  N N N	 1 N N	N N N  1 N N
	W |Y Y Y  N N N	 N N N	N N N  N N N
	RW|Y Y Y  N N N	 N N N	N N N  N N N
 - - - - -|
 Deny	R |C C C  N N N	 N N N	N N N  N N N
 All	W |C C C  N N N	 N N N	N N N  N N N
	RW|C C C  N N N	 N N N	N N N  N N N
 - - - - -|
 Deny	R |2 C C  N N N	 Y N N	N N N  Y N N
 Write	W |C C C  N N N	 N N N	Y N N  Y N N
	RW|C C C  N N N	 N N N	N N N  Y N N
 - - - - -|
 Deny	R |C C C  N N N	 N Y N	N N N  N Y N
 Read	W |C C C  N N N	 N N N	N Y N  N Y N
	RW|C C C  N N N	 N N N	N N N  N Y N
 - - - - -|
 Deny	R |2 C C  N N N	 Y Y Y	N N N  Y Y Y
 None	W |C C C  N N N	 N N N	Y Y Y  Y Y Y
	RW|C C C  N N N	 N N N	N N N  Y Y Y
Legend: Y = open succeeds, N = open fails with error code 05h
	C = open fails, INT 24 generated
	1 = open succeeds if file read-only, else fails with error code
	2 = open succeeds if file read-only, else fails with INT 24
SeeAlso: #01636,#01404

(Table 01404)
Values for DOS 7.x file sharing behavior:
	  |	Second and subsequent Opens
 First	  |Compat    Deny      Deny	 Deny	   Deny
 Open	  |	     All       Write	 Read	   None
	  |R W RW A  R W RW A  R W RW A	 R W RW A  R W RW A
 - - - - -| - - - - - - - - - - - - - - - - - - - - - - - -
 Compat R |Y Y Y Y   N N N N   Y N N Y	 N N N Y   Y N N Y
	W |Y Y Y C   N N N N   N N N N	 N N N Y   Y N N Y
	RW|Y Y Y C   N N N N   N N N N	 N N N Y   Y N N Y
	NA|Y C C Y   N N N N   Y N N Y	 N N N Y   Y N N Y
 - - - - -|
 Deny	R |C C C C   N N N N   N N N N	 N N N N   N N N N
 All	W |C C C C   N N N N   N N N N	 N N N N   N N N N
	RW|C C C C   N N N N   N N N N	 N N N N   N N N N
	NA|C C C C   N N N N   N N N N	 N N N N   N N N N
 - - - - -|
 Deny	R |Y C C Y   N N N N   Y N N Y	 N N N Y   Y N N Y
 Write	W |C C C C   N N N N   N N N N	 Y N N Y   Y N N Y
	RW|C C C C   N N N N   N N N N	 N N N Y   Y N N Y
	NA|Y C C Y   N N N N   Y N N Y	 N N N Y   Y N N Y
 - - - - -|
 Deny	R |C C C C   N N N N   N Y N N	 N N N N   N Y N N
 Read	W |C C C C   N N N N   N N N N	 N Y N N   N Y N N
	RW|C C C C   N N N N   N N N N	 N N N N   N Y N N
	NA|Y Y Y Y   N N N N   Y Y Y Y	 N N N Y   Y Y Y Y
 - - - - -|
 Deny	R |Y Y Y Y   N N N N   Y Y Y Y	 N N N Y   Y Y Y Y
 None	W |C C C C   N N N N   N N N N	 Y Y Y Y   Y Y Y Y
	RW|C C C C   N N N N   N N N N	 N N N Y   Y Y Y Y
	NA|Y Y Y Y   N N N N   Y Y Y Y	 N N N Y   Y Y Y Y
Legend: R -> reading, W -> writing, RW -> both reading & writing,
	A/NA -> reading without access time update
	Y = open succeeds, N = open fails with error code 05h
	C = open fails, INT 24 generated
SeeAlso: #01403,#01636
--------D-213F-------------------------------
INT 21 - DOS 2+ - "READ" - READ FROM FILE OR DEVICE
	AH = 3Fh
	BX = file handle
	CX = number of bytes to read
	DS:DX -> buffer for data
Return: CF clear if successful
	    AX = number of bytes actually read (0 if at EOF before call)
	CF set on error
	    AX = error code (05h,06h) (see #01680 at AH=59h/BX=0000h)
Notes:	data is read beginning at current file position, and the file position
	  is updated after a successful read
	the returned AX may be smaller than the request in CX if a partial
	  read occurred
	if reading from CON, read stops at first CR
	under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
BUG:	Novell NETX.EXE v3.26 and 3.31 do not set CF if the read fails due to
	  a record lock (see AH=5Ch), though it does return AX=0005h; this
	  has been documented by Novell
SeeAlso: AH=27h,AH=40h,AH=93h,INT 2F/AX=1108h,INT 2F/AX=1229h
--------D-213E-------------------------------
INT 21 - DOS 2+ - "CLOSE" - CLOSE FILE
	AH = 3Eh
	BX = file handle
Return: CF clear if successful
	    AX destroyed
	CF set on error
	    AX = error code (06h) (see #01680 at AH=59h/BX=0000h)
Notes:	if the file was written to, any pending disk writes are performed, the
	  time and date stamps are set to the current time, and the directory
	  entry is updated
	recent versions of DOS preserve AH because some versions of Multiplan
	  had a bug which depended on AH being preserved
SeeAlso: AH=10h,AH=3Ch,AH=3Dh,INT 2F/AX=1106h,INT 2F/AX=1227h
Eine weiter Möglichkeit mit ähnlicher Vorgehensweise besteht darin zur Laufzeit unserer Anwendung Speicher von DOS anzufordern, um dort hinein unsere Daten zu laden.
So können wir auf das Reservieren der Tabellen im Datenbereich völlig verzichten, so das unsere Anwendung selber kleiner wird.
So bekommt das Nachladen unserer Daten auch einen Sinn, denn sonst könnte man einfach nur einen Bereich für beide Tabellen zusammen im Datenbereich reservieren,
wobei nur die Adressbezüge zu den Tabellen verloren gehen, wenn man anstelle von relativen Adressangaben mit Label verzichtet und dafür fixe Adressen im Codebereich verwendet die auf die Tabellen zeigen.
(Aber auch das würde unseren Quellcode ja schon kleiner machen.)

Beim Anfordern von Speicher erhalten wir dadurch eine Segmentadresse wohin wir unsere Daten laden können. Das DS-Segmentregister muss dafür vor dem "Datei lesen" auf dieses angeforderte Segment gelegt werden.
Da dieser Beitrag jedoch schon etwas länger ist lasse ich das aber mal weg.

...

Auch die anderen von mir angesprochene Möglichkeiten den Codebereich mit neuen Opcodes aus einer anderen Datei zu überschreiben
und auch die Möglichkeit eine zweite Anwendung aus der Anwendung heraus zu starten (wie es z.B. auch der Norten Commander macht) lasse ich hier mal unberücksichtigt.
Ggf. kann ich das in einem neuen Beitrag genauer aufzeigen.

Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Jetzt habe ich verstanden was du meinst.
Das brauch ich bei C glaube ich nicht tun, denn da muss ich nur nen Header schreiben und schwubbs hab ich zwei getrennte sourcecodes. Denn das ist das, was ich brauche, denn ich möchte den C-Code für alle lesbar halten und diese spizelle ASM-Methodik ist bei C-Porgrammierern wahrscheinlich nicht so bekannt.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

So ich habe jetzt meine Header aufgespalten:

vorher:
TUI.H der header mit allen funktionen etc.
TUIIO.H der header der mit erweiterte maus und keyboard funktionen anbieten (isKeyPressed() etc.)
nachher
ERRORCOD.H enthält definitionen für errorcodes (NOT_ENOUGH_RAM etc. werden zahlen zugeordnet)
STDTYPES.H enthält definitionen wie byte = unsigned char und word = unsigned short usw.
ASCIIVID.H enthält funktionen die nötig sind um rechtecke zu zeichnen oder rahmen und sowas halt
TUIIO.H s.o.
TUI.H enthält nur noch für die TUI wichtiges funktionen

jetzt klappt das kompilieren schon schneller. und es gibt (noch) keine fehler.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ein Bug gesichtet:
Eine Variable deklariert, aber keinen Wert zugewiesen

Ist echt erstaunlich oft, dass man so auf die sachen fixiert ist, da man denkt, dort müsse der Fehler sein, dann aber rausfindet, dass er in den kleinen Aspekten ist.
Wie so oft steckt der Teufel im Detail =)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Hey jetzt geht es gut voran.
Ich kann schon in die textarea reinschreiben und der Text erscheint wo er soll.
Jetzt muss ich noch ein paar kinderkrankheiten ausmerzen, wie z.B. dass der Text mitscrollt und dann müsste es bestimmt bald gehen. Wenn ich die Textareas fertig habe, könnte ich ja vllt. eine DOS-Variante für CardFile programmieren. Wer das Programm aus Win3.11 kennt, wird verstehen, warum ich grade das ausgewählt habe. Wer noch leichtere Beispiele für ein erstes Programm hat, bei dem ich keine Dateispezifikationen durchlesen muss, kann es mir gerne mitteilen. Das programmm sollte möglichst wenig können, wenig fenster brauchen und am besten auch nicht viel mit dateien am hut haben.

Wo ich drüber rede... ich glaube ich mach einen Copy-Aufsatz mit chicken Ladebalden.

Meine Motivation so viel an der TUI zu arbeiten war übrigens, dass ich den sourcecode auf ne rote Diskette kopiert habe. Ich kann nicht erklären warum, aber externe Datenträger regen mich immer dazu an, irgendwas zu programmieren xD xD

ich bedanke mich hier nochmal ganz herzlich für euren bisherigen Beistand.

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

Re: TUI programmieren [C]

Beitrag von DOSferatu »

Wenn sich's bei dem externen Datenträger um 'ne Diskette handelt, regt mich persönlich das eher immer an, die darauf enthaltenen Daten schnellstens woanders hin zu sichern...
Vor allem, wenn's wichtige Daten sind...
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Aber auf ner floppy halten daten eig. schon ein paar jährchen.
Benutzeravatar
Shockwav3
DOS-Übermensch
Beiträge: 1381
Registriert: Mi 9. Mai 2007, 16:42
Wohnort: Berlin XBerg

Re: TUI programmieren [C]

Beitrag von Shockwav3 »

oDOSseus hat geschrieben:Aber auf ner floppy halten daten eig. schon ein paar jährchen.
Betonung auf eigentlich. Effektiv sind die meisten 3.5" HD Medien inzwischen so ausgelutscht, dass 50% aller Medien in meinem Fundus mindestens 1 Sektorfehler haben ... und das trotz artgerechter Haltung.
Aber blah, wollt die Tage dazu nochmal nen eigenen Thread aufmachen.
Hauptsystem: Asus VL/I-486SV2GX4, DX2 @ 66MHz, 1MB L2 Cache, 64MB RAM, 1GB CF HDD, Cirrus Logic 5428 VLB, ARGUS Prototype Rev. 02 #0, umschaltbarer Covox/DSS-DAC, 2x LPT, DOS 6.22 + Win 3.11
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ich hätte da grad ma ne frage an die, die C und ASM können.
Ich wollte die Funktionen, die in den RAM-Bereich des VideoModes reinschreiben in ASM schreiben. das klappte auch
aber nur 1,2 mal, danach versagte die Funktion.
Ich glaube, es liegt daran, dass ich den Pointer nicht richtig in ASM benutzt habe.

ich habe einen Pointer namens:
char far *VIDMEM = (char far *)0xB8000000;
und in den funktionen selber gebe ich die an eine funktion namens "memsetw" zurück. die macht das gleiche wie memset von C nur halt mit words statt bytes.
an diese Funktion, die folgendermaßen deklariert ist:
void *memsetw(void *ptr,word nValue,size_t num);
gebe ich nun als *ptr die Adresse VIDMEM+nOffset (wobei nOffset irgendeine Zahl >=0 sein kann) mit.

die funktion memsetw steckt dann den wert von BP+8 in ES und setzt DI null. Danach wird einfach ganz oft "repet stosw" ausgeführt. mit "push" und "pop" ist alles geregelt.

Kann man das so machen und der Fehler ist woanders oder muss man den Pointer anders überreichen?
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

ahaaaaa
ich habe DI nun auf bp+6 gesetzt und *Zack* klappts. *jubel*
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Ich hätte da grad ma ne frage an die, die C und ASM können.
Ich wollte die Funktionen, die in den RAM-Bereich des VideoModes reinschreiben in ASM schreiben. das klappte auch
aber nur 1,2 mal, danach versagte die Funktion.
Ich glaube, es liegt daran, dass ich den Pointer nicht richtig in ASM benutzt habe.

ich habe einen Pointer namens:
char far *VIDMEM = (char far *)0xB8000000;
und in den funktionen selber gebe ich die an eine funktion namens "memsetw" zurück. die macht das gleiche wie memset von C nur halt mit words statt bytes.
an diese Funktion, die folgendermaßen deklariert ist:
void *memsetw(void *ptr,word nValue,size_t num);
gebe ich nun als *ptr die Adresse VIDMEM+nOffset (wobei nOffset irgendeine Zahl >=0 sein kann) mit.

die funktion memsetw steckt dann den wert von BP+8 in ES und setzt DI null. Danach wird einfach ganz oft "repet stosw" ausgeführt. mit "push" und "pop" ist alles geregelt.

Kann man das so machen und der Fehler ist woanders oder muss man den Pointer anders überreichen?
Wie der Pointer richtig übergeben wird weiss ich leider nicht. Aber zum Befüllen des Textbildschirms braucht man folgende Opcodes:

Code: Alles auswählen

cld                  ; Clear direction-flag für Stringoperationen die von niedriger Adresse zur höheren Adresse arbeiten sollen (wird nur benötigt wenn Flag gesetzt).
mov ax, 0B800h       ; Segmentadresse
mov es, ax           ;   ins ES-Segmentregister
mov di, Ziel-Offset
mov cx, Anzahl       ; gibt an wie oft mit "rep" wiederholt werden soll. Am Ende ist CX = 0.
mov ax, ASCII+Color  ; Inhalt
rep stosw            ; schreibt Anzahl * Words in AX nach ES:DI. Nach jedem "stosw" wird DI um 2 Byte erhöht.
Zum Kopieren eines Textes zum Textbildschirms braucht man folgende Opcodes:

Code: Alles auswählen

cld
mov ax, Quell-Segment
mov ds, ax
mov si, Quell--Offset
mov ax, 0B800h
mov es, ax
mov di, Ziel-Offset
mov cx, Anzahl
rep movsw            ; Kopiert Anzahl * Words von DS:SI nach ES:DI. Nach jedem "movsw" wird SI und DI um 2 Byte erhöht.
Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:ahaaaaa
ich habe DI nun auf bp+6 gesetzt und *Zack* klappts. *jubel*
Ah, dann lag es doch an der Übergabe des Pointers.

Dirk
Antworten