Newsgroup: it.comp.lang.c
Titolo: [forse OT] Modificare la tebella caratteri

Forse il msg è un pò OT, ma che io sappia non esiste un NG it.comp.lang.asm.
Ho un problema. Vorrei modificare la tabella dei caratteri ASCII modalità
testo. Ho consultato la lista degli interrupt di Ralph Brown e ho trovato
qualcosa all' int 10h (gestione video). Purtoppo però mi sono perso perché
ci sono troppi servizi simili sull'argomento e poi, una volta caricata la
tabella in memoria non saprei come gestirla (non ne conosco il formato).
Sarei felice se qualcuno sapesse aiutarmi.
Grazie in anticipo, Giuseppe
------
PS.  Molte volte un listato di esempio è molto più esauriente di Km di
spiegazione :)

...

Ciao, ti posso mandare un estratto di una mia ormai vecchia libreria per dos
(che ho abbandonato).
Si puo' usare il BIOS per modificare la tabella, ma e' troppo lento. Per
avere prestazioni migliori occorre agire direttamente sulla scheda. Io avevo
implementato la simulazione del mouse grafico nella modalita' carattere.
In pratica, ad ogni movimento del mouse, rimappavo i quattro caratteri entro
cui si trovava il mouse con l'immagine del mouse (la classica freccia) e li
visualizzavo sullo schermo (dopo aver salvato, naturalmente, i quattro
originari).
P.S. Fanno parte di una classe C++ (era l'inizio del mio passaggio dal C al
C++), ma sono utilizzabili anche come C normale.
PP.SS. Naturalmente usano l'asm inline, formato Borland :-)
Spero di non aver disturbato il NG con un msg troppo lungo [e forse troppo
OT] :-)
Se ti interessa posso mandarti tutta la mia libreria :-)
Ciao
Nazzareno
// -------------------------------------------------------------------------
--
void P_Video_Base::set_table_bios(int car, UBYTE *s, int n, int b_x_car)
{
asm {
  mov dx,car
  mov cx,n
  mov bx,b_x_car
  xchg bl,bh
  push bp
  les bp,s
  mov ax,0x1100
  int 0x10
  pop bp
  }
}
// -------------------------------------------------------------------------
---
void P_Video_Base::set_table(int car,UBYTE *buff,int n,int byte_x_car)
{
  prep_reg_map();
  output_map(car,buff,n,byte_x_car);
  reset_reg_map();
}
// -------------------------------------------------------------------------
---
void P_Video_Base::get_curr_table(int car,UBYTE *buff,int n,int byte_x_car)
{
  prep_reg_map();
  input_map(car,buff,n,byte_x_car);
  reset_reg_map();
}
// -------------------------------------------------------------------------
---
void P_Video_Base::reset_table(void)
{
asm {
  xor bl,bl
  mov ax,0x1104
  int 0x10
  }
}
// -------------------------------------------------------------------------
---
// -------------------------------------------------------------------------
---
static void output_map(int car, UBYTE *buff, int n, int byte_x_car)
{
asm {
  mov ax,0xa000  // segmento memoria video in cui c'e' la mappa
  mov es,ax             // dei caratteri
  mov di,car            // carattere di inizio da copiare
  mov cx,5
  shl di,cl             // l'offset di ogni carattere e' ogni 32 byte
  mov cx,n              // numero di caratteri da copiare
  mov bx,byte_x_car     // byte usati per mappare un carattere
  mov dx,32             // offset pieno
  sub dx,bx      // spazio non usato tra un carattere e l'altro
  push ds
  lds si,buff           // carica il buffer da cui copiare
  cld                   // direzione in avanti
  }
loop:
asm  {
  mov ax,cx             // salva numero di caratteri
  mov cx,bx      // byte per carattere
  rep movsb             // trasferisce
  add di,dx             // porta il puntatore al prossimo carattere
  mov cx,ax             // ripristina caratteri da copiare
  loop loop
  pop ds
  }
}
// -------------------------------------------------------------------------
---
static void input_map(int car, UBYTE *buff, int n, int byte_x_car)
{
asm {
  push ds
  mov ax,0xa000
  mov ds,ax
  mov si,car
  mov cx,5
  shl si,cl
  mov cx,n
  mov bx,byte_x_car
  mov dx,32
  sub dx,bx
  les di,buff
  cld
  }
loop:
asm  {
  mov ax,cx
  mov cx,bx
  rep movsb
  add si,dx
  mov cx,ax
  loop loop
  pop ds
  }
}
// -------------------------------------------------------------------------
---
static void wait_sync(void)
{
asm {
  mov    dx,0x3DA               // registro stato
  cli                           // nessun interrupt - viene ripristinato
dalla routine chiamante
  }
wait_V:
asm {
  in     al,dx                  // legge lo stato
  test   al,8                   // Retrace verticale in corso se attivo
  jne    end                    // se non e' zero -> ok
  rcr  al,1                   // verifica se e' in corso quello orizzontale
  jnc wait_V                  // no, riprova
  }
wait_H:
asm {
  in al,dx                   // attende il prossimo retrace orizzontale
  rcr al,1
  jnc wait_H
  }
end:
;
}
// -------------------------------------------------------------------------
---
static void prep_reg_map(void)
{
  wait_sync();
asm {
  mov    al,2           // funzione Map Mask Register, selezione piano
  mov    dx,0x3C4  // registro di controllo Sequenzializzatore
  out    dx,al
  mov    al,4           // seleziona piano 2
  inc    dx             // registro dati Sequenzializzatore
  out    dx,al
  mov    al,4           // funzione Memory Mode Register
  mov    dx,0x3C4 // registro di controllo Sequenzializzatore
  out    dx,al
  mov    al,7           // modo alfanum.+ oltre 64k + abilita odd/even
  inc    dx             // registro dati Sequenzializzatore
  out    dx,al
  mov    al,5           // funzione Modo di scrittura
  mov    dx,0x3CE // registro Grafico
  out    dx,al
  mov    al,0           // modo 0
  inc    dx
  out    dx,al
  mov    al,6           // funzione varie
  mov    dx,0x3CE // registro Grafico
  out    dx,al
  mov    al,4           // usa 0xA000-0xAFFF EGA/VGA Graphics modes
  inc    dx
  out    dx,al
  mov    al,4           // funzione Read Map Select Register
  mov    dx,0x3CE // registro Grafico
  out    dx,al
  mov    al,2           // piano 2, generatore di caratteri
  inc    dx
  out    dx,al
  sti
  }
}
// -------------------------------------------------------------------------
---
static void reset_reg_map(void)
{
  wait_sync();
asm {
  mov    al,2           // funzione Map Mask Register
  mov    dx,0x3C4 // registro di controllo Sequenzializzatore
  out    dx,al
  mov    al,3           // abilita piani 0 e 1, codice carattere e attributo
  inc    dx
  out    dx,al
  mov    al,4           // funzione Memory Mode Register
  mov    dx,0x3C4 // registro di controllo Sequenzializzatore
  out    dx,al
  mov    al,3           // modo alfanum.+ oltre 64k
  inc    dx
  out    dx,al
  mov    al,5           // funzione Modo di scrittura
  mov    dx,0x3CE       // registro Grafico
  out    dx,al
  mov    al,0x10        // modo 0 + abilita odd/even
  inc    dx
  out    dx,al
  mov    al,6           // funzione varie
  mov    dx,0x3CE
  out    dx,al
  mov    al,0xE         // modo alf. + abil. odd/even + usa 0xB800-0xBFFF
  inc    dx
  out    dx,al
  mov    al,4           // funzione Read Map Select Register
  mov    dx,0x3CE
  out    dx,al
  mov    al,0           // legge piano 0
  inc    dx
  out    dx,al
  sti
  }
}
// -------------------------------------------------------------------------
---

Ti rigrazio vivamente, era da un pò che sbattevo su questo argomento.
Si, se non è troppo grossa e se non ti reca disturbo mi piacerebbe davvero
dare un'occhiata alla tua libreria.
Grazie e ciao



...

Ok,
ti invio in forma privata la libreria
Ciao
Nazzareno