Newsgroup: it.comp.programmare
Titolo: Roba da hacker

Ho costruito un microcomputer con microprocessore Z80 ed ho scritto il
BIOS della mobo di modo tale da poter leggere delle informazioni da un
tastierino esadecimale.
La palla e' doverlo programmare ogni volta. Visto che non dispongo
ancora di un programmatore di eprom lo devo programmare tutte le volte
tramite il tastierino...immaginate cosa voglia dire inserire un
programma di 500byte e accorgersi di aver sbagliato una misera
cosuccia, tale da dover far ricominciare.
Il mio scopo e' quello di voler scrivere un programmatore tramite
porta parallela.
Innanzitutto vi dico che la scheda a microprocessore è in ascolto
sullo zoccolo del tastierino quindi non dovrò fare altro che mandare
le informazioni binerie che simulano le informazioni che altrimenti
manderei tramite il tastierino.
Per la programmazione dispongo di un file esadecimale che costituisce
il programma da caricare (lo carico sulla ram della scheda) ed è un
file cosi':
$cat input.txt
C30E
esempio spicciolo e sbrigativo.
Questo sopra e' un file di 2byte che dovra' essere modificato. Deve
seguire un certo protocollo di comunicazione e cioe' la stringa sopra
mi deve diventare:
2C --> primo byte da mandare, il 2 indica che ho inserito un dato
semplice
DF --> altro byte, simula il rilascio del tasto
23 --> altro byte, simula la pressione del 3
DF --> rilascio tasto
23 --> equivale al premere invio della tastiera
-----> fine primo byte (C3)
Dalla porta parallela deve dunque uscire:
         2             C   --> esadecimale
        0010          1100 --> binario
     MSD^                ^LSD
         D             F
        1101          1111
