Hallo, gute Tag. Ich kenne von CGA nur die Textdarstellung. Das einzelne Byte setzen mit Farbe kenne ich nicht. Ich lese von CGA immer nur über die Textauflösung. Im Bild habe ich mal 2 Byte gesetzt mit dem TC3, das erste und das letzte. Es ist weiß. Wie setzt sich bitte 1 Byte zusammen für eine farbige Darstellung? Warum hält beim TC3 das "return 0;" die Programführung nicht an? -------------------------------------------- #include <dos.h> int adr; char byte; void setze() { pokeb(0xb800,adr,byte); } void cga() { asm{ mov ax,04h int 10h } } main() { cga(); adr=32; byte=255; setze(); adr=8031; byte=255; setze(); return 0; } ----------------------------- Gruss
wenn schon dann schon int main() und bitte keine globalen void setze(int adr, char byte) { pokeb(0xb800,adr,byte); } und dann setze(32, 255); setze(8031, 255); und zur besseren Lesbarkeit ax splitten void cga() { asm{ mov ah,0 mov al,4 // 320 x 200 Pixel, vier Farben int 10h } } keine Ahung wie dieser CGA Modus auf gebaut ist - 2 Bits per Farbe? 4 Planes?
Peter B. schrieb: > Warum hält beim TC3 das "return 0;" die Programführung nicht an? Das Programm wird beendet - allerdings schaltet unter DOS(BOX) niemand den Grafik Modus zurück. Der bleibt auf CGA Mode stehen. Peter B. schrieb: > Wie setzt sich bitte 1 Byte zusammen für eine farbige Darstellung? Ein Byte sind 4 Pixel á 2 Bit. Probiere mal andere Werte aus.
der 1. Post könnte passen http://www.vcfed.org/forum/showthread.php?54561-CGA-mode-4-(320x200x4)-put-pixel-in-C
cppbert schrieb: > der 1. Post könnte passen > > http://www.vcfed.org/forum/showthread.php?54561-CGA-mode-4-(320x200x4)-put-pixel-in-C und JA der CGA Modus ist viel schwieriger als der 320x200x256 Mode 19
oder so static void write_pixel2(unsigned x, unsigned y, unsigned c) { unsigned wd_in_bytes, off, mask; c = (c & 3) * 0x55; wd_in_bytes = 320 / 4; off = wd_in_bytes * y + x / 4; x = (x & 3) * 2; mask = 0xC0 >> x; pokeb(0xB800, off, (peekb(0xB800, off) & ~mask) | (c & mask)); }
CGA Low-res 320x200, 4-color (video modes 04H and 05H) Segment: b800 Layout: Interleaved scan lines, packed-pixel. Even-numbered scan lines begin at b800:0, and odd-numbered lines begin at b800:2000. Each scan line is 80-bytes long and there are 200 scan lines (regen size=8000 bytes * 2 regions). Each byte contains 4 pixels (16,000 total pixels): ╓7┬6┬5┬4┬3┬2┬1┬0╖ ║ │ │ │ ║ ╙─┴─┴─┴─┴─┴─┴─┴─╜ bits mask ╚╦╝ ╚╦╝ ╚╦╝ ╚═╩═► 0-1: 03H fourth pixel in byte ║ ║ ╚══════► 2-3: 0cH third pixel in byte ║ ╚══════════► 4-5: 30H second pixel in byte ╚══════════════► 6-7: c0H first pixel in byte 00=black; 01=green/cyan 10=red/magenta; 11=brown/white Each 2-bit field selects one of four colors, depending on the setting of the CGA palette. Use INT 10H 0bH.
Danke für die Information, Wusste nicht ,das CGA mehr braucht als dieses VGA. Warum wird hier bitte bei y=199 2x durchlaufen? 1x mit eine Leerzeile und dann wird beim zweiten mal die Leerzeile gefüllt. -------------------------------- static void write_pixel2(unsigned x, unsigned y, unsigned c) { unsigned wd_in_bytes, off, mask; c = (c & 3) * 0x55; wd_in_bytes = 320 / 4; off = wd_in_bytes * y + x / 4; x = (x & 3) * 2; mask = 0xC0 >> x; pokeb(0xB800, off, (peekb(0xB800, off) & ~mask) | (c & mask)); } --------------------------------- Danke.
Peter B. schrieb: > 1x mit eine Leerzeile und dann wird beim zweiten mal die Leerzeile > gefüllt. hier wird nichts mehrfach durchlaufen - man muss eben das bestehende byte lesen um darin die entsprechenden 2 bits zu veraendern
Wenn ich y=199 habe dann werden 100 Zeilen ab der ersten nach unten geschrieben mit einer Leerzeile dann fängt es oben bei der zweiten an und schreibt wieder 100 nach unten , wobei jetzt die Leerzeilen gefüllt werden. Hier ein Zwischenfoto. ---------------------------------------- #include <dos.h> #include <conio.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> int x,y,col; void cga_graf() { asm{ mov ax,04h int 10h } } void cga_text() { asm{ mov ax,05h int 10h } } void plot(unsigned x, unsigned y, unsigned c) { unsigned wd_in_bytes, off, mask; c = (c & 3) * 0x55; wd_in_bytes = 320 / 4; off = wd_in_bytes * y + x / 4; x = (x & 3) * 2; mask = 0xC0 >> x; pokeb(0xB800, off, (peekb(0xB800, off) & ~mask) | (c & mask)); } main() { cga_graf(); col=2; for (y = 0; y <= 199; y++) { for (x = 0; x <= 320; x++) { plot(x,y,2); } } return 0; } ------------------------------------------- Gruss
:
Bearbeitet durch User
> for (y = 0; y <= 199; y++) { > for (x = 0; x <= 320; x++) { auf jeden Fall mal y < 200 x < 320
cppbert schrieb: >> for (y = 0; y <= 199; y++) { >> for (x = 0; x <= 320; x++) { > > auf jeden Fall mal > > y < 200 > x < 320 btw: halte deine variablen immer möglichst nah im dem Scope wo du sie brauchst d.h. die globalen x,y,col lieber in die main - hilft alles auf dauer Fehler zu vemeiden
einfach #include <assert.h> rein und in deine void plot(unsigned x, unsigned y, unsigned c) { unsigned wd_in_bytes, off, mask; // Vorbedingung die erfuellt sein muessen assert(x >= 0 && x < 320); assert(y >= 0 && y < 200); assert(c >= 0 && c < 4); c = (c & 3) * 0x55; wd_in_bytes = 320 / 4; off = wd_in_bytes * y + x / 4; x = (x & 3) * 2; mask = 0xC0 >> x; pokeb(0xB800, off, (peekb(0xB800, off) & ~mask) | (c & mask)); } dann fallen dir solche "Anwendungsfehler" schneller auf
Hallo, guten Tag. Ich bekomme es nicht hin dieses Byte : byte=0xb11111111; zu setzen damit 4 Pixel grün werden oder auch 4 Pixel rot . Ich bekomme die Aufteilung der 8 Pixel nicht hin. Zur Zeit sind 4 Pixel weiß : byte=0xb11111111; Auch warum muss die Adresse Hex : B800:20 sein damit das Byte als erstes oben links erscheint. Gruss ---------------------------------------- #include <dos.h> #include <conio.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> void setze(int adr, char byte) { pokeb(0xb800,adr,byte); } void cga_graf() { asm{ mov ah,0 mov al,4 int 10h } } void cga_text() { asm{ mov ax,05h int 10h } } int main() { int adr; char byte; cga_graf(); adr=32; byte=0xb11111111; setze(adr,byte); while (1) { switch (getche()) { case 'e': cga_text(); exit(0); } } return 0; } --------------------------------------------
1. geht mein Beispiel mit der plot-Funktion? 2. du willst jetzt den Algorithmus selbst schreiben? Ich hab den Algorithmus mal ein bisschen aufgeschluesselt aber Bit-Operationen musst du verstehen sonst geht es nicht
1 | const int WIDTH = 320; |
2 | const int HEIGHT = 200; |
3 | const int COLORS = 4; |
4 | const int BITS_PER_COLOR = COLORS / 2; |
5 | const int PIXEL_PER_BYTE = 8 / BITS_PER_COLOR; |
6 | const int BYTES_PER_LINE = WIDTH / PIXEL_PER_BYTE; |
7 | |
8 | volatile unsigned char* cga_mem = (volatile unsigned char*)(0xb800); |
9 | |
10 | int x = 6; |
11 | int y = 0; |
12 | int color = 2; |
13 | |
14 | assert(x >= 0 && x < WIDTH); |
15 | assert(y >= 0 && y < HEIGHT); |
16 | assert(color >= 0 && color < COLORS); |
17 | |
18 | //prepare color_mask and shiftet_color
|
19 | |
20 | // which Pixel inside the byte (left to right, 0..3)
|
21 | const unsigned pixel_offset = x % PIXEL_PER_BYTE; |
22 | const unsigned rshift = pixel_offset * 2; |
23 | const unsigned color_mask = 0b11000000 >> rshift; |
24 | const unsigned shiftet_color = color >> (6 - rshift); |
25 | |
26 | // which byte?
|
27 | const unsigned y_offset = y * BYTES_PER_LINE; |
28 | const unsigned x_offset = x / PIXEL_PER_BYTE; |
29 | const unsigned byte_offset = y_offset + x_offset; |
30 | |
31 | volatile unsigned char* byte = &cga_mem[byte_offset]; |
32 | |
33 | *byte = (*byte & ~color_mask) | shiftet_color; |
Peter B. schrieb: > Ich bekomme es nicht hin dieses Byte : byte=0xb11111111; > zu setzen damit 4 Pixel grün werden oder auch 4 Pixel rot . Wenn Du vier grüne Pixel haben willst, dann schreib halt auch viermal grün in das Byte: byte=0xb01010101 oder eben rot: byte=0xb10101010
Nein, deiner geht soweit wunderbar. Den ändere ich nicht. Gruss
Peter B. schrieb: > Nein, deiner geht soweit wunderbar. > Den ändere ich nicht. > > Gruss den hatte ich auch nur im Internet gefunden und dann sauber gemacht - so das man auch versteht was da passiert
Das hatte ich schon aus der Tabelle: (16,000 total pixels): ╓7┬6┬5┬4┬3┬2┬1┬0╖ ║ │ │ │ ║ ╙─┴─┴─┴─┴─┴─┴─┴─╜ bits mask ╚╦╝ ╚╦╝ ╚╦╝ ╚═╩═► 0-1: 03H fourth pixel in byte ║ ║ ╚══════► 2-3: 0cH third pixel in byte ║ ╚══════════► 4-5: 30H second pixel in byte ╚══════════════► 6-7: c0H first pixel in byte 00=black; 01=green/cyan 10=red/magenta; 11=brown/white --------------------------- adr=0x20; byte=0xb01010101; setze(adr,byte); ---------------------------- Es kommt nur 1 Pixel. Warum weiss ich nicht, was falsch ist. Was bedeutet da drin 03h , 0c, 30h, c0h ? Gruss
------------------------ Welche Build-Umgebung nutzt Du? ------------------------ Borland Turbo C++ 3.0 (3.5-720k) Borland Turbo C++ 3.0 (5.25-1.2mb) /* dos.h Defines structs, unions, macros, and functions for dealing with MSDOS and the Intel iAPX86 microprocessor family. Copyright (c) 1987, 1991 by Borland International All Rights Reserved. */ Habe beide getestet. byte=0xb11111111; , das geht ja und es sind 4 weiße Pixel da. Gruss
:
Bearbeitet durch User
cppbert schrieb: > ... War da nicht noch was mit "Interleaved scan lines"? Also sowas in der Art:
1 | const unsigned y_offset = ( y & 0x01 ) ? y / 2 * BYTES_PER_LINE + 0x2000 : y / 2 * BYTES_PER_LINE; |
Btw.
1 | volatile unsigned char* cga_mem = (volatile unsigned char*)(0xb800); |
Das kann so auch nicht funktionieren. Zum einen muß das wohl ein 'far' Pointer sein und zu anderen ist 0xb800 eine Segmentaddresse. Also eher:
1 | volatile unsigned char far* cga_mem = (volatile unsigned char far*)(0xb800:0000); |
oder falls TC die Schreibweise nicht versteht:
1 | volatile unsigned char far* cga_mem = (volatile unsigned char far*)(0xb8000); |
bzw. falls das Makro existiert noch bessesr:
1 | volatile unsigned char far* cga_mem = (volatile unsigned char far*)MK_FP(0xB800,0x0000); |
Hmm...eine komische Sache. WEnn ich statt byte=0xb01010101 dieses eingebe : byte=85 geht es. Stimmt die Hexmarkierung nicht? Aber warum wird byte=0xb11111111 weiß? Gruss
:
Bearbeitet durch User
guest schrieb: > cppbert schrieb: >> ... > > War da nicht noch was mit "Interleaved scan lines"? > Also sowas in der Art:const unsigned y_offset = ( y & 0x01 ) ? y / 2 * > BYTES_PER_LINE + 0x2000 : y / 2 * BYTES_PER_LINE; ist nicht richtig kompilierbar - speziell nicht unter TC 3, ich wollte nur die Algorithmus ein wenig zerlegt aufzeige, die orginal plot funktion geht ja
Peter B. schrieb: > WEnn ich statt byte=0xb01010101 dieses eingebe : byte=85 geht es. > Stimmt die Hexmarkierung nicht? > > Aber warum wird byte=0xb11111111 weiß? > Gruss bitte nur 0b als Prefix für Binär - nicht 0xb, das x ist kein Trenner sondern steht fuer Hex und 0xb heisst dann Hexbinär??? also 0b[01]+ oder 0x[A-F0-9]+ bitte ein ganzes Beispiel - es ist schwer dir zu folgen mit so Häppchen-Fragen
Peter B. schrieb: > Hmm...eine komische Sache. > > WEnn ich statt byte=0xb01010101 dieses eingebe : byte=85 geht es. > Stimmt die Hexmarkierung nicht? > > Aber warum wird byte=0xb11111111 weiß? > Gruss die 0b schreibweise gibt es erst seit 1-2 Jahren, und keine Ahnung was dein Kompiler mit 0xb macht???
Peter B. schrieb: > adr=0x20; > byte=0xb01010101; > setze(adr,byte); > ---------------------------- > > Es kommt nur 1 Pixel. > > Warum weiss ich nicht, was falsch ist. > Was bedeutet da drin 03h , 0c, 30h, c0h ? > > Gruss Sorry, da hab ich auch noch was übersehen. Die binäre Schreibweise dürfte TC nicht kennen und mit 0x am Anfang wirds eh als hex interpretiert. Also für grün so: byte=0x55 und für rot: byte=0xAA. Oder falls TC doch damit klarkommt: byte=0b01010101, also ohne das 'x'. "03h , 0c, 30h, c0h" Das sind die Masken (in hex) um die vier Pixel innerhalb eines Byte zu maskieren. Im Endeffekt das, was cppbert in 'color_mask' stehen hat.
cppbert schrieb: > und keine Ahnung was > dein Kompiler mit 0xb macht??? er interpretiert es ja klarerweise als hex ist also ein Hexzahl: 0xB11111111 da ist nicht binär also kommt da ein völlig falscher Wert aus wie gesagt 0b gibt es erst seit kurzem - du musst die Binärdarstellung wohl oder übel durch den Calc oder sonstwas jagen
cppbert schrieb: > und keine Ahnung was > dein Kompiler mit 0xb macht??? 'b' ist eine gültige Hex-Ziffer, von meinem falschen Bsp. "0xb01010101" (dez. 47261483265) bleibt am Ende in dem Byte nur noch 0x01 übrig und damit genau der von Peter erwähnte eine Pixel.
Alles klar ,danke. Ist keine Problem in HEX oder Deci zu schreiben. Das Binäre war halt mehr übersichtlicher. Gruss
:
Bearbeitet durch User
cppbert schrieb: > und JA der CGA Modus ist viel schwieriger als der 320x200x256 Mode 19 Allerdings ist letzterer ziemlich blöde umgesetzt mit seinem skurrilen chain4 und der damit einhergehenden Verschwendung von 3/4 des Grafikspeichers.
Peter B. schrieb: > Was bedeutet da drin 03h , 0c, 30h, c0h ? Das sind die Wert zum maskieren der Pixel 03h = 0x03 = 0b00000011 0Ch = 0x0C = 0b00001100 30h = 0x30 = 0b00110000 C0h = 0xC0 = 0b11000000 Die Schreibweise mit dem h als Suffix stammt vom Assembler (MASM ?)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.