Newsgroup: it.comp.programmare.win32
Titolo: indirizzo della pagina video

salve a tutti, stavo provando a scrivere una classe c++ che mi permetta di 
scrivere ovunque nella finestra video (console) e non solo una riga dopo 
l'altra.
quello di cui ho bisogno adesso č di sapere l'indirizzo della pagina della 
memoria video, in modo da velocizzare le varie operazioni.
al momento infatti lavoro su un array di char che mi funge da memoria video 
che viene quindi stampata a video con una serie di printf, cosa che oltre ad 
essere estremamente poco elegante č anche indicibilmente lenta.
avendo l'indirizzo della pagina video invece potrei usare un ben piů veloce 
memcpy o addirittura (ma mi pare azzardato) lavorare direttamente sulla 
memoria video.
qualche idea? 

su google ho trovato questa dispensa:
...
Ciò che viene rappresentato sul video non è altro che il contenuto di una 
zona di memoria detta buffer video; in una pagina video in modalità testo di 
80 colonne per 25 righe sono presenti in totale 2000 caratteri. Il buffer 
video corrispondente occupa però 4000 byte perché ad ogni carattere è 
associato un ulteriore byte di attributi (colore carattere, colore sfondo, 
lampeggiante).
In genere il buffer video per la modalità testo occupa la zona di memoria a 
partire dall'indirizzo di base B800H e offset (scostamento) 0000H, più 
precisamente scritto: B800H:0000H.
...
Il byte attributi:
bit7: 1=lampeggiante 0=non lampeggiante
bit3..bit0: colore carattere
bit6..bit4: colore sfondo.
ma non mi pare che funzioni (il programma si pianta con un errore di accesso 
alla memoria): quando provo ad accedere a 0xB800+0
dove sbaglio? 

 dove sbaglio?
Prova ad indirizzare correttamente e vedi che succede...
Bye Dave.

 dove sbaglio?
Se il sistema operativo è Windows NT o 2000 o XP non puoi
accedere direttamente alla memoria (almeno, non con una
semplice applicazione) quindi direi che è abbastanza normale
ottenere un simile errore.
Ciao,
==========================
Stefano Frosio
http://www.esse-effe.com
==========================

 ottenere un simile errore.
 effettivamente io ho xp, però in qualche modo so che quell'indirizzo 
(B800:0000) è ancora "funzionante" come memoria video perchè con debug.exe 
succede questo:
-d b800:0000
B800:0000  2D 07 64 07 20 07 62 07-38 07 30 07 30 07 3A 07   -.d. 
.b.8.0.0.:.
B800:0010  30 07 30 07 30 07 30 07-20 07 20 07 20 07 20 07   0.0.0.0. . . . 
.
B800:0020  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
B800:0030  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
B800:0040  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
B800:0050  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
B800:0060  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
B800:0070  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . 
.
come faccio ad accederci, allora?

 come faccio ad accederci, allora?
directx
ma anche con quelle non aspettarti di poter fare tutto quello che vuoi
ciao

 come faccio ad accederci, allora?
Se proprio vuoi accederci, devi farlo in kernel mode scrivendo un device 
driver. Un gioco che (ti dico subito) non vale la candela.
Windows funziona cosě, le applicazioni in user mode non accedono 
direttamente a queste risorse bensě tramite dei device driver.

 driver.
Questo vale solo per le ultime versioni di windows, vero?
Altrimenti i vecchi giochi per dos (quei pochi) che funzionano come fanno? 

> directx
per la console? 

proviamo a cambiare la domanda, allora.
conoscete una qualche libreria per c/c++ che mi permetta di fare output 
formattato sullo schermo con l'uso di colori e la possibilità di 
posizionarmi in un dato punto? (qualcosa tipo i comandi LOCATE e COLOR di 
basic) 

 per la console? 
ops :-\
hai ragione scusa



Credo che l'unico modo sia di farlo in una sessione DOS con un prg a
16 bit e tramite le funzioni del compilatore che dovrebbero essere ad
esempio se ricordo bene poke(),pokeb(),peek(),peekb() per quanto
riguarda il Borland a 16 bit .