e cosi' via.
La stessa cosa deve essere fatta per 0E:
20
DF
2E
DF
23
Di seguito posto il programma che sto scrivendo e vorrei sapere se
avete consigli da darmi e se sapete spiegarmi perchè all'ultimo mi da
problemi.
Ecco il programma:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/io.h>
#define PORT 378
main(){
 FILE *fp, *fw, *fd, *fd2;
 unsigned char nop,lf;
 int i,len,capp,intero;
 unsigned char ch[5000],ar[5000],va,carattere;
 nop=223;//223=DFh --> tasto rilasciato
 lf=50;//50=32h --> corrisponde a DA
 printf("\nIl programma legge il file esadecimale input.txt, manda in
uscita il\n");
 printf("file esadecimale in linea nel file output.txt e mette nel
file 'definitivo'\n");
 printf("il contenuto di cio' che manda sulla porta parallela.\n");
 fd2=fopen("fd2", "a");
 if( fd2==NULL ) {
 perror("Errore in apertura di input.txt");
 sleep(5);
 exit(1);
 }
 fp=fopen("input.txt", "r");
 if( fp==NULL ) {
 perror("Errore in apertura di input.txt");
 sleep(5);
 exit(1);
 }
 fw=fopen("output.txt","w");
 if( fw==NULL ) {
 perror("Errore in apertura di output.exe");
 sleep(5);
 exit(1);
 }
 fd=fopen("definitivo","w");
 if( fd==NULL ) {
 perror("Errore in apertura del file definitivo");
 sleep(5);
 exit(1);
 }
i=0;
while ((capp=fgetc(fp))!=EOF)
{
 ch[i]=capp;
 ar[i]=0;
 switch (ch[i])
 {
 case '0':      ar[i]=32;break;
 case '1':      ar[i]=33;break;
 case '2':      ar[i]=34;break;
 case '3':      ar[i]=35;break;
 case '4':      ar[i]=36;break;
 case '5':      ar[i]=37;break;
 case '6':      ar[i]=38;break;
 case '7':      ar[i]=39;break;
 case '8':      ar[i]=40;break;
 case '9':      ar[i]=41;break;
 case 'A':      ar[i]=42;break;
 case 'B':      ar[i]=43;break;
 case 'C':      ar[i]=44;break;
 case 'D':      ar[i]=45;break;
 case 'E':      ar[i]=46;break;
 case 'F':      ar[i]=47;break;
 default :  printf("\nC'e' un carattere sconosciuto! Esco!\n");
 }
 fputc (ch[i],fw);
 fputc('\n',fw);
 i=i+1;
}
len=i;
printf ("\nNumero dei byte: %d",len);
ch[i]='\0';
printf ("\nVettore ch: %s",ch);
for (i=0; i<len; i++)
printf ("\nVettore ar:[%d]: %c",i,ar[i]);
 printf("\n");
 fclose(fp);
 fclose(fw);
 printf("Fatto!\n");
 printf ("Mando sulla porta e sul file 'definitivo'\n");
 ioperm(PORT,1,1);
 for(i=0;i<len;i=i+2){
 fputc(ar[i],fd);//questi sono da mandare sulla parallela --> parte +
significativa dato
 outb(ar[i],PORT);
 fputc(nop,fd);//Scrivo DF --> tasto rilasciato
 outb(nop,PORT);
 fputc(ar[i+1],fd);//--> parte - significativa dato
 outb(ar[i+1],PORT);
 fputc(nop,fd);//Scrivo DF --> tasto rilasciato
 outb(nop,PORT);
 fputc(lf,fd);
 outb(lf,PORT);
 }
 ioperm(PORT,1,0);
 fclose(fd);
 sleep(2);
 printf("\nRiabilito la tastiera...vai!");
 printf("\n\nInserisci valori esadecimali da 0 a F");
 printf("\nInserisci r per RUN");
 printf("\nInserisci k per DA");
 printf("\nInserisci l per LO");
 printf("\nInserisci h per HI\n");
 while(1){
  ioperm(PORT,1,1);
  fd2=fopen("fd2","a");
  printf("\n--> ");
  intero=getc(stdin);
  carattere=intero;
  switch(carattere) {
  case '0': va=32;break;
  case '1': va=33;break;
  case '2': va=34;break;
  case '3': va=35;break;
  case '4': va=36;break;
  case '5': va=37;break;
  case '6': va=38;break;
  case '7': va=39;break;
  case '8': va=40;break;
  case '9': va=41;break;
  case 'a': va=42;break;
  case 'b': va=43;break;
  case 'c': va=44;break;
  case 'd': va=45;break;
  case 'e': va=46;break;
  case 'f': va=47;break;
  case 'r': va=51;break;//RUN
  case 'k': va=50;break;//DA
  case 'l': va=49;break;//LO
  case 'h': va=48;break;//HI
  default : { va=223;
              printf("\nHai inserito un dato non valido\n");
            }
  }
  fputc(nop,fd2);
  outb(nop,PORT);
  fputc(va,fd2);
  outb(va,PORT);
  fclose(fd2);
  fflush(stdin);
  ioperm(PORT,1,0);
 }
}
Premetto che lavoro sotto Linux ma non mi farebbe schifo rendere il
programma girabile anche sotto altri sistemi, come windows che e'
quello che purtroppo si usa a scuola :°°°
Ho problemi nell'ultimo switch, come se non funzionasse la fflush(),
l'output è il seguente:
Riabilito la tastiera...vai!
Inserisci valori esadecimali da 0 a F
Inserisci r per RUN
Inserisci k per DA
Inserisci l per LO
Inserisci h per HI
--> a
-->
Hai inserito un dato non valido
--> b
-->
Hai inserito un dato non valido
-->
come se considerasse un carattere vuoto dopo quello che ho inserito e
giustamente lo considera non valido perchè non e' presente nello
switch.
Mi scuso per la lunghezza del post e vi ringrazio anticipatamente per
le eventuali risposte.
Se mi risponderete anche via e-mail mi farete un gran favore.
Ciao e buon lavoro.

  fflush(stdin);
   Non si fa flush su input, e` definito solo per output. :(
-- 
S.L.

...

Scusa ma sono un elettronico, programmo solo per passione, è già tanto
che sono riuscito a fare una cosa del genere.
Comunque ho risolto mettendo un getchar() al posto di fflush(), così
ho eliminato il secondo carattere presente nel buffer.
Ad ogni modo se avete consigli sono bene accetti.

Il programma definitivo e funzionante sotto Linux e' il seguente, mi
sapreste dire come adattarlo per farlo funzionare anche sotto windows?
Grazie
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <asm/io.h>
#define PORT 0x378
int converti(int);
main(){
 FILE *fr;
 char nomefile[81],ok;
 int num,appoggio,i,lunghezza,gioco;
 int nop=223;
 int lf=50;
 printf("\nIl programma legge contenuto di un file esadecimale e manda
il contenuto\n");
 printf("sulla porta parallela.\n");
 printf("\nImmetti il nome del file esadecimale : ");
 scanf("%s",nomefile);
 ioperm(PORT,1,1);
 outb(nop,PORT);
 ioperm(PORT,1,0);
 printf("\nAccendi la scheda z80 e premi un tasto\n");
 scanf("%c",&ok);
 scanf("%c",&ok);
 printf("\nAttendi...sto programmando.");
 //apro il file in lettura
 fr=fopen(nomefile, "r");
 if( fr==NULL ) {
 perror("Errore in apertura del file esadecimale");
 sleep(5);
 exit(1);
 }
 gioco=0;
 i=0;
 while ((appoggio=fgetc(fr))!=EOF)
 {
  ioperm(PORT,1,1);
  i=i+1;
  num=converti(appoggio);
  if ( num < 97 && num > 102 && num < 65 && num > 70 && num < 48 &&
num > 57 ){
   printf("\nC'e' un carattere sconosciuto, esco!\n");
   exit(1);
  }
  outb(num,PORT);
  usleep(50000);
  outb(nop,PORT);
  usleep(50000);
  gioco=~gioco;
  if ( gioco != 0 )
   continue;
  outb(lf,PORT);
  usleep(50000);
  outb(nop,PORT);
  usleep(50000);
  ioperm(PORT,1,0);
 }
 printf("\nFine programmazione automatica."); 
 lunghezza=i-1;
 printf ("\nNumero dei byte : %d",lunghezza);
 fclose(fr);//chiudo il file
 sleep(1);
 
 printf("\n\nRiabilito la tastiera...vai!");
 printf("\n\nInserisci valori esadecimali da 0 a F");
 printf("\nInserisci r per RUN");
 printf("\nInserisci k per DA");
 printf("\nInserisci l per LO");
 printf("\nInserisci h per HI\n");
 while(1){
  ioperm(PORT,1,1);
  printf("\n--> ");
  appoggio=getchar();
  getchar();
  num=converti(appoggio);
  if ( num < 'a' && num > 'f' && num < 'A' && num > 'F' && num < '0'
&& num > '9' )
   printf("\nCarattere non valido.");
  outb(num,PORT);
  usleep(50000);
  outb(nop,PORT);
  usleep(50000);
 }
}
int converti(int x){
 if ( x>='A' && x<='F' )
  x=x-23;
 else if ( x>='a' && x<='f' )
  x=x-55;
 else if ( x>='0' && x<='9' )
  x=x-16;
 else if ( x=='r' || x=='R' )
  x=51;
 else if ( x=='k' || x=='K' )
  x=50;
 else if ( x=='l' || x=='L' )
  x=49;
 else if ( x=='h' || x=='H')
  x=48;
 else if ( x==176 )
  x=223;
 else if ( x==10 )
  x=223;
 else{
  x=223;
  printf("\nHai inserito un numero errato.\n");
  }
 return x;
}

 sapreste dire come adattarlo per farlo funzionare anche sotto windows?
cygwin.
-- 
Morpheu5

> cygwin.
Caruccio questo programma ma volevo divertirmi con il C.
La versione per windows e' la seguente ma mi crasha, potreste dirmi
perche'?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#define PORT 0x378
#include <windows.h>
#include <winbase.h>
void stampa(int);
int converti(int);
main(){
 FILE *fr;
 char nomefile[81],ok;
 int num,appoggio,i,lunghezza,gioco;
 int nop=223;
 int lf=50;
 printf("\nIl programma legge contenuto di un file esadecimale e manda
il contenuto\n");
 printf("sulla porta parallela.\n");
 printf("\nSto all'inizio");
 printf("\nStampo nop");
 stampa(nop);
 printf("\nDopo nop");
 printf("\nAccendi la scheda z80 e premi un tasto\n");
 scanf("%c",&ok);
 scanf("%c",&ok);
 printf("\nAttendi...sto programmando.");
 //apro il file in lettura
 fr=fopen("a", "r");
 if( fr==NULL ) {
 perror("Errore in apertura del file esadecimale");
 Sleep(5000);
 exit(1);
 }
 gioco=0;
 i=0;
 while ((appoggio=fgetc(fr))!=EOF)
 {
  i=i+1;
  num=converti(appoggio);
  if ( num < 32 || num > 51 ){
   printf("\nC'e' un carattere sconosciuto, esco!\n");
   exit(1);
  }
  stampa(num);
  Sleep(1000);
  stampa(nop);
  Sleep(1000);
  gioco=~gioco;
  if ( gioco != 0 )
   continue;
  stampa(lf);
  Sleep(1000);
  stampa(nop);
  Sleep(1000);
 }
 printf("\nFine programmazione automatica.");
 lunghezza=i-1;
 printf ("\nNumero dei byte : %d",lunghezza);
 fclose(fr);//chiudo il file
 Sleep(1000);
 printf("\n\nRiabilito la tastiera...vai!");
 printf("\n\nInserisci valori esadecimali da 0 a F");
 printf("\nInserisci r per RUN");
 printf("\nInserisci k per DA");
 printf("\nInserisci l per LO");
 printf("\nInserisci h per HI\n");
 while(1){
  printf("\n--> ");
  appoggio=getchar();
  getchar();
  num=converti(appoggio);
  if ( num < 32 || num > 51 )
   printf("\nCarattere non valido.");
  stampa(num);
  Sleep(1000);
  stampa(nop);
  Sleep(1000);
 }
}
int converti(int x){
 if ( x>='A' && x<='F' )
  x=x-23;
 else if ( x>='a' && x<='f' )
  x=x-55;
 else if ( x>='0' && x<='9' )
  x=x-16;
 else if ( x=='r' || x=='R' )
  x=51;
 else if ( x=='k' || x=='K' )
  x=50;
 else if ( x=='l' || x=='L' )
  x=49;
 else if ( x=='h' || x=='H')
  x=48;
 else if ( x==176 )
  x=223;
 else if ( x==10 )
  x=223;
 else{
  x=223;
  printf("\nHai inserito un numero errato.\n");
  }
 return x;
}
void stampa(int z){
  __asm("push %si");
  __asm("push %di");
 
  __asm("push %ds");
 
  __asm("push %ax");
  __asm("push %bx");
  __asm("push %cx");
  __asm("push %dx");
 
  __asm("mov %dx,0x378");
  __asm("mov %eax,'z'");
  __asm("mov %dx,%ax");
 
  __asm("pop %dx");
  __asm("pop %cx");
  __asm("pop %bx");
  __asm("pop %ax");
 
  __asm("pop %ds");
 
  __asm("pop %di");
  __asm("pop %si");
}
ho provato a pushare e poppare tutti i registri sopra ma crasha lo
stesso.

  __asm("mov %eax,'z'");
Potrebbe essere "ax" invece di "eax"?
Leonardo
-- 
Nach doiligh domhsa mo chailin a mholadh
'S ni he amhain mar bhi si or
Bhi si mar gath greine a dhul in eadan na gloinne
Is bhi sceimh mhna na finne le mo cailin or

Il programma dovrebbe essere questo se solo il Dev-C++ mi prendesse
gli Sleep() e gli outp():
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dos.h>
#define PORT 0
int converti(int);
void menu();
main(){
 FILE *fr;
 char nomefile[81],ok;
 int num,appoggio,i,lunghezza,gioco,gioco2;
 int nop=223;
 int lf=50;
   printf("\n  *********************************************************************");
   printf("\n  *                                                      
            *");
   printf("\n  *                  Programmatore per microcomputer con 
            *");
   printf("\n  *                        microprocessore Z-80          
            *");
   printf("\n  *                                                      
            *");
   printf("\n  *                                                      
            *");
   printf("\n  *********************************************************************");
 printf("\nIl programma legge contenuto di un file esadecimale e manda
il contenuto\n");
 printf("sulla porta parallela.\n");
 printf("\nImmetti il nome del file esadecimale : ");
 scanf("%s",nomefile);
 outp(PORT,nop);
 printf("\nAccendi la scheda z80 e premi un tasto\n");
 scanf("%c",&ok);
 scanf("%c",&ok);
 printf("\nAttendi...sto programmando.");
 //apro il file in lettura
 fr=fopen(nomefile, "r");
 if( fr==NULL ) {
 perror("Errore in apertura del file esadecimale");
 Sleep(5000);
 exit(1);
 }
 gioco=0;
 i=0;
 while ((appoggio=fgetc(fr))!=EOF)
 {
  i=i+1;
  num=converti(appoggio);
  if ( (num < 32 || num > 51) && (num!=208) && (num!=223) &&
(num!=209) ){
   printf("\nC'e' un carattere sconosciuto, esco!\n");
   exit(1);
  }
  if ( num == 208 )
    gioco=~gioco;
  outp(PORT,num);
  Sleep(100);
  outp(PORT,nop);
  Sleep(100);
  gioco=~gioco;
  if ( gioco != 0 )
   continue;
  outp(PORT,lf);
  Sleep(100);
  outp(PORT,nop);
  Sleep(100);
 }
 printf("\n\nFine programmazione automatica.");
 lunghezza=lunghezza-1;
 printf ("\nNumero dei byte : %d",lunghezza);
 fclose(fr);//chiudo il file
 Sleep(300);
 printf("\n\n * Riabilito la tastiera");
  Sleep(3000);
  printf(".");
  Sleep(3000);
  printf(".");
  Sleep(3000);
  printf(".");
  Sleep(3000);
  printf("vai!");
  menu();
 gioco2=10;
 while(1){
  gioco2=gioco2-1;
  if ( gioco2==0 ){
   gioco2=10;
   printf("(p:stampa il menu')");
  }
  printf(" --> ");
  appoggio=getchar();
  getchar();
  printf("\n");
  num=converti(appoggio);
  if ( num==210 )
   exit(0);
  if ( (num < 32 || num > 51) && (num!=223) && (num!=50) && (num!=51)
&& (num!=49) && (num!=48))
   printf("\nCarattere non valido.\n");
  outp(PORT,num);
  Sleep(100);
  outp(PORT,nop);
  Sleep(100);
 }
}
int converti(int x){
 if ( x>='A' && x<='F' )
   x=x-23;
  else if ( x>='a' && x<='f' )
   x=x-55;
  else if ( x>='0' && x<='9' )
   x=x-16;
  else if ( x=='r' || x=='R' )
   x=51;
  else if ( x=='k' || x=='K' )
   x=50;
  else if ( x=='l' || x=='L' )
   x=49;
  else if ( x=='h' || x=='H')
   x=48;
  else if ( x=='p' || x=='P' ){
   x=223;
   menu();
  }
  else if ( x=='q' || x=='Q' )
   x=210;
  else if ( x==10 )
   x=209;
  else if ( x==' ' ){
   x=208;
  }
  else{
   x=223;
   printf("\n\nHai inserito un numero errato! Controlla il file
letto.\n");
 }
 return x;
}
void menu(){
   printf("\n\nInserisci valori esadecimali da 0 a F");
   printf("\nInserisci r per RUN");
   printf("\nInserisci k per DA");
   printf("\nInserisci l per LO");
   printf("\nInserisci h per HI");
   printf("\nInserisci p per stampare questo menu'");
   printf("\nInserisci q per uscire\n\n");
}
Sotto Linux e' leggermente diverso e va una favola, sotto windows non
riesco proprio a farlo girare.
Help.

  outp(PORT,num);
Questo dovrebbe potersi fare con:
	cli
	push	dx
	push	ax
	mov	dx, PORT
	mov	ax, num
	out	dx, al	; Credo serva un byte solo
	pop	ax
	pop	dx
	sti


 sti
Solo su Win98. Su 2000-XP serve un driver specifico per I/O. Non è possbile
accedere direttamente alle porte con l'istruzione OUT dai programmi che
girano in user mode, occorre passare in kernel mode e questo lo può fare
solo un driver.
Ciao
Luca FRanzesi

ho risolto utilizzando uno stream a PRN e usando fprintf su quello stream.
Comunque grazie lo stesso a tutti.
Buon lavoro  :)