/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\ ³ ³ ³ 765DEBUG 5.0 - M¢dulo avanzado de an lisis de disquetes. ³ ³ ³ ³ (C) 1992-1995 Ciriaco Garc¡a de Celis ³ ³ ³ \ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ #include #include #include #include #include #include #include #include "2m-info.h" #define SMAX 32768L /* mayor sector soportado por el programa */ #define CX 12 /* color para pantalla de "memoria insuficiente" */ #define CFX 0 /* color de fondo para "memoria insuficiente" */ #define C765 1 /* color de '765DEBUG' */ #define CM 15 /* color para el men£ principal */ #define CFM 3 /* color de fondo para el men£ principal */ #define C3D 10 /* color para el marco 3D */ #define CB 2 /* color para la banda de fondo del marco 3D */ #define CTIT 14 /* color del t¡tulo superior */ #define CVER 4 /* color de la versi¢n */ #define CB1 5 /* color 1 para botones del men£ principal */ #define CB2 7 /* color 2 para botones del men£ principal */ #define CTB1 15 /* color 1 para tinta de botones del men£ principal */ #define CTB2 0 /* color 2 para tinta de botones del men£ principal */ #define CI 1 /* color para informe en men£ principal */ #define CMI 11 /* color para el marco del informe en men£ principal */ #define CS 15 /* color para confirmar salida */ #define CFS 6 /* color de fondo para confirmar salida */ #define CD 15 /* color para advertencia del tama¤o buffer DMA */ #define CFD 6 /* color de fondo advertencia tama¤o buffer DMA */ #define CR 15 /* color para "ayuda" */ #define CDR 14 /* color para direcci¢n en "ayuda" */ #define CFR 5 /* color de fondo para "ayuda" */ #define CL 15 /* color para LeerSector */ #define CFL 4 /* color de fondo para LeerSector */ #define CE 15 /* color para EscribirSector */ #define CFE 4 /* color de fondo para EscribirSector */ #define CF 15 /* color para FormatearPista */ #define CFF 5 /* color de fondo para FormatearPista */ #define CIW 15 /* color para 'Leyendo ID's...' */ #define CFIW 4 /* color de fondo para 'Leyendo ID's...' */ #define CFI 0 /* color de fondo para lectura de ID's */ #define CIC 14 /* color cabecera de lectura ID's */ #define CFIC 4 /* color de fondo cabecera de lectura ID's */ #define CIMS 15 /* color para milisegundos en lectura ID's */ #define CIS 12 /* color para sector en lectura ID's */ #define CIT 10 /* color para tama¤os en lectura ID's */ #define CICC 14 /* color para cilindro/cabezal en lectura ID's */ #define CIST 13 /* color para registros STx en lectura ID's */ #define CIB 9 /* color para mensaje barra en lectura ID's */ #define CRS 15 /* color para resultados R/W/F */ #define CFRS 5 /* color de fondo para resultados R/W/F */ #define CFV 1 /* color de fondo para ver buffer */ #define CFVM 3 /* color de fondo del menu de ver buffer */ #define CVMM 0 /* color del marco del menu de ver buffer */ #define CVMI 1 /* color del texto del menu de ver buffer */ #define CVMS 10 /* color de la ayuda para salir del menu de ver buffer */ #define CVMD 15 /* color de la informaci¢n del menu de ver buffer */ #define CVD 15 /* color para direcciones en ver buffer */ #define CVH 11 /* color para datos hexadecimales en ver buffer */ #define CVS 15 /* color para gui¢n separador en ver buffer */ #define CVA 15 /* color para datos ASCII en ver buffer */ #define CVNS 15 /* color para pedir nueva secci¢n en ver buffer */ #define CFVNS 4 /* color de fondo para pedir nueva secci¢n en ver buffer */ #define CVNB 15 /* color para pedir nuevo tama¤o en ver buffer */ #define CFVNB 5 /* color de fondo para pedir nuevo tama¤o en ver buffer */ #define CVA 15 /* color para ayuda en ver buffer */ #define CFVA 6 /* color de fondo para ayuda en ver buffer */ #define C2M 15 /* color para informaci¢n de disco 2M */ #define CF2M 6 /* color de fondo para informaci¢n de disco 2M */ extern void EsperaDma0 (int); extern void MoveMem (char huge *, char huge *, unsigned); extern int es386 (void); extern unsigned rnd (unsigned); int HablaSp (void), infdc (void), EsperarInt (void), EsOS2 (void), PeligrosoOS2 (void), Hay2M3 (void), CodePage437 (void), SalirConfirmado (void), EditarTablaFmt (unsigned char *, int), input (char *, int, int, int, int), Tecla (void), TipoDrive (int), hextoi (char *); void Vram (int), TestDMA (int), CursorOff (void), BrilloOn (void), DibujaOpciones (void), DibujaValores (int, int, int, int, int), Marco3df (int, int, int, int, int, int, int), Marco3dg (int, int, int, int, int, int, int, int), v3dg (int, int, int, int, int, int, int, int, int), v3df (int, int, int, int, int, int, int, int), v3d (int, int, int, int, int), ventana (int, int, int, int, int, int, int), boton (int, int, int, int, int, int, char *), Informe2M (int, int *, int *, int), SeleccionarUnidad (int, int), ResetUnidad (int), DensidadSpecify (int), recalibrar (int, int, int, int), posicionar (int, int, int, int), LeerSector (int, int, int, int, char huge *, unsigned *, int), LeerPista (int, int, int, int, char huge *, unsigned *, int), EscribirSector (int, int, int, int, int, unsigned *, char huge *), FormatearPista (int, int, int, int, int), LeerIds (int, int, int, int), Resultados (int, int, int), MostrarBuffer (char huge *, unsigned *), MotorOn (int), MotorOff (void), outfdc (unsigned char), PreparaDma (unsigned, unsigned, char huge *); char *hex2str (int), *dec2str (unsigned), *dec3str (unsigned), *dec5str (unsigned), *dec2strq (unsigned), *dec3strq (unsigned), *dec5strq (unsigned), *ReservarMemoria (char huge **); unsigned long VDMA (unsigned *); int sp; /* 1-espa¤ol 0-ingl‚s */ char *KeybShifts = MK_FP (0x40, 0x17); extern void interrupt NuevaInt0E (void); void main (int argc, char **argv) { char huge *buffer, /* buffer para sector */ huge *bloque, cad[32]; int unidad=0, vunidad[2], mf_mfm[2], cabezal[2], cilindro[2], opc, t, tp, opcion, dmakb, refrescar, avisos=1, discos=1, SalirEnOS2=0; static PrimeraVez=1; unsigned bytes=0; void interrupt (*ViejaInt0E) (void); sp = HablaSp(); if (argc>1) if ((!strcmp(argv[1], "/I") || !strcmp(argv[1], "/i"))) sp ^=1; else { printf ("\n765DEBUG 5.0 (C) 1992-1995 Ciriaco Garc¡a de Celis.\n"); if (sp) printf(" M¢dulo avanzado de an lisis de disquetes.\n" " Indique /I para conmutar el idioma.\n"); else printf(" Advanced low level disk analysis utility.\n" " Use the /I switch to change the language.\n"); exit (0); } Vram (PRESERVAR); Vram (MODO80); /* asegurar modo texto de 80 columnas */ ViejaInt0E=getvect(0x0E); setvect (0x0E, NuevaInt0E); if (*KeybShifts & 3) PrimeraVez = 0; /* con SHIFT, evitar avisos */ mf_mfm[0]=mf_mfm[1]=1; cabezal[0]=cabezal[1]=cilindro[0]=cilindro[1]=0; dmakb=7; for (t=0; t<=1; t++) { tp = TipoDrive (t); if ((tp >= 5) && (dmakb < 26)) dmakb=26; /* 2.88M */ if ((tp == 4) && (dmakb < 13)) dmakb=13; /* 1.44M */ if ((tp == 2) && (dmakb < 11)) dmakb=11; /* 1.2M */ switch (tp) { case 1: vunidad[t]=1; break; /* 360K */ case 3: vunidad[t]=2; break; /* 720K */ default: vunidad[t]=0; break; /* resto de unidades */ } } t=TipoDrive(1); /* -1 si falla */ if (t==-1) t=peekb(0x40, 0x10) >> 6; /* n§ unidades-1 */ if (t) discos++; /* n§ unidades disquete */ if ((bloque=ReservarMemoria (&buffer))!=NULL) { opcion=0; refrescar=1; do { BrilloOn(); if (refrescar) { DibujaOpciones(); refrescar=0; } if (avisos) { avisos=0; if (PrimeraVez) SalirEnOS2=PeligrosoOS2(); if (SalirEnOS2) { opcion=SALIR; break; } if (PrimeraVez) TestDMA (dmakb); recalibrar (0, 0, 0, 0); /* recalibrar unidades al */ if (discos>1) /* entrar en el programa */ recalibrar (1, 0, 0, 0); SeleccionarUnidad (unidad, vunidad[unidad]); /* por defecto */ } DibujaValores (unidad, vunidad[unidad], mf_mfm[unidad], cilindro[unidad], cabezal[unidad]); CursorOff(); opc=getch(); if (!opc) opc=getch() << 8; /* usar Tecla() borrar¡a el buffer */ switch (opc) { case '0': recalibrar (0, cabezal[0], vunidad[0], 1); if (discos>1) recalibrar (1, cabezal[1], vunidad[1], 1); cilindro[0]=cilindro[1]=0; SeleccionarUnidad (unidad, vunidad[unidad]); break; case '1': unidad ^= 1; SeleccionarUnidad (unidad, vunidad[unidad]); break; case '2': vunidad[unidad]++; if (vunidad[unidad]>3) vunidad[unidad]=0; DensidadSpecify (vunidad[unidad]); break; case '3': gotoxy (64, 18); strcpy (cad, dec2strq (cilindro[unidad])); if (input (cad, 1, 2, CI, CFM)) { cilindro[unidad] = atoi (cad); posicionar (unidad, cabezal[unidad], cilindro[unidad], vunidad[unidad]); } break; case '4': cabezal[unidad]^=1; break; case '5': LeerIds (unidad, mf_mfm[unidad], cabezal[unidad], vunidad[unidad]); refrescar=1; break; case '6': LeerSector (unidad, mf_mfm[unidad], cilindro[unidad], cabezal[unidad], buffer, &bytes, vunidad[unidad]); break; case '7': EscribirSector (unidad, mf_mfm[unidad], vunidad[unidad], cilindro[unidad], cabezal[unidad], &bytes, buffer); break; case '8': MostrarBuffer (buffer, &bytes); refrescar=1; break; case '9': FormatearPista (unidad, mf_mfm[unidad], vunidad[unidad], cilindro[unidad], cabezal[unidad]); break; case 'a': case 'A': mf_mfm[unidad]^=1; break; case 'i': case 'I': Informe2M (unidad, &cilindro[unidad], &cabezal[unidad], vunidad[unidad]); break; case 0x1B: if (SalirConfirmado()) opcion=SALIR; break; /* ESC */ case 0x2D00: opcion=SALIR; break; /* ALT-X */ case 0x4400: LeerPista (unidad, mf_mfm[unidad], /* F10 */ cilindro[unidad], cabezal[unidad], buffer, &bytes, vunidad[unidad]); break; case 0x3B00: ventana (ABRIR, 3, 3, 77, 22, CR, CFR); /* F1 */ if (sp) { gotoxy ( 2, 1); cputs(" El acceso directo a la controladora puede dejar ‚sta en situaci¢n no"); gotoxy ( 2, 2); cputs("estable en caso de error (por ejemplo, abortando una lectura de ID's"); gotoxy ( 2, 3); cputs("que falla). En ese caso las dem s ¢rdenes podr¡an fallar inicialmente."); gotoxy ( 2, 4); cputs("Si es preciso, ejecute un reset y recalibre las unidades (opci¢n 0)."); gotoxy ( 2, 6); cputs(" No se limitan, intencionadamente, algunas acciones aparentemente"); gotoxy ( 2, 7); cputs("il¢gicas por parte del usuario, con objeto de lograr una herramienta de"); gotoxy ( 2, 8); cputs("mayor potencia. En general, pulsando INTRO cuando no se sabe qu‚ hacer,"); gotoxy ( 2, 9); cputs("en la mayor¡a de las ocasiones las decisiones se toman autom ticamente."); gotoxy ( 2,11); cputs(" Si durante las operaciones con un disco de prueba se baja la l¡nea de"); gotoxy ( 2,12); cputs("cambio, la BIOS podr¡a no detectar luego el soporte. Si tiene problemas"); gotoxy ( 2,13); cputs("con dicho disquete al salir al DOS, s quelo y vuelva a introducirlo."); textcolor (CDR); gotoxy (21,15); cputs ("¨Usuario *REGISTRADO* con problemas?"); gotoxy (20,16); cputs ("Mis buzones de correo electr¢nico son:"); } else { gotoxy ( 2, 1); cputs(" The direct access to diskette drive controller can leave it in an"); gotoxy ( 2, 2); cputs("undefined state if an error occurs (for example after aborting a failed"); gotoxy ( 2, 3); cputs("Read IDs command). In such cases the subsequent functions may initially"); gotoxy ( 2, 4); cputs("fail. If needed, you can reset and recalibrate the drives (option 0)."); gotoxy ( 2, 6); cputs(" Some apparently incorrect actions performed by the user are"); gotoxy ( 2, 7); cputs("intentionally not skipped, in order to increase the power of this"); gotoxy ( 2, 8); cputs("program. Generally, press the ENTER key when you don't know what to do;"); gotoxy ( 2, 9); cputs("in most cases, your decisions are automatically adopted by the program."); gotoxy ( 2,11); cputs(" If during some disk operations the disk change line is reset, system"); gotoxy ( 2,12); cputs("BIOS may not always be able to detect the disk media in further access."); gotoxy ( 2,13); cputs("If you have problems after exiting to DOS, remove & insert the disk."); textcolor (CDR); gotoxy (21,15); cputs ("A *REGISTERED* user with problems?"); gotoxy (24,16); cputs ("My electronic mailboxes are:"); } gotoxy (2,18); cputs ("Internet ciri@gui.uva.es - Compuserve 100657,1253 - Fidonet: 2:341/21.8"); CursorOff(); Tecla(); ventana (CERRAR, 3, 3, 77, 22, 0, 0); break; } } while (opcion!=SALIR); } if ((!SalirEnOS2) && (bloque!=NULL)) { pokeb (0x40, 0x94, cilindro[0]); pokeb (0x40, 0x95, cilindro[1]); outportb (FD_DCR, peekb(0x40, 0x8B) >> 6); /* velocidad normal */ } if (bloque!=NULL) farfree ((char far *) bloque); setvect (0x0E, ViejaInt0E); Vram (RESTAURAR); PrimeraVez=0; /* evitar avisos molestos en pr¢ximas ejecuciones */ } void Vram (int operacion) { static scr_ok, modo, pag, cx, cy, colorbits; static long tam; static char *scrbuf; union REGS regs; if (operacion==PRESERVAR) { scr_ok=0; modo=peekb(0x40, 0x49) & 0x7F; if (peekb(0x40, 0x84) < 24) pokeb(0x40, 0x84, 24); pag=peekb(0x40,0x62); cx=peekb(0x40,0x50+pag*2); cy=peekb(0x40,0x51+pag*2); colorbits=peek(0x40, 0x10) & 0x30; tam = 2L * (peekb(0x40, 0x84) + 1) * peek (0x40, 0x4A); if (tam > 32768L) tam=32768L; if ((modo<=3)||(modo==7)) { if ((scrbuf=farmalloc(tam))!=NULL) { scr_ok=1; movedata ((modo==7) ? 0xb000: 0xb800, (modo==7) ? 0 : peek(0x40, 0x4e), FP_SEG(scrbuf), FP_OFF(scrbuf), tam); } } if ((modo!=3) && (modo!=7)) textmode ((modo!=7) ? C80:MONO); } else if ((operacion==RESTAURAR) || (operacion==MOSTRAR)) { poke (0x40, 0x10, peek(0x40, 0x10) & 0xFFCF | colorbits); if (modo != (peekb(0x40, 0x49) & 0x7F)) { regs.x.ax=modo; int86 (0x10, ®s, ®s); } else { regs.x.ax=0x1003; regs.x.bx=1; int86 (0x10, ®s, ®s); } regs.x.ax=0x500+pag; int86 (0x10, ®s, ®s); regs.x.ax=0x200; regs.x.bx=pag<<8; regs.h.dh=cy; regs.h.dl=cx; int86 (0x10, ®s, ®s); if (scr_ok) { movedata (FP_SEG(scrbuf), FP_OFF(scrbuf), (modo==7) ? 0xb000 : 0xb800, (modo==7) ? 0 : peek(0x40, 0x4e), tam); if (operacion==RESTAURAR) farfree(scrbuf); } } else if ((operacion==MODO80)) { poke (0x40, 0x10, peek(0x40, 0x10) & 0xFFCF | colorbits); if (((peekb(0x40, 0x49) & 0x7F) == 0x13) || ((modo!=3) && (modo!=7))) textmode ((modo!=7) ? C80:MONO); if ((scr_ok) && ((modo==2) || (modo==3) || (modo==7))) movedata (FP_SEG(scrbuf), FP_OFF(scrbuf), (modo==7) ? 0xb000 : 0xb800, (modo==7) ? 0 : peek(0x40, 0x4e), tam); } } char *ReservarMemoria (char huge **buffer) { unsigned long dir; char *bloque, *bf; *buffer=bloque=farmalloc(SMAX << 1); bf=farmalloc(4096L); if ((*buffer==NULL) || (bf==NULL)) { if (*buffer!=NULL) farfree ((char far *) *buffer); textbackground (CFX); textcolor (CX); clrscr(); gotoxy (24,12); if (sp) cputs ("Memoria insuficiente para 765DEBUG"); else cputs ("Insufficient memory for 765DEBUG"); CursorOff(); delay (2000); return (NULL); } farfree (bf); /* liberar bloque "de seguridad" */ dir = ((unsigned long) FP_SEG(*buffer) <<4) + FP_OFF(*buffer); if ( (dir>>16) != ( (dir+SMAX) >> 16) ) *buffer+=SMAX; /* evitar buffer entre dos p ginas de DMA */ return (bloque); } void DibujaOpciones() { textbackground (CFM); textcolor(CM); clrscr(); v3dg (3, 2, 76, 12, 1, 2, C3D, CFM, CB); v3d (3, 2, 76, 12, 2); textcolor (C765); gotoxy (2,1); cputs("ÛßßßÛ ÛßßÛÛ Ûßßßß Û Û "); textcolor(CVER); cputs(" ÜÜÜÜÜ ÜÜÜÜÜ"); textcolor (C765); gotoxy (2,2); cputs(" Û Û Û Û Û ÜÜÜÜÜÄÅÄ"); textcolor(CVER); cputs(" Û Û Û"); textcolor (C765); gotoxy (2,3); cputs(" ÛÛ ÛßßÛÛ ßßßÛÛ ÛßßßÛ ÛßßßÛ ÛßßßÛ Û Û Û Û "); textcolor(CVER); cputs(" ßßßÛÛ Û ÛÛ"); textcolor (C765); gotoxy (2,4); cputs(" ÛÛ Û ÛÛ ÛÛ Û Û Ûßßßß Û Û Û Û Û Û "); textcolor(CVER); cputs(" Ü ÛÛ Û ÛÛ"); textcolor (C765); gotoxy (2,5); cputs(" ßß ßßßßß ßßßßß ßßßßß ßßßßß ßßßßß ßßßßß ßßßßÛ "); textcolor(CVER); cputs(" ßßßßß ß ßßßßß"); textcolor (C765); gotoxy (2,6); cputs(" ÛÜÛ "); gotoxy (2,6); textcolor (CTIT); if (sp) cputs("ANALISIS AVANZADO A BAJO NIVEL DE DISQUETES"); else cputs(" ADVANCED LOW LEVEL DISK ANALYSIS UTILITY"); window (1,1,80,25); if (sp) { boton ( 3,15,CB1,CTB1,CM,CFM," 0 "); cputs (" Recalibrar unidades + reset."); boton ( 3,16,CB2,CTB2,CM,CFM," 1 "); cputs (" Seleccionar unidad."); boton ( 3,17,CB1,CTB1,CM,CFM," 2 "); cputs (" Seleccionar densidad + enviar specify."); boton ( 3,18,CB2,CTB2,CM,CFM," 3 "); cputs (" Posicionar cabezal."); boton ( 3,19,CB1,CTB1,CM,CFM," 4 "); cputs (" Cambiar de cabezal."); boton ( 3,20,CB2,CTB2,CM,CFM," 5 "); cputs (" Leer ID's."); boton ( 3,21,CB1,CTB1,CM,CFM," 6 "); cputs (" Leer sector al buffer interno."); boton ( 3,22,CB2,CTB2,CM,CFM," 7 "); cputs (" Escribir sector del buffer interno."); boton ( 3,23,CB1,CTB1,CM,CFM," 8 "); cputs (" Ver o editar sector del buffer interno."); boton ( 3,24,CB2,CTB2,CM,CFM," 9 "); cputs (" Formatear pista."); boton (51,21,CB2,CTB2,CM,CFM,"F10"); cputs (" Leer pista cruda."); boton (51,22,CB1,CTB1,CM,CFM," A "); cputs (" Conmutar MF/MFM."); boton (51,23,CB2,CTB2,CM,CFM," I "); cputs (" Informaci¢n disco 2M."); boton (51,24,CB1,CTB1,CM,CFM,"ESC"); cputs (" Salir (ALT-X r pido)."); } else { boton ( 3,15,CB1,CTB1,CM,CFM," 0 "); cputs (" Recalibrate drives & reset."); boton ( 3,16,CB2,CTB2,CM,CFM," 1 "); cputs (" Select drive."); boton ( 3,17,CB1,CTB1,CM,CFM," 2 "); cputs (" Select density & send specify."); boton ( 3,18,CB2,CTB2,CM,CFM," 3 "); cputs (" Seek to new track."); boton ( 3,19,CB1,CTB1,CM,CFM," 4 "); cputs (" Select other head."); boton ( 3,20,CB2,CTB2,CM,CFM," 5 "); cputs (" Read ID's."); boton ( 3,21,CB1,CTB1,CM,CFM," 6 "); cputs (" Read sector into internal buffer."); boton ( 3,22,CB2,CTB2,CM,CFM," 7 "); cputs (" Write internal buffer's sector."); boton ( 3,23,CB1,CTB1,CM,CFM," 8 "); cputs (" View or edit internal buffer's sector."); boton ( 3,24,CB2,CTB2,CM,CFM," 9 "); cputs (" Format track."); boton (51,21,CB2,CTB2,CM,CFM,"F10"); cputs (" Read a raw track."); boton (51,22,CB1,CTB1,CM,CFM," A "); cputs (" Change MF/MFM."); boton (51,23,CB2,CTB2,CM,CFM," I "); cputs (" 2M disk information."); boton (51,24,CB1,CTB1,CM,CFM,"ESC"); cputs (" Exit (ALT-X quit!)."); } v3df (51, 14, 27, 7, 1, 1, CMI, CFM); } void DibujaValores (unidad, vunidad, mf_mfm, cilindro, cabezal) { textcolor (CI); textbackground (CFM); gotoxy (57, 16); if (sp) cputs("Unidad "); else cputs("Drive "); putch(unidad+'A'); putch(':'); if (mf_mfm) cputs(" MFM"); else cputs(" MF"); gotoxy (55, 17); switch (vunidad) { case 2: cputs ("250 Kbps"); break; case 1: cputs ("300 Kbps"); break; case 0: cputs ("500 Kbps"); break; default: cputs (" 1 Mbps"); break; } switch (vunidad) { case 1: cputs(" ..... 360K"); break; case 2: cputs(" ..... 720K"); break; case 3: cputs(" .... 2.88M"); break; default: cputs(" 1.2/1.44M"); break; } gotoxy (55, 18); if (sp) cputs("Cilindro "); else cputs("Cylinder "); cputs (dec2strq(cilindro)); cputs(" "); gotoxy (68, 18); if (sp) cputs("Cara "); else cputs("Side "); cputs (dec2strq(cabezal)); } int PeligrosoOS2() { int largarse=0, t; if (EsOS2()) { ventana (ABRIR, 15, 8, 64, 19, CS, CFS); if (sp) { gotoxy (5, 2); cputs("Esta sesi¢n DOS est  corriendo bajo OS/2"); gotoxy (5, 4); cputs("765DEBUG puede funcionar bajo OS/2, pero"); gotoxy (3, 5); cputs("sus continuos accesos al hardware de disco y"); gotoxy (3, 6); cputs("el control que realiza OS/2 de los puertos"); gotoxy (3, 7); cputs("convierten la tarea en algo conflictiva."); gotoxy (8, 9); cputs("INTRO - CONTINUAR ESC - SALIR"); } else { gotoxy (6, 2); cputs("This DOS session is running under OS/2"); gotoxy (5, 4); cputs("765DEBUG can work with OS/2 loaded, but it"); gotoxy (3, 5); cputs("continually accesses disk hardware directly,"); gotoxy (3, 6); cputs("and the I/O ports control performed by OS/2"); gotoxy (3, 7); cputs("cause its functions to conflict somewhat."); gotoxy (8, 9); cputs("ENTER - CONTINUE ESC - EXITS"); } CursorOff(); t = Tecla(); if (t!=13) largarse=1; ventana (CERRAR, 15, 8, 64, 19, 0, 0); } return (largarse); } void TestDMA (int dmakb) { unsigned emm; unsigned long bytes; if ((bytes=VDMA(&emm)) < 1024L*dmakb) { ventana (ABRIR, 21, 6, 61, 20, CD, CFD); if (sp) { gotoxy (17,1); cputs("AVISO"); gotoxy (2, 3); cputs("El buffer para transferencias con DMA"); gotoxy (2, 4); cputs("de su controlador de memoria admite"); gotoxy (2, 5); cputs("s¢lo "); cputs (dec5strq((unsigned) bytes)); cputs (" bytes ("); cputs(dec2strq((unsigned) bytes/1024)); cputs(" Kb)."); gotoxy (2, 7); cputs("El sistema podr¡a estrellarse o puede"); gotoxy (2, 8); cputs("salir un mensaje de su controlador de"); gotoxy (2, 9); cputs("memoria si trabaja con sectores de un"); gotoxy (2,10); cputs("tama¤o superior (y s¢lo en ese caso)."); if (emm == 20805) { gotoxy (2,12); cputs("Con su controlador (QEMM) bastar¡a en"); gotoxy (2,13); cputs("ese caso a¤adir la opci¢n DMA=Kbytes."); } } else { gotoxy (16,1); cputs("WARNING"); gotoxy (2, 3); cputs("The current maximum DMA buffer size"); gotoxy (2, 4); cputs("supported by your memory manager has"); gotoxy (2, 5); cputs("only "); cputs (dec5strq((unsigned) bytes)); cputs (" bytes ("); cputs(dec2strq((unsigned) bytes/1024)); cputs(" Kb)."); gotoxy (2, 7); cputs("The system may hang; or your memory"); gotoxy (2, 8); cputs("manager may print an error message if"); gotoxy (2, 9); cputs("you work with sectors bigger than the"); gotoxy (2,10); cputs("buffer size (and only in this case)."); if (emm == 20805) { gotoxy (2,12); cputs("With your EMM (QEMM) you can add, if"); gotoxy (2,13); cputs("needed, a DMA=Kbytes option."); } } CursorOff(); getch(); ventana (CERRAR, 21, 6, 61, 20, 0, 0); } } unsigned long VDMA (unsigned *emm) { union REGS r; struct SREGS s; unsigned long bytes; bytes = 65536L; /* supuesto que no hay problemas con el DMA */ *emm = 0; /* supuesto que no hay controlador de memoria */ if (es386()) { r.x.ax = 0x354B; int86x (0x21, &r, &r, &s); if ((s.es | r.x.bx) && (s.es != 0xFFFF) && (r.x.bx != 0xFFFF)) { r.x.ax = 0x8102; r.x.dx = r.x.si = r.x.di = 0; int86 (0x4B, &r, &r); if ((!(r.x.flags & 1)) && (r.x.si | r.x.di)) { bytes = ((unsigned long) r.x.si << 16) | r.x.di; *emm = r.x.bx; } } } return (bytes); } int SalirConfirmado() { int salir, t; t = peekb(0x40, 0x49) & 0x7F; ventana (ABRIR, 27, 9, 60, 15, CS, CFS); textcolor (CS); if (sp) { gotoxy (5,2); cputs("¨Seguro que desea salir?"); gotoxy (4,4); cputs("Pulse "); } else { gotoxy (2,2); cputs("Are you sure you want to exit?"); gotoxy (4,4); cputs("Press "); } if (t!=7) { textcolor (CFS+BLINK); textbackground (CS); } else { textcolor (0); textbackground (7); } if (sp) { cputs ("INTRO"); textcolor (CS); textbackground (CFS); cputs(" para confirmar"); } else { cputs ("ENTER"); textcolor (CS); textbackground (CFS); cputs(" key to confirm"); } CursorOff(); t=Tecla(); if ((t==13) || (t==0x2D00)) salir=1; else salir=0; ventana (CERRAR, 27, 9, 60, 15, 0, 0); return (salir); } void Informe2M (int unidad, int *cilindro, int *cabezal, int vunidad) { Boot sector0, virtual; int i, error, anio, mes, dia, hora, min, seg, dif; *cilindro = *cabezal = 0; /* terminaremos en pista 0 */ outportb (FD_DCR, peekb(0x40, 0x8B) >> 6); /* velocidad normal */ ventana (ABRIR, 22, 7, 57, 16, C2M, CF2M); if (sp) { gotoxy (9, 1); cputs("INFORME UNIDAD "); putch(unidad+'A'); putch(':'); } else { gotoxy (10,1); cputs("DRIVE "); putch(unidad+'A'); putch(':'); cputs(" REPORT"); } if (!Hay2M3()) { if (sp) { gotoxy (5,4); cputs("2M ¢ 2MX 3.X no instalado"); gotoxy (8,6); cputs("Imposible informar"); } else { gotoxy (6,4); cputs("2M ¢ 2MX 3.X not loaded"); gotoxy (5,6); cputs("Information not available"); } } else { error=biosdisk(2, unidad, 0x80, 0, 1, 1, §or0); if (error) { biosdisk (0, unidad, 0, 0, 1, 1, §or0); error=biosdisk(2, unidad, 0x80, 0, 1, 1, §or0); } if (error) error=biosdisk(2, unidad, 0x80, 0, 1, 1, §or0); if (error==4) { if (sp) { gotoxy (4,5); cputs("El disquete no es de tipo 2M"); } else { gotoxy (4,5); cputs("Diskette is not 2M formatted"); } } else if (error) { if (sp) { gotoxy (8,4); cputs("Unidad no preparada"); gotoxy (8,5); cputs("o disquete extra¤o."); } else { gotoxy (10,4); cputs("Drive not ready"); gotoxy (7,5); cputs("or strange disk format."); } } else { gotoxy (3,3); if (sp) cputs("Tipo de disco: "); else cputs("Disk type: "); for (i=0; i<8; i++) putch(sector0.IdSis[i]); gotoxy (3,4); if (sp) cputs("Capacidad: "); else cputs("Disk size: "); cputs (dec5strq(sector0.NumSect/(1024/sector0.BytesSect))); cputs(" Kb"); gotoxy (3,5); if (sp) cputs("Versi¢n formato: "); else cputs("Format release: "); cputs (dec2strq(sector0.VersionFmt)); gotoxy (3,6); if (sp) cputs("Fecha formateo: "); else cputs("Format date: "); if (sector0.Flags & 1) { anio=1980+(sector0.FechaF>>9); mes=(sector0.FechaF>>5) & 15; dia=sector0.FechaF & 31; if (sp) { cputs (dec2strq(dia)); putch('/'); cputs (dec2str(mes)); putch('/'); cputs (dec5strq(anio)); } else { cputs (dec2strq(mes)); putch('/'); cputs (dec2str(dia)); putch('/'); cputs (dec5strq(anio)); } } else { if (sp) cputs("No disponible"); else cputs("Not available"); } gotoxy (3,7); if (sp) cputs("Hora formateo: "); else cputs("Format time: "); if (sector0.Flags & 1) { hora=sector0.HoraF>>11; min=(sector0.HoraF>>5) & 63; seg=(sector0.HoraF & 31) << 1; cputs (dec2str(hora)); putch(':'); cputs (dec2str(min)); putch(':'); cputs (dec2str(seg)); } else { if (sp) cputs("No disponible"); else cputs("Not available"); } } } CursorOff(); i = Tecla(); ventana (CERRAR, 22, 7, 57, 16, 0, 0); SeleccionarUnidad (unidad, vunidad); /* restaurar condiciones iniciales */ } void SeleccionarUnidad (unidad, vunidad) { pokeb(0x40,0x40,0xFF); outportb (FD_DOR, 1<<(unidad+4) | 4+8 | unidad); pokeb (0x40, 0x3F, peekb(0x40, 0x3F) | (1 << unidad)); DensidadSpecify (vunidad); MotorOff(); } void ResetUnidad (unidad) { int i, vez; for (vez=0; vez<2; vez++) { pokeb (0x40, 0x3E, peekb (0x40, 0x3E) & 0x7F); /* asegurar detecci¢n */ outportb (0x20, 0x66); /* muy largo de explicar :-) */ outportb (FD_DOR, 1<<(unidad+4) | unidad | 8); /* reset */ delay (10); outportb (FD_DOR, 1<<(unidad+4) | unidad | 8+4); /* fin reset */ if (EsperarInt()) { /* esperar interrupci¢n (si viene) */ outfdc (8); /* comando 'leer estado de interrupciones' */ (void) infdc(); /* leer y desechar resultado */ (void) infdc(); break; /* reset con ‚xito */ } } MotorOff(); } void DensidadSpecify (int vunidad) { outportb (FD_DCR, vunidad); /* seleccionar densidad */ outfdc (3); /* comando Specify */ if (vunidad==3) outfdc (0xAF); /* tiempo de acceso pista-pista y head unload */ else if (!vunidad) outfdc (0xBF); else outfdc (0xDF); outfdc (2); /* head load time = 1; modo DMA */ } void recalibrar (unidad, cabezal, vunidad, pausa) { int recal, res, pis; ventana (ABRIR, 30, 10, 50, 17, 15, 1); gotoxy (3, 3); if (sp) cputs("Recalibrando "); else cputs("Recalibrate "); putch(unidad+'A'); putch(':'); CursorOff(); MotorOn (unidad); /* asegurar que el motor est  en marcha */ SeleccionarUnidad (unidad, vunidad); MotorOn (unidad); ResetUnidad (unidad); /* aprovechar para resetear */ DensidadSpecify (vunidad); /**** Recalibrar hasta dos veces si es preciso ****/ for (recal=0; recal<2; recal++) { outfdc (7); /* comando de recalibrado */ outfdc (cabezal << 2 | unidad); /* byte 1 de dicho comando */ EsperarInt(); /* esperar interrupci¢n */ outfdc (8); /* comando 'leer estado de interrupciones' */ res=infdc(); /* leer resultado */ pis=infdc(); if (!recal) clrscr(); gotoxy (5, 1+recal*2); if ((res>=0) && (pis>=0)) { cputs ("ST0 = 0x"); cputs (hex2str(res)); gotoxy (5, 2+recal*2); if (sp) cputs ("Pista = "); else cputs ("Track = "); cputs (dec2strq(pis)); } else cputs ("ST0 = ??"); if (!((res ^ 32) & (0xF0))) break; /* resultado correcto */ } MotorOff(); if (recal<2) { /* sin fallo */ CursorOff(); if (pausa) delay(750); } else { gotoxy (3, 6); if (sp) cputs ("Pulsa una tecla"); else cputs (" Press any key "); CursorOff(); Tecla(); } ventana (CERRAR, 30, 10, 50, 17, 0, 0); } void posicionar (unidad, cabezal, cilindro, vunidad) { int res, pis; ventana (ABRIR, 30, 9, 50, 14, 15, 1); gotoxy (3, 2); if (sp) cputs("Posicionando "); else cputs(" Seek "); putch(unidad+'A'); putch(':'); CursorOff(); MotorOn (unidad); /* asegurar que el motor est  en marcha */ SeleccionarUnidad (unidad, vunidad); MotorOn (unidad); /**** Desplazar cabezal hasta la pista ****/ outfdc (0xF); /* comando 'Seek' */ outfdc (cabezal << 2 | unidad); /* byte 1 de dicho comando */ outfdc (cilindro); EsperarInt(); /* esperar interrupci¢n */ outfdc (8); /* comando 'leer estado de interrupciones' */ res=infdc(); pis=infdc(); clrscr(); gotoxy (5, 1); if ((res>=0) && (pis>=0)) { cputs ("ST0 = 0x"); cputs (hex2str(res)); gotoxy (5, 2); if (sp) cputs ("Pista = "); else cputs ("Track = "); cputs (dec2strq(pis)); gotoxy (3, 4); } else cputs ("ST0 = ??"); MotorOff(); if (!(res & 0xC0)) { CursorOff(); delay(750); } else { if (sp) cputs ("Pulsa una tecla"); else cputs (" Press any key "); CursorOff(); Tecla(); } ventana (CERRAR, 30, 9, 50, 14, 0, 0); } void LeerSector (unidad, mf_mfm, cilindro, cabezal, buffer, bytes, vunidad) char huge *buffer; unsigned *bytes; { static sector=1, nsects=1, tsector=2, t128=128; unsigned t, sbytes; char cad[32]; ventana (ABRIR, 23, 7, 65, 21, CL, CFL); if (sp) { gotoxy (12,1); cputs("LECTURA DE SECTOR"); } else { gotoxy (16,1); cputs("SECTOR READ"); } gotoxy (2,3); cputs("Sector: "); strcpy (cad, dec3strq (sector)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaLectura; sector = atoi (cad); if (sector>255) sector=255; gotoxy (2, 5); if (sp) cputs("Tama¤o de sector:"); else cputs("Sector size:"); gotoxy (2, 6); cputs(" 0 -> 1-128 bytes 5 -> 4096 bytes"); gotoxy (2, 7); cputs(" 1 -> 256 bytes 6 -> 8192 bytes"); gotoxy (2, 8); cputs(" 2 -> 512 bytes 7 -> 16384 bytes"); gotoxy (2, 9); cputs(" 3 -> 1024 bytes 8 -> 32768 bytes"); gotoxy (2,10); cputs(" 4 -> 2048 bytes Val"); if (sp) cputs("or: "); else cputs("ue: "); strcpy (cad, dec2strq (tsector)); if (!input (cad, 1, 2, CL, CFL)) goto AbortaLectura; tsector = atoi (cad); if (tsector==0) { gotoxy (24, 10); if (sp) cputs("Indica"); else cputs("Select"); cputs(" 1-128: "); strcpy (cad, dec3strq (t128)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaLectura; t128 = atoi (cad); if (t128>255) t128=255; else if (!t128) t128=1; } sbytes = tsector? (unsigned) 128 << tsector: t128; gotoxy (sp?19:16, 3); cputs(sp?"N§ de sectores: ":"Number of sectors: "); strcpy (cad, dec3strq (nsects)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaLectura; nsects = atoi (cad); if (!nsects || (nsects > SMAX/sbytes)) { if (!nsects) nsects=1; else nsects=SMAX/sbytes; gotoxy (sp?19:16, 3); cputs(sp?"N§ de sectores: ":"Number of sectors: "); cputs (dec3strq(nsects)); cputs(" "); } gotoxy (7,12); if (sp) cputs("Cilindro: "); else cputs("Cylinder: "); strcpy (cad, dec3strq (cilindro)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaLectura; cilindro = atoi (cad); if (cilindro>255) cilindro=255; gotoxy (25,12); if (sp) cputs("Cara: "); else cputs("Side: "); strcpy (cad, dec3strq (cabezal)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaLectura; cabezal = atoi (cad); if (cabezal>255) cabezal=255; clrscr(); gotoxy (17, 6); if (sp) cputs("Leyendo..."); else cputs("Reading..."); for (t=0; t255) sector=255; gotoxy (2, 5); if (sp) cputs("Tama¤o de sector:"); else cputs("Sector size:"); gotoxy (2, 6); cputs(" 0 -> 1-128 bytes 5 -> 4096 bytes"); gotoxy (2, 7); cputs(" 1 -> 256 bytes 6 -> 8192 bytes"); gotoxy (2, 8); cputs(" 2 -> 512 bytes 7 -> 16384 bytes"); gotoxy (2, 9); cputs(" 3 -> 1024 bytes 8 -> 32768 bytes"); gotoxy (2,10); cputs(" 4 -> 2048 bytes Val"); if (sp) cputs("or: "); else cputs("ue: "); strcpy (cad, dec2strq (tsector)); if (!input (cad, 1, 2, CE, CFE)) goto AbortaEscritura; tsector = atoi (cad); if (tsector==0) { gotoxy (24, 10); if (sp) cputs("Indica"); else cputs("Select"); cputs(" 1-128: "); strcpy (cad, dec3strq (t128)); if (!input (cad, 1, 3, CE, CFE)) goto AbortaEscritura; t128 = atoi (cad); if (t128>255) t128=255; else if (!t128) t128=1; } sbytes = tsector? (unsigned) 128 << tsector: t128; nsects = *bytes / sbytes; if (!nsects) nsects=1; gotoxy (sp?19:16, 3); cputs(sp?"N§ de sectores: ":"Number of sectors: "); strcpy (cad, dec3strq (nsects)); if (!input (cad, 1, 3, CL, CFL)) goto AbortaEscritura; nsects = atoi (cad); if (!nsects || (nsects > SMAX/sbytes)) { if (!nsects) nsects=1; else nsects=SMAX/sbytes; gotoxy (sp?19:16, 3); cputs(sp?"N§ de sectores: ":"Number of sectors: "); cputs (dec3strq(nsects)); cputs(" "); } gotoxy (7,12); if (sp) cputs("Cilindro: "); else cputs("Cylinder: "); strcpy (cad, dec3strq (cilindro)); if (!input (cad, 1, 3, CE, CFE)) goto AbortaEscritura; cilindro = atoi (cad); if (cilindro>255) cilindro=255; gotoxy (25,12); if (sp) cputs("Cara: "); else cputs("Side: "); strcpy (cad, dec3strq (cabezal)); if (!input (cad, 1, 3, CE, CFE)) goto AbortaEscritura; cabezal = atoi (cad); if (cabezal>255) cabezal=255; gotoxy (2, 14); if (sp) cputs("¨Escritura normal sin reset? (S/N): "); else cputs("Normal write without reset? (Y/N): "); if (wreset) strcpy (cad, "N"); else strcpy (cad, sp?"S":"Y"); if (!input (cad, 0, 1, CE, CFE)) goto AbortaEscritura; if ((cad[0] | 32) == 'n') wreset=1; else wreset=0; if (wreset) { if (dmacnt == -1) /* primera vez */ switch (TipoDrive(unidad)) { case 2: if (!vunidad) dmacnt = 10240; else dmacnt = 6098; break; case 4: switch (vunidad) { case 1: dmacnt = 7344; break; /* valores 2MGUI t¡picos */ case 2: dmacnt = 6098; break; case 3: dmacnt = 24626; break; default: dmacnt = 12314; break; } break; default: dmacnt = 6098; break; } gotoxy (2, 14); clreol(); if (sp) cputs("Valor del contador del DMA: "); else cputs("Value for DMA count: "); strcpy (cad, dec5strq (dmacnt)); if (!input (cad, 1, 5, CE, CFE)) goto AbortaEscritura; dmacnt = atoi (cad); if (dmacnt > SMAX - 32) dmacnt = SMAX-32; gotoxy (2, 16); if (sp) cputs("¨M s checksum y GAP de 2MGUI? (S/N): "); else cputs("May I add 2MGUI checksum/GAP (Y/N)?: "); strcpy (cad, sp?"S":"Y"); if (!input (cad, 0, 1, CE, CFE)) goto AbortaEscritura; if ((cad[0] | 32) == 'n') dmares = dmacnt; else { p = (unsigned *) buffer; chk=0; for (i=dmacnt; i < dmacnt+22; i++) buffer[i]=0; /* GAP Anti-FIFO */ for (i=0; i < ((dmacnt+1) >> 1); i++) chk += *p++; /* checksum */ chk = ~chk; buffer [dmacnt] = chk & 0xFF; buffer [dmacnt+1] = chk >> 8; dmares = dmacnt+22; } } clrscr(); gotoxy (15, 8); if (sp) cputs("Escribiendo..."); else cputs(" Writing..."); MotorOn (unidad); SeleccionarUnidad (unidad, vunidad); MotorOn (unidad); *bytes = sbytes * nsects; PreparaDma (0x4A, wreset? dmares: *bytes, buffer); outfdc (0x05 | mf_mfm << 6); /* comando para escribir */ outfdc (cabezal << 2 | unidad); /* byte 1 de dicho comando */ outfdc (cilindro); outfdc (cabezal); outfdc (sector); outfdc (tsector); outfdc (sector+nsects-1); outfdc (1); /* GAP m¡nimo */ outfdc (t128); /* tama¤o si tsector=0 */ if (wreset) { EsperaDma0 (unidad); /* con reset precario */ ResetUnidad (unidad); /* reset en condiciones */ SeleccionarUnidad (unidad, vunidad); } else EsperarInt(); ventana (CERRAR, 23, 5, 65, 23, 0, 0); if (!wreset) Resultados (ESCRIBIR, unidad, cabezal); goto FinEscritura; AbortaEscritura: ventana (CERRAR, 23, 5, 65, 23, 0, 0); FinEscritura: ; } void FormatearPista (unidad, mf_mfm, vunidad, cilindro, cabezal) { unsigned char buffer[768]; /* ­hasta 192 sectores! */ static sectores=-1, pokete=0xE6, tsector=2, eformat=0, freset=0, autogap=1, tunidad=4, gap=108, dmacnt=-1; int i, b765; long bytes; char cad[32]; ventana (ABRIR, 23, 3, 64, 23, CF, CFF); if (sp) { gotoxy (12,1); cputs("FORMATEO DE PISTA"); } else { gotoxy (15,1); cputs("FORMAT TRACK"); } gotoxy (2, 3); if (sp) cputs("Tama¤o de sector:"); else cputs("Sector size:"); gotoxy (2, 4); cputs(" 0 -> 1-128 bytes 5 -> 4096 bytes"); gotoxy (2, 5); cputs(" 1 -> 256 bytes 6 -> 8192 bytes"); gotoxy (2, 6); cputs(" 2 -> 512 bytes 7 -> 16384 bytes"); gotoxy (2, 7); cputs(" 3 -> 1024 bytes 8 -> 32768 bytes"); gotoxy (2, 8); cputs(" 4 -> 2048 bytes Val"); if (sp) cputs("or: "); else cputs("ue: "); strcpy (cad, dec2strq (tsector)); if (!input (cad, 1, 2, CF, CFF)) goto AbortaFormateo; tsector = atoi (cad); if (sectores==-1) { /* primera vez */ switch (TipoDrive(unidad)) { case 2: if (vunidad==0) sectores = 15; else sectores=9; break; case 5: if (vunidad==3) sectores = 36; /* sin break :-) */ case 4: if (vunidad==0) sectores = 18; if ((vunidad==1) || (vunidad==2)) sectores=9; break; case 1: case 3: default: sectores = 9; tunidad = 1; break; } if (!mf_mfm) sectores >>= 1; } gotoxy (2,10); if (sp) cputs("Sectores: "); else cputs("Sectors: "); strcpy (cad, dec3strq (sectores)); if (!input (cad, 1, 3, CF, CFF)) goto AbortaFormateo; sectores = atoi (cad); if (sectores>192) sectores=192; gotoxy (2,12); if (sp) cputs("¨Calculo yo el GAP3? (S/N): "); else cputs("Do I adjust the GAP3? (Y/N): "); if (autogap) strcpy (cad, sp?"S":"Y"); else strcpy (cad, "N"); if (!input (cad, 0, 1, CF, CFF)) goto AbortaFormateo; if ((cad[0] | 32) == 'n') autogap=0; else autogap=1; if (autogap) { gotoxy ( 2, 12); clreol(); if (TipoDrive(unidad)!=-1) tunidad=TipoDrive(unidad); else { gotoxy (17, 11); cputs("1 - 360K"); gotoxy (17, 12); cputs("2 - 1.2M"); gotoxy (17, 13); cputs("3 - 720K"); gotoxy (17, 14); cputs("4 - 1.44M"); gotoxy (17, 15); cputs("5 - 2.88M"); gotoxy ( 2, 17); if (sp) cputs("Indica el tipo de UNIDAD: "); else cputs("Select DRIVE type: "); strcpy (cad, dec2strq (tunidad)); if (!input (cad, 1, 2, CF, CFF)) goto AbortaFormateo; tunidad = atoi (cad); if (tunidad>5) { tunidad=4; goto AbortaFormateo; } for (i=11; i<=17; i++) { gotoxy (1, i); clreol(); } } if (tunidad==6) tunidad=5; /* convenci¢n AMI */ switch (tunidad) { case 1: case 3: switch (vunidad) { case 1: bytes = 7500; break; default: bytes = 6250; break; } break; case 2: switch (vunidad) { case 0: bytes = 10416; break; case 2: bytes = 5208; break; default: bytes = 6250; break; } break; case 4: case 5: switch (vunidad) { case 1: bytes = 7500; break; case 2: bytes = 6250; break; case 3: bytes = 25000; break; default: bytes = 12500; break; } break; } b765=62; if (!mf_mfm) { bytes >>= 1; b765 >>= 1; } gap = (bytes-((b765 + (128L << tsector)) * sectores)-146-32) / sectores; if (gap>255) gap=255; if (gap<1) { gap=1; gotoxy (10,12); if (sp) cputs("-> ­No caben tantos sectores!"); else cputs("-> Too many sectors for track!"); } gotoxy (2, 12); cputs("GAP3: "); cputs(dec5strq(gap)); } else { gotoxy (2,12); clreol(); cputs("GAP3: "); strcpy (cad, dec3strq (gap)); if (!input (cad, 1, 3, CF, CFF)) goto AbortaFormateo; gap = atoi (cad); if (gap>255) gap=255; } gotoxy (20,10); if (sp) cputs("Byte de relleno: "); else cputs("Fill byte: "); strcpy (cad, dec3strq (pokete)); if (!input (cad, 1, 3, CF, CFF)) goto AbortaFormateo; pokete = atoi (cad); if (pokete>255) pokete=255; gotoxy (2, 14); if (sp) cputs("¨Usar valores normales? (S/N): "); else cputs("Format with standard values? (Y/N): "); if (eformat) strcpy (cad, "N"); else strcpy (cad, sp?"S":"Y"); if (!input (cad, 0, 1, CF, CFF)) goto AbortaFormateo; if ((cad[0] | 32) == 'n') eformat=1; else eformat=0; gotoxy (2, 16); if (sp) cputs("¨Formateo normal sin reset? (S/N): "); else cputs("Normal format without reset? (Y/N): "); if (freset) strcpy (cad, "N"); else strcpy (cad, sp?"S":"Y"); if (!input (cad, 0, 1, CF, CFF)) goto AbortaFormateo; if ((cad[0] | 32) == 'n') freset=1; else freset=0; if (freset) { if (dmacnt==-1) dmacnt=sectores<<2; gotoxy (2, 18); if (sp) cputs("Valor del contador del DMA: "); else cputs("Value for DMA count: "); strcpy (cad, dec5strq (dmacnt)); if (!input (cad, 1, 5, CF, CFF)) goto AbortaFormateo; dmacnt = atoi (cad); } for (i=0; i65) cputs("..."); if (sp) { gotoxy (2, 11); cputs("Opciones:"); gotoxy (2, 12); cputs(" 1 - Introducir manualmente los 4"); gotoxy (2, 13); cputs(" bytes de un sector."); gotoxy (2, 14); cputs(" 2 - Modificar un cierto byte en"); gotoxy (2, 15); cputs(" todos los sectores."); gotoxy (2, 16); cputs(" ESC - Cancelar orden de formateo."); gotoxy (2, 17); cputs("INTRO - Proceder con el formateo."); gotoxy (2, 18); cputs(" Elige: "); } else { gotoxy (2, 11); cputs("Options:"); gotoxy (2, 12); cputs(" 1 - To introduce the 4 bytes one"); gotoxy (2, 13); cputs(" by one."); gotoxy (2, 14); cputs(" 2 - To modify one of the 4 bytes"); gotoxy (2, 15); cputs(" in all sectors."); gotoxy (2, 16); cputs(" ESC - Cancel format command."); gotoxy (2, 17); cputs("INTRO - Run format command now."); gotoxy (2, 18); cputs(" Choose: "); } do opcion=Tecla(); while (((opcion<'1') || (opcion>'3')) && (opcion!=27) && (opcion!=13)); for (i=11; i<19; i++) { gotoxy (1, i); clreol(); } if (opcion=='1') { do { gotoxy (2, 11); if (sp) cputs("Sector a alterar: "); else cputs("Sector to modify: "); strcpy (cad, dec3strq (sector)); if (!input (cad, 1, 3, CF, CFF)) break; sector = atoi (cad); if (sector>255) sector=255; for (i=0; (i255) cil=255; gotoxy (2, 14); if (sp) cputs ("N§ Cabezal (anterior="); else cputs ("Head number (previous="); cputs (dec3str(buffer[i*4+1])); cputs ("): "); if (cab==-1) cab=buffer[i*4+1]; strcpy (cad, dec3strq (cab)); if (!input (cad, 1, 3, CF, CFF)) break; cab = atoi(cad); if (cab>255) cab=255; gotoxy (2, 15); if (sp) cputs ("N£mero sector (anterior="); else cputs ("Sector number (previous="); cputs (dec3str(buffer[i*4+2])); cputs ("): "); if (sec==-1) sec=buffer[i*4+2]; strcpy (cad, dec3strq (sec)); if (!input (cad, 1, 3, CF, CFF)) break; sec = atoi(cad); if (sec>255) sec=255; gotoxy (2, 16); if (sp) cputs ("Tama¤o Sector (anterior="); else cputs ("Sector size (previous="); cputs (dec3str(buffer[i*4+3])); cputs ("): "); if (tse==-1) tse=buffer[i*4+3]; strcpy (cad, dec3strq (tse)); if (!input (cad, 1, 3, CF, CFF)) break; tse = atoi(cad); if (tse>255) tse=255; buffer[i*4]=cil; buffer[i*4+1]=cab; buffer[i*4+2]=sec; buffer[i*4+3]=tse; /* hechos cambios */ } } while (0); /* do-bobo, para poder salir con break ;-) */ } else if (opcion=='2') { if (sp) { gotoxy (2, 11); cputs("Caracter¡stica a cambiar: "); gotoxy (2, 12); cputs(" 0 - N§ Cilindro"); gotoxy (2, 13); cputs(" 1 - N§ Cabezal"); gotoxy (2, 14); cputs(" 2 - N§ Sector"); gotoxy (2, 15); cputs(" 3 - Tama¤o sector"); gotoxy (2, 16); cputs(" Elige: "); } else { gotoxy (2, 11); cputs("Characteristic to modify: "); gotoxy (2, 12); cputs(" 0 - Cylinder number"); gotoxy (2, 13); cputs(" 1 - Head number"); gotoxy (2, 14); cputs(" 2 - Sector number"); gotoxy (2, 15); cputs(" 3 - Sector size"); gotoxy (2, 16); cputs(" Choose: "); } strcpy (cad, dec2strq (subop)); if (input (cad, 1, 3, CF, CFF)) { subop = atoi (cad); if (subop>3) subop=3; else { for (i=11; i<17; i++) { gotoxy (1, i); clreol(); } gotoxy (2, 11); if (sp) cputs("Nuevo valor general: "); else cputs("New general value: "); strcpy (cad, dec3strq (valor)); if (input (cad, 1, 3, CF, CFF)) { valor = atoi (cad); if (valor>255) valor=255; for (i=0; iantlectura) if (cnth++>8) break; /* timeout */ } while (!(peekb(0x40, 0x3E) & 0x80)); pokeb (0x40, 0x3E, peekb (0x40, 0x3E) & 0x7F); /* reset int. */ outportb (0x61, inportb(0x61) & 0xFE); /* bajar GATE */ outportb (0x61, inportb(0x61) | 1); /* subir GATE */ if (kbhit()) { tec = getch(); if (!tec) tec=getch() << 8; if (tec==27) { /* tecla ESC */ ventana (CERRAR, 23, 11, 58, 15, 0, 0); goto fin_ids; } } for (j=0; j<7; j++) if ((nec[i][j]=infdc())==-1) break; if (cnth<9) tmp[i]=cnth*65535L + (65535-lectura); else { tmp[i]=0L; /* error */ nec[i][0]=-1; /* no informar */ pokeb (0x40, 0x40, 0xFF); /* asegurar motor en marcha */ } /* porque probablemente se est  perdiendo mucho tiempo */ } outportb (0x61, inportb(0x61) & 0xFC); ventana (CERRAR, 23, 11, 58, 15, 0, 0); textcolor (CIMS); textbackground(CFI); if (!primeravez++) clrscr(); gotoxy (4,1); textcolor (CIC); textbackground (CFIC); if (sp) cputs(" Milisegundos "); else cputs(" Milliseconds "); textbackground (CFI); putch(' '); textbackground (CFIC); cputs(" Sector "); textbackground (CFI); putch(' '); textbackground (CFIC); if (sp) cputs(" Tama¤o "); else cputs(" Size "); textbackground (CFI); putch(' '); textbackground (CFIC); if (sp) cputs(" Cilindro "); else cputs(" Cylinder "); textbackground (CFI); putch(' '); textbackground (CFIC); if (sp) cputs(" Cara "); else cputs(" Side "); textbackground (CFI); putch(' '); textbackground (CFIC); cputs(" ST0 "); textbackground (CFI); putch(' '); textbackground (CFIC); cputs(" ST1 "); textbackground (CFI); putch(' '); textbackground (CFIC); cputs(" ST2 "); textbackground (CFI); acu=0; for (j=0; j<23; j++) { /* rechazar primera muestra */ gotoxy (4, j+2); textcolor (CIMS); if (tmp[j+1] && tmp[j]) { acu+=tmp[j+1]; cprintf("[%8.2f]%7.2f ", acu/1193.18, tmp[j+1]/1193.18); } else cprintf(" N.D. "); if (nec[j][0]>=0) { textcolor (CIS); cputs(" "); cputs(dec3str(nec[j][5])); textcolor (CIT); cputs(" "); if (nec[j][6]<9) cputs(dec5str(128 << nec[j][6])); else cputs (" ?"); cputs(" ("); cputs(dec3str(nec[j][6])); putch(')'); textcolor (CICC); cputs(" "); cputs(dec3str(nec[j][3])); cputs(" "); cputs(dec3str(nec[j][4])); textcolor (CIST); cputs (" 0x"); cputs(hex2str(nec[j][0])); cputs (" 0x"); cputs(hex2str(nec[j][1])); cputs (" 0x"); cputs(hex2str(nec[j][2])); } else { textcolor (CIMS); cputs(" ?? ?? ?? ?? ?? ?? ?? "); } } textcolor (CIB); if (sp) { gotoxy (17, 25); cputs("Pulse la BARRA ESPACIADORA para leer m s ID's"); } else { gotoxy (23, 25); cputs("Press SPACE BAR to read more ID's"); } CursorOff(); tec = Tecla(); } while ((tec==32) || (tec=='5')); fin_ids: MotorOff(); } void Resultados (operacion, unidad, cabezal) { int xx, yy, res, t, st[3], str, bit; char sterr[2][10][40] = { { "MA (Missing Address Mark)", "NW (Non Writable: write protect error)", "ND (No data)", "", "OR (Overrun)", "DE (Data Error)", "", "EN (End of cylinder)", }, { "MD (Missing Address Mark in Data Field", "BC (Bad Cylinder)", "", "", "WC (Wrong Cylinder)", "DD (Data Error in Data Field)", "CM (Control Mark)", "", } }; ventana (ABRIR, 12, 7, 69, 22, CRS, CFRS); gotoxy (2, 1); switch (operacion) { case LEER: if (sp) cputs ("RESULTADO LECTURA"); else cputs ("READ RESULTS"); break; case ESCRIBIR: if (sp) cputs ("RESULTADO ESCRITURA"); else cputs ("WRITE RESULTS"); break; case FORMATEAR: if (sp) cputs ("RESULTADO FORMATEO"); else cputs ("FORMAT RESULTS"); break; } xx=wherex(); yy=wherey(); gotoxy (2, 3); cputs("[ST0 0x"); st[0]=res=infdc(); if (res>=0) cputs(hex2str(res)); else cputs("??"); putch(']'); if (res<0) { if (sp) { cputs (" ­El FDC no responde!"); gotoxy (xx, yy); cputs (": ­ERROR!"); } else { cputs (" FDC does not respond!"); gotoxy (xx, yy); cputs (": ERROR!"); } } else { gotoxy (2, 4); cputs("[ST1 0x"); st[1]=res=infdc(); if (res<0) st[1]=0; else st[1] &= 0xB7; if (res>=0) cputs(hex2str(res)); else cputs("??"); putch(']'); gotoxy (xx, yy); if ((st[0] & 0xC0)==0) cputs (sp?": CORRECTO":": OK"); else cputs (sp?": ­ERROR!":": ERROR!"); gotoxy (14, 3); cputs("[ST2 0x"); st[2]=res=infdc(); if (res<0) st[2]=0; else st[2] &= 0x73; if (res>=0) cputs(hex2str(res)); else cputs("??"); putch(']'); gotoxy (26, 3); if (sp) cputs("[Cilindro "); else cputs("[Cylinder "); res=infdc(); if (res>=0) cputs(dec3str(res)); else cputs("??"); putch(']'); gotoxy (26, 4); if (sp) cputs("[Cabezal "); else cputs("[Head "); res=infdc(); if (res>=0) cputs(dec3str(res)); else cputs("??"); putch(']'); gotoxy (42, 3); cputs("[Sector "); res=infdc(); if (res>=0) cputs(dec3str(res)); else cputs("??"); putch(']'); gotoxy (42, 4); if (sp) cputs("[Tama¤o "); else cputs("[Size "); res=infdc(); if (res>=0) cputs(dec3str(res)); else cputs("??"); putch(']'); outfdc (4); /* Leer ST3 */ outfdc (cabezal << 2 | unidad); /* byte 1 */ gotoxy (14, 4); cputs("[ST3 0x"); res=infdc(); if (res>=0) cputs(hex2str(res)); else cputs("??"); putch(']'); gotoxy (2, wherey()+1); for (str=1; str<=2; str++) for (bit=0, t=1; bit<8; bit++, t <<= 1) if (st[str] & t) { gotoxy (2, wherey()+1); cputs ("ST"); putch(str+'0'); putch('('); putch(bit+'0'); cputs("): "); cputs (sterr[str-1][bit]); } } MotorOff(); CursorOff(); while (kbhit()) getch(); while (!kbhit()); /* dejar tecla en buffer */ if ((bioskey(1) & 0xFF)==27) getch(); /* excepto si es ESC */ ventana (CERRAR, 12, 7, 69, 22, 0, 0); } void MostrarBuffer (char huge *buffer, unsigned *bytes) { static linea=0, cx=0, cy=0, asc=0, nibble=0, primeravez=1; char *pantalla; char huge *auxbuff; unsigned char huge *p; unsigned register x, off; unsigned y, t, i, auxlong=0; int lineas, my; char cad[32]; char hexa[16]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; textbackground (CFV); textcolor (CVMI); clrscr(); window (1,19,80,25); textbackground (0); textcolor (CVMM); clrscr(); window (1,20,80,25); textbackground (CFVM); clrscr(); putch('Ú'); for (x=1; x<79; x++) putch ('Ä'); putch('¿'); for (y=2; y<6; y++) { gotoxy (1, y); putch('³'); gotoxy (80, y); putch('³'); } putch('À'); for (x=1; x<79; x++) putch ('Ä'); _wscroll=0; putch('Ù'); _wscroll=1; if ((auxbuff = malloc (*bytes)) != NULL) { auxlong = *bytes; MoveMem (buffer, auxbuff, auxlong); /* copia de seguridad */ } textcolor (CVMI); gotoxy ( 3,2); cputs("F1: "); cputs(sp?"Ayuda":"Help"); if (auxlong) { gotoxy ( 3,3); cputs("F2: "); cputs(sp?"Deshacer":"Undo"); } gotoxy ( 3,4); if (sp) cputs("Intro: Nueva secci¢n"); else cputs("Enter: New section"); gotoxy ( 3,5); cputs("Tab: Hex\021-\020ASCII "); gotoxy (30,2); if (sp) cputs("F5: Poner buffer a 0"); else cputs("F5: Set buffer to 0"); gotoxy (30,3); if (sp) cputs("F6: Buffer con trama"); else cputs("F6: Fixed grid buffer"); gotoxy (30,4); if (sp) cputs("F7: Buffer aleatorio"); else cputs("F7: Random grid buffer"); gotoxy (30,5); if (sp) cputs("F8: Tama¤o de buffer"); else cputs("F8: Set buffer size"); textcolor (CVMD); gotoxy (58,2); if (sp) cputs("Secci¢n "); else cputs("Section "); if (sp) { gotoxy (58,3); cputs("Buffer de bytes"); } else { gotoxy (64,3); cputs("bytes buffer"); } textcolor (CVMS); gotoxy (58,5); if (sp) cputs("ESC/ALT-X Abandonar"); else cputs(" ESC/ALT-X Exit"); window (1, 1,80,25); lineas = (*bytes >> 4); if (*bytes & 0xF) lineas++; if (linea>=lineas) linea=0; textbackground (CFV); /* atributos de fondo */ for (y=2; y<=17; y++) { gotoxy (3, y); textcolor (CVD); cputs (" "); textcolor (CVH); cputs (" "); textcolor (CVS); cputs (" "); textcolor (CVH); cputs (" "); textcolor (CVA); cputs (" "); } do { p = &buffer[linea << 4]; for (y=16; y<272; y += 16, p += 16) { pantalla = MK_FP ((peekb(0x40, 0x49) & 0x7F) == 7 ? 0xB000:0xB800, 0); textcolor (CVD); textbackground (CFV); off = (p-buffer); if (off >= *bytes) { y >>= 4; for (i=0; i < (18-y)*80; i++) pantalla [(y*80+i) << 1]=' '; my=y-2; if (my<0) my=0; break; } else my=15; pantalla += ((y/16) * 80 + 2 ) << 1; *pantalla=hexa[off >> 12]; pantalla+=2; *pantalla=hexa[(off >> 8) & 15]; pantalla+=2; *pantalla=hexa[(off >> 4) & 15]; pantalla+=2; *pantalla=hexa[off & 15]; pantalla+=2; *pantalla=':'; pantalla+=6; for (x=0; x < 8; x++) { *pantalla=hexa[p[x] >> 4]; pantalla+=2; *pantalla=hexa[p[x] & 15]; pantalla+=4; } *pantalla='-'; pantalla+=4; for (x=8; x < 16; x++) { *pantalla=hexa[p[x] >> 4]; pantalla+=2; *pantalla=hexa[p[x] & 15]; pantalla+=4; } pantalla+=4; for (x=0; x < 16; x++) { *pantalla=p[x]?p[x]:32; pantalla+=2; } } textcolor (CVMD); textbackground (CFVM); gotoxy (70,21); strcpy (cad, dec3strq((linea >> 4) + 1)); cputs(cad); putch('/'); strcpy (cad, dec3strq(lineas >> 4)); cputs(cad); cputs(" "); if (sp) gotoxy (68,22); else gotoxy (58, 22); cputs(dec5str(*bytes)); if (cy>my) cy=my; if (primeravez && *bytes) { ventana (ABRIR, 18, 6, 62, 14, CVA, CFVA); if (sp) { gotoxy (10,1); cputs ("Editor compatible Borland"); gotoxy (2,3); cputs ("Cursores: \033 \032 \030 \031"); gotoxy (2,4); cputs ("Retroceder/Avanzar: REPAG/AVPAG"); gotoxy (2,5); cputs ("Inicio/Fin de l¡nea: INICIO/FIN"); gotoxy (2,6); cputs ("Inicio/Fin pantalla: CONTROL-INICIO/FIN"); gotoxy (2,7); cputs ("Inicio/Fin buffer: CONTROL-REPAG/AVPAG"); window (1,1,80,25); } else { gotoxy (10,1); cputs ("Borland compatible editor"); gotoxy (3,3); cputs ("Cursor keys: \033 \032 \030 \031"); gotoxy (3,4); cputs ("Backwards/Forward: PGUP/PGDN"); gotoxy (3,5); cputs ("Begin/End of line: HOME/END"); gotoxy (3,6); cputs ("Begin/End of screen: CTRL-HOME/END"); gotoxy (3,7); cputs ("Begin/End of buffer: CTRL-PGUP/PGDN"); } } if (lineas && !(primeravez && *bytes)) gotoxy (asc ? cx+62: cx<8? cx*3+10+nibble: cx*3+12+nibble, cy+2); else CursorOff(); t=Tecla(); if (primeravez && *bytes) { ventana (CERRAR, 18, 6, 62, 14, 0, 0); primeravez = 0; if ((t==13) || (t==27) || (t==32)) t = 0xFFFF; /* INTRO, ESC ¢ SP */ } switch (t) { case 0xFFFF: break; case 0x4800: if (cy>0) /* UP */ cy--; else if (linea>0) linea--; nibble=0; break; case 0x5000: if ((cy<15) && (cy+linea0) /* LEFT */ cx--; else if (cy>0) { cy--; cx=15; } else if (linea>0) { linea--; cx=15; } nibble=0; break; case 0x4700: cx=0; break; /* HOME */ case 0x4F00: cx=15; break; /* END */ case 0x7700: cy=0; break; /* CTRL-HOME */ case 0x7500: if (cy+linea+1515) linea -= 16; else linea=cy=0; /* PGUP */ nibble=0; break; case 0x5100: if (linea+1615) cy=linea=lineas-16; else { linea=0; cy = lineas-1; } } nibble=0; break; case 0x8400: linea=cx=cy=nibble=0; break; /* CTRL-PGUP */ case 0x7600: if (lineas>15) /* CTRL-PGDN */ cy=linea=lineas-16; else { linea=0; cy = lineas-1; } cx=15; nibble=0; break; case 0x3B00: primeravez=1; break; /* F1 */ case 0x3C00: if (auxlong) { /* F2 */ ventana (ABRIR, 18, 8, 58, 12, CVA, CFVA); gotoxy (4,2); if (sp) cputs ("Anulados los cambios en el buffer"); else cputs ("Buffer restored to initial state"); CursorOff(); *bytes = auxlong; MoveMem (auxbuff, buffer, auxlong); lineas = (*bytes >> 4); if (*bytes & 0xF) lineas++; if (linea>=lineas) linea=lineas-1; if (linea==-1) linea++; delay (1000); ventana (CERRAR, 18, 8, 58, 12, 0, 0); } break; case 0x3F00: t = lineas << 4; /* F5 */ for (i=0; i < t; i++) buffer[i]=0; break; case 0x4000: t = lineas << 4; /* F6 */ for (i=0; i < t; i++) buffer[i]=i; break; case 0x4100: t = lineas << 4; /* F7 */ for (i=0; i < t; i++) buffer[i]=rnd(256); break; case 13: ventana (ABRIR, 29, 9, 50, 11, CVNS, CFVNS); if (sp) cputs (" Nueva secci¢n: "); else cputs (" New section: "); strcpy (cad, dec3strq((linea >> 4) + 1)); if (input (cad, 1, 3, CVNS, CFVNS)) linea = (atoi(cad)-1) << 4; if (linea>=lineas) linea=lineas-1; if (linea==-1) linea++; ventana (CERRAR, 29, 9, 50, 11, 0, 0); break; case 0x4200: ventana (ABRIR, 21, 11, 56, 13, CVNB, CFVNB); /* F8 */ if (sp) cputs (" Nuevo tama¤o del buffer: "); else cputs (" New buffer size: "); strcpy (cad, dec5strq(*bytes)); t=*bytes; /* bytes previos */ if (input (cad, 1, 5, CVNB, CFVNB)) *bytes = atol(cad); if (*bytes > SMAX) *bytes=SMAX; lineas = (*bytes >> 4); if (*bytes & 0xF) lineas++; if (linea>=lineas) linea=lineas-1; if (linea==-1) linea++; ventana (CERRAR, 21, 11, 56, 13, 0, 0); CursorOff(); for (i=t; i < *bytes; i++) buffer[i]=0; cx=cy=asc=nibble=0; break; case 9: asc ^= 1; break; /* TAB */ case 0x1B: case 0x2D00: break; default: if (((t>='0') && (t<='9')) || ((t>='A') && (t<='F')) || ((t>='a') && (t<='f')) || asc) { if (asc) { buffer[linea*16+cy*16+cx] = t; if (cx<15) cx++; else if (cy+linea='a') && (t<='z')) t -= 32+7; if ((t>='A') && (t<='Z')) t -= 7; t -= '0'; buffer[linea*16+cy*16+cx] &= 0xF0 >> ((1-nibble)*4); buffer[linea*16+cy*16+cx] |= t << ((1-nibble)*4); nibble++; if (nibble>1) { if (cx<15) cx++; else if (cy+linea>7)==0)); } while ((i<8) && !rd); if (rd) outportb (FD_DATA, dato); } int infdc() /* leer byte del FDC */ { /* no esperando m s de 440 ms */ int t, i=0, rd; do { i++; t=peekb(0x40, 0x6C); while ((t==peekb(0x40, 0x6C)) && ((rd=inportb(FD_STATUS)>>7)==0)); } while ((i<8) && !rd); if (rd) return (inportb (FD_DATA)); else return (-1); /* fallo */ } int EsperarInt() /* Esperar interrupci¢n no m s de 2 seg. */ { int t, i=0; do { i++; t=peekb(0x40, 0x6C); while ((t==peekb(0x40, 0x6C)) && (!(peekb(0x40, 0x3E) & 0x80))); } while ((i<37) && (!(peekb(0x40, 0x3E) & 0x80))); pokeb (0x40, 0x3E, peekb (0x40, 0x3E) & 0x7F); return (i<37); } void PreparaDma (rmodo, bytes, buffer) unsigned rmodo, bytes; char huge *buffer; { unsigned long dir; unsigned dmapag, dmaoff; dir = ((unsigned long) FP_SEG(buffer) <<4) + FP_OFF(buffer); dmapag = dir >> 16; dmaoff = dir & 0xFFFF; outportb (0x81, dmapag); /* registro de p gina del canal 2 */ outportb (0xB, rmodo); /* programar registro de modo */ outportb (0xC, 0); /* clear first/last flip-flop */ outportb (4,dmaoff & 0xFF); /* direcci¢n base (parte baja) */ outportb (4,dmaoff >> 8); /* direcci¢n base (parte alta) */ outportb (5,(bytes-1) % 256); /* n§ de bytes menos 1 (parte baja) */ outportb (5,(bytes-1) / 256); /* n§ de bytes menos 1 (parte alta) */ outportb (0xA, 2); /* habilitar canal 2 */ } char *hex2str (int num) { static char cad[32]; char hexa[16]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; cad[0]=hexa[num >> 4]; cad[1]=hexa[num & 15]; cad[2]=0; return (cad); } int hextoi (char *cad) { unsigned num=0, error=0; char *p; p=cad; while (*p) { if (*p > '9') *p = (*p & 0xDF) - 7; p++; } p=cad; while (*p && !error) if ((*p<'0') || (*p>'?')) error++; else p++; p=cad; while (*p) { num <<= 4; num |= *p-'0'; p++; } if (!error) return (num); else return(0); } int input (char *cad, int modo, int maxcar, int tinta, int papel) { int x, y, t, i, px, primeravez=1; static insercion=1; x=wherex(); y=wherey(); px = strlen (cad); gotoxy (x, y); textcolor (tinta+BLINK); textbackground (papel); cputs (cad); textcolor (tinta); for (i=px; i=32) && (t<256) && ( (modo==0) || ((modo==1) && (t>='0') && (t<='9')) || ((modo==2) && ( ((t>='0') && (t<='9')) || /* Modo 0: Asc */ ((t>='a') && (t<='f')) || /* Modo 1: Dec */ ((t>='A') && (t<='F')) /* Modo 2: Hex */ ) ) ) ) if (!insercion) { if (px < maxcar) { cad[strlen(cad)+1]=0; cad[px++]=t; } } else if (strlen(cad) < maxcar) { for (i=strlen(cad); i>=px; i--) cad[i+1]=cad[i]; cad[i+1]=t; px++; } break; } gotoxy (x, y); cputs (cad); for (i=strlen(cad); i ESC */ return (t==13); } char *dec2str (unsigned num) { static char cad[32]; if (num >= 10) { cad[0]=num/10+'0'; num %= 10; } else cad[0]='0'; cad[1]=num+'0'; cad[2]=0; return (cad); } void CursorOff (void) { union REGS regs; regs.x.ax=0x200; regs.x.bx=peekb(0x40,0x62)<<8; regs.h.dl=1; regs.h.dh=63; int86 (0x10, ®s, ®s); } void BrilloOn (void) { union REGS regs; if (peekb(0x40, 0x49)!=7) { /* evitarlo en MDA */ regs.x.ax=0x1003; regs.x.bx=0; int86 (0x10, ®s, ®s); } } int TipoDrive (int unidad) { union REGS r; r.h.ah=8; r.h.dl=unidad; r.h.bl = 255; int86 (0x13, &r, &r); if ((r.x.flags & 1) || (r.h.bl==255)) return (-1); else return ((unsigned char) r.h.bl); } void ventana (operacion, x0, y0, x1, y1, tinta, papel) { static void *memoria; char far *pantalla; int i, t; if (operacion==ABRIR) { if ((memoria = farmalloc (2L*(x1-x0+3)*(y1-y0+2)))!=NULL) gettext (x0, y0, x1+2, y1+1, memoria); textbackground (papel); if (tinta>7) t=tinta-8; else t=tinta; textcolor (t+8); gotoxy (x0, y0); putch('Ú'); gotoxy (x0, y1); putch('À'); textcolor (t); gotoxy (x1, y0); putch('¿'); gotoxy (x1, y1); putch('Ù'); for (i=1; i= 3) { r.x.ax=0x4010; int86 (0x2F, &r, &r); return (r.x.ax != 0x4010); } else return (0); /* DOS 2.X, evitar llamada a INT 2Fh */ } int Hay2M3() /* devolver 1 si 2M 3.X est  instalado */ { int entrada, instalado=0; union REGS r; struct SREGS s; for (entrada=0xc0; (entrada<=0xff) && (!instalado); entrada++) { r.x.ax=entrada << 8; s.es=0x1492; r.x.di=0x1992; int86x (0x2f, &r, &r, &s); if (r.x.ax==0xFFFF) if ((peek(s.es,r.x.di-4)==9002) && (peek(s.es,r.x.di-2)==10787)) if (strstr (MK_FP(s.es, r.x.di),"2M:3.")) instalado=1; if (strstr (MK_FP(s.es, r.x.di),"2MX:3.")) instalado=1; } return (instalado); } char *dec2strq (unsigned num) { char *p; p=dec2str(num); if (*p=='0') p++; return (p); } char *dec3strq (unsigned num) { char *p; p=dec3str(num); while (*p==' ') p++; return (p); } char *dec3str (unsigned num) { static char cad[32]; int i; if (num >= 100) { cad[0]=num/100+'0'; num %= 100; } else cad[0]='0'; if (num >= 10) { cad[1]=num/10+'0'; num %= 10; } else cad[1]='0'; cad[2]=num+'0'; cad[3]=0; for (i=0; (i<2) && (cad[i]=='0'); i++) cad[i]=' '; return (cad); } char *dec5str (unsigned num) { static char cad[32]; int i; if (num >= 10000) { cad[0]=num/10000+'0'; num %= 10000; } else cad[0]='0'; if (num >= 1000) { cad[1]=num/1000+'0'; num %= 1000; } else cad[1]='0'; if (num >= 100) { cad[2]=num/100+'0'; num %= 100; } else cad[2]='0'; if (num >= 10) { cad[3]=num/10+'0'; num %= 10; } else cad[3]='0'; cad[4]=num+'0'; cad[5]=0; for (i=0; (i<4) && (cad[i]=='0'); i++) cad[i]=' '; return (cad); } int HablaSp() /* devolver 1 si mensajes en castellano */ { union REGS r; struct SREGS s; char info[64]; int i, idioma, spl[]={54, 591, 57, 506, 56, 593, 503, 34, 63, 502, 504, 212, 52, 505, 507, 595, 51, 80, 508, 598, 58, 3, 0}; idioma=0; /* supuesto el ingl‚s */ if (_osmajor>=3) { r.x.ax=0x3800; s.ds=FP_SEG(info); r.x.dx=FP_OFF(info); intdosx (&r, &r, &s); i=0; while (spl[i++]) if (spl[i-1]==r.x.bx) idioma=1; } return (idioma); } void Marco3dg (cx, cy, lx, ly, foco, tin, pap, banda) { int tb, x, y, w; w = _wscroll; _wscroll=0; if (tin<8) tb=tin+8; else tb=tin; if (foco) { textbackground (pap); textcolor (tb); for (y=cy; y < cy+ly; y++) { textbackground (pap); gotoxy (cx, y); if (CodePage437()) putch('Þ'); else putch('Û'); } for (x=cx+1; x < cx+lx-1; x++) { textbackground (banda); gotoxy (x, cy); putch('ß'); } textcolor (8); for (y=cy; y < cy+ly; y++) { textbackground (pap); gotoxy (cx+lx-1, y); if (CodePage437()) putch('Ý'); else putch('Û'); } for (x=cx+1; x < cx+lx-1; x++) { textbackground (banda); gotoxy (x, cy+ly-1); putch('Ü'); } } else { textbackground (pap); textcolor (8); for (y=cy; y < cy+ly; y++) { textbackground (banda); gotoxy (cx, y); if (CodePage437()) putch('Þ'); else putch('Û'); } for (x=cx+1; x < cx+lx-1; x++) { textbackground (pap); gotoxy (x, cy); putch('ß'); } textcolor (tb); for (y=cy; y < cy+ly; y++) { textbackground (banda); gotoxy (cx+lx-1, y); if (CodePage437()) putch('Ý'); else putch('Û'); } for (x=cx+1; x < cx+lx-1; x++) { textbackground (pap); gotoxy (x, cy+ly-1); putch('Ü'); } } _wscroll = w; } int CodePage437 (void) /* Devolver TRUE si p gina de c¢digos 437 */ { union REGS r; static pg437=-1; if (pg437 == -1) { if ((_osmajor*100 + _osminor) >= 330) { r.x.ax=0x6601; int86 (0x21, &r, &r); pg437 = (r.x.bx == 437); } else pg437 = 1; /* DOS < 3.30, suponer p gina 437 */ } return (pg437); } void Marco3df (cx, cy, lx, ly, foco, tin, pap) { int tb, x, y, w; w = _wscroll; _wscroll=0; if (tin<8) tb=tin+8; else tb=tin; textbackground (pap); textcolor (foco?tb:8); gotoxy (cx, cy); putch('Ú'); for (y=cy+1; y < cy+ly-1; y++) { gotoxy (cx, y); putch('³'); } gotoxy (cx, y); putch('À'); for (x=cx+1; x < cx+lx-1; x++) { gotoxy (x, cy); putch('Ä'); } textcolor (foco?8:tb); gotoxy (cx+lx-1, cy); putch('¿'); for (y=cy+1; y < cy+ly-1; y++) { gotoxy (cx+lx-1, y); putch('³'); } gotoxy (cx+lx-1, y); putch('Ù'); for (x=cx+1; x < cx+lx-1; x++) { gotoxy (x, cy+ly-1); putch('Ä'); } _wscroll = w; }