Beh, se crei un programma console con BCB puoi approfittare
della funzione gotoxy, in pratica il locate del QBasic. Tra
l'altro pare che la cputs possa lavorare direttamente sulla
memoria video. Riporto uno stralcio dall'help:
<BCB_HELP>
int cputs(const char *str);
Description
Writes a string to the screen.
cputs writes the null-terminated string str to the current
text window. It does not append a newline character.
The string is written either directly to screen memory or by
way of a BIOS call, depending on the value of the global
variable _directvideo. Unlike puts, cputs does not translate
linefeed characters (\n) into carriage-return/linefeed
character pairs (\r\n).
</BCB_HELP>


 riguarda il Borland a 16 bit .
beh, ma se lo può fare una funzione di un vecchio compilatore devo poterlo 
fare anch'io, in un modo o nell'altro... 


http://pdcurses.sourceforge.net/

 Altrimenti i vecchi giochi per dos (quei pochi) che funzionano come fanno? 
I vecchi giochi DOS non funzionano se eseguiti in ambiente XP.
Funzionano ovviamente se eseguiti in ambiente dos puro.

> non capisco cosa vuoi intendere.
esempio: lancia debug.exe e digita "d b800:0000"
ti comparirà il dump dei primi 128 byte della memoria video di quella 
finestra dos. quindi il programma debug.exe è in grado di leggere da quella 
"posizione". ok?
poi digita "e b800:0000 30 31 32 33 34 35 36 37 38 39"
se guardi a questo punto in alto nello schermo vedrai dei caratteri colorati 
a caso. questo vuol dire che debug.exe è in grado di scrivere in quella 
posizione.
ora, COME FA debug.exe (che presumo non essere scritto in assembler) ad 
accedere in lettura e scrittura a quella posizione (così come a qualunque 
altra, se non vado errato)? 

> a questo punto in alto nello schermo vedrai
volevo dire console, non schermo.

altra, se non vado errato)? 
Mi sembra di avertelo gia detto.
O usi delle specifiche funzioni presenti nel tuo compilatore oppure
devi usare delle istruzioni assembler per andare a scrivere in quella
posizione .
Cosi a memoria (ma potrei sbagliare) mi sembra di ricordare che il
servizio di interrupt per scrivere sullo schermo sia lo 0x0A .

 servizio di interrupt per scrivere sullo schermo sia lo 0x0A .
Hai un qualche link per approfondire? Grazie. 



Rettifico 
e' l'interrupt 0x10 funzione 08 per leggere e 09 per scrivere un
carattere .
Pero non indirizza direttamente il valore di memoria video da te
richiesto ma scrive alla posizione currente del cursore.
Comunque in assembler non dovrebbe essere troppo complicato
scrivere direttamente nel buffer video . Dovrebbe bastare una semplice
istruzione MOV .
Ti allego l'implementazione di poke,pokeb,peek,peekb del C che scrive
un carattere in qualsiasi parte della memoria (compresa quella video).
void poke(unsigned segment, unsigned offset, int value)
{
        _ES = segment;
        * (int _es *) offset = value;
}
void pokeb(unsigned segment, unsigned offset, char value)
{
        _ES = segment;
        * (char _es *) offset = value;
}
int peek(unsigned segment, unsigned offset)
{
        _ES = segment;
        return(* (int _es *) offset);
}
char peekb(unsigned segment, unsigned offset)
{
        _ES = segment;
        return(* (unsigned char _es *) offset);
}

        * (int _es *) offset = value;
presumo che _ES e _es sia il registro, ma ho bisogno di qualche include 
particolare? 



#include <dos.h>

> #include <dos.h>
hmmm, no. in compilazione mi da errore. dentro il file dos.h non ci sono 
definizioni, e una veloce ricerca all'interno dei file della cartella degli 
include non mi trova nulla per "_ES " o "_es ".
ho dev-cpp su windows. può essere questo il problema? 

ho dev-cpp su windows. può essere questo il problema? 
si 
perche il codice da me postato si riferiva a un compilatore Borland a
16 bit.