home *** CD-ROM | disk | FTP | other *** search
-
- /*───────────────────────────────────────────────────────────────────\
- │ │
- │ █████ █ █ █▀▀▀▀ │
- │ █ ██ ██ █ │
- │ █████ █ █ █ █▀▀ │
- │ █ █ █ █ │
- │ █████ █ █ █ │
- │ │
- │ 2MF.C 3.0 - UTILIDAD DE FORMATEO DE DISQUETES 2M │
- │ │
- │ (C) 1993-1995 Ciriaco García de Celis. │
- │ │
- │ - Para cualquier Turbo C o Borland C en modelo de memoria LARGE. │
- │ - Este programa se compila abriendo un proyecto e introduciendo │
- │ en él 2MF.C y 2MFKIT.OBJ │
- │ - Importante: no activar ciertas optimizaciones que no lo están │
- │ por defecto (como la de alineamiento a palabra o la de salto). │
- │ │
- │ - NOTA: Las funciones de bajo nivel que acceden directamente a │
- │ la controladora de disquetes no son indispensables, tan │
- │ sólo se emplean para producir menos ruido al detectar │
- │ la introducción de un nuevo disquete en la unidad. │
- │ │
- │ Este programa detecta además la presencia de una posible │
- │ utilidad de intercambio de unidades A:-B: llamada FDSWAP │
- │ para que en caso de estar activado dicho intercambio sea │
- │ posible acceder a la unidad física correspondiente. │
- │ │
- \───────────────────────────────────────────────────────────────────*/
-
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <dos.h>
- #include <bios.h>
- #include <time.h>
- #include <alloc.h>
- #include <conio.h>
- #include <io.h>
- #include <fcntl.h>
-
-
- #define CARDWARE 100 /* nº discos formateados antes del aviso */
- #define MAXSECT 46 /* máximo número de sectores por pista */
- #define MAXFAT 6128 /* mayor FAT de 12 bits posible */
- #define BOOT2M 80 /* bytes principales del Boot */
- #define FD_DATA 0x3F5 /* registro de datos del 765 */
- #define FD_STATUS 0x3F4 /* registro principal de estado del 765 */
- #define FD_DOR 0x3F2 /* registro de salida digital */
- #define FD_DIR 0x3F7 /* registro de entrada digital (RD) */
- #define FD_DCR 0x3F7 /* registro de control del disquete (WR) */
-
-
- typedef struct { /* sector arranque disquetes 2M */
- unsigned char Salto[3], IdSis[8];
- short BytesSect;
- char SectCluster;
- short SectReserv;
- char NumFats;
- short FichRaiz, NumSect;
- char MediaId;
- short SectFat, SectPista, Caras;
- long Especiales, Sect32;
- char Unidad, Reservado, Flag;
- long NumSerie;
- char Titulo[11], TipoFat[8];
- char Flags;
- char CheckSum;
- char VersionFmt, FlagWr, VelPista0, VelPistaX;
- short OffsetJmp, OffsetPista0, OffsetPistaX, OffsetListaTam;
- unsigned short FechaF;
- unsigned short HoraF;
- char Resto[512-BOOT2M]; /* depende del tamaño de lo anterior */
- } Boot;
-
- typedef struct { /* entrada de directorio */
- char Etiqueta[11];
- char Tipo;
- char Reservado[10];
- int Hora;
- int Fecha;
- char Resto[6];
- } Root;
-
- typedef struct { /* parámetros en línea de comandos */
- int Unidad, UnidadLogica,
- HD, ED, TipoFmt,
- NoVerify, MarcaPoco,
- Pistas, FichRaiz, Silencioso, NoPausa, NoTecla, X, Y, G,
- Tipoetiq, NoFlash, Rapido;
- char Volumen[12];
- } Parametros;
-
-
- int HablaSp (void),
- Hay2m (void),
- Hay2mBoot (void),
- FdswapOn (void),
- TipoDrive (int),
- EsperarCambioDisco (int, int),
- infdc (void),
- ValeDensidad (Boot *, Parametros *),
- FormatearDisco (Boot *,unsigned char far *,unsigned char far *,
- Parametros *, long *, int *),
- MarcaFat (int, int, Boot *, int, int, unsigned char far *,
- unsigned char far *, long *),
- InicializaDisco (int, Boot *, unsigned char far *,
- unsigned char far *);
- void Ayuda (void),
- ProcesarParametros (int, char **, Parametros *),
- DetectaMedio (Parametros *, Boot *),
- CrearSector0 (Boot *, Parametros),
- DiagnosticoError (int),
- InformeDisco (Boot *, Parametros *, long, int),
- IncrementarEtiqueta (Parametros *),
- SonidoSube (void),
- SonidoBaja (void),
- SonidoError (void),
- SonidoOn (void),
- SonidoOff (void),
- Sonido (int),
- posicionar (int, int),
- outfdc (unsigned char),
- EsperarInt (void),
- CardWare (char *, int);
- extern BootHDPrg, BootHDPrgLong, BootDDPrg, BootDDPrgLong,
- Boot2mCode, Boot2mLong,
- biosdsk (int, int, int, int, int, int, void far *);
- void interrupt NuevaInt24 (void);
- extern void PicoRetardo (void), interrupt (*ViejaInt24) (void);
-
-
-
- int sp; /* 1-español 0-inglés */
-
- unsigned long far *cbios=MK_FP(0x40, 0x6C); /* reloj del sistema */
- unsigned char far *irq6=MK_FP(0x40, 0x3E); /* flag BIOS de IRQ6 */
-
-
- void main (int argc, char **argv)
- {
- Boot sector0;
- Parametros cmd;
- int salir, result, sg, detectar, tec;
- long bytes_err, dir;
- unsigned char far *buffer; /* para contener toda una pista */
- unsigned char far *fat; /* para contener toda la FAT */
- int disquetes=0; /* nº discos formateados */
- void interrupt
- (*ViejaInt24) (void);
-
- sp=HablaSp(); /* determinar idioma del país */
-
- ProcesarParametros (argc, argv, &cmd);
-
- if (!Hay2m())
- if (!Hay2mBoot()) {
- if (sp)
- printf(" 2M ó 2MX 3.0 no está instalado, imposible formatear.\n");
- else
- printf(" 2M or 2MX 3.0 is not installed, impossible to format.\n");
- exit(128);
- }
- else {
- if (sp)
- printf(" Modo SuperBOOT: instale 2M para dar formato.\n");
- else
- printf(" SuperBOOT mode: needed to install 2M to format.\n");
- exit(127);
- }
-
- if (((fat=farmalloc( (unsigned long) MAXFAT))==NULL) ||
- ((buffer=farmalloc( (unsigned long) MAXSECT<<10))==NULL)) {
- if (sp) printf(" Memoria insuficiente.\n");
- else printf(" Insufficient memory.\n");
- exit(126);
- }
-
- /* Definir el buffer para que no cruce una frontera de DMA */
-
- dir = ((unsigned long) FP_SEG(buffer) <<4) + FP_OFF(buffer);
- if ((dir >> 16) != ((dir + ((unsigned long) MAXSECT << 9)) >> 16))
- buffer+=(unsigned long) MAXSECT << 9;
-
- if (!cmd.NoPausa) {
- if (sp)
- printf(" Pulsa INTRO para formatear en");
- else
- printf(" Press ENTER to format on");
- printf(" %c:", cmd.UnidadLogica+'A');
- tec=getch(); if (!tec) tec=getch()<<8;
- salir = (tec!=13);
- }
- else
- salir=0;
-
- /* si no se indica densidad detectarla */
-
- detectar = (cmd.HD==-1);
-
- /* formateo de múltiples disquetes */
-
- while (!salir) {
- if (detectar) DetectaMedio (&cmd, §or0);
- CrearSector0 (§or0, cmd);
- if (!cmd.Silencioso) SonidoSube();
- switch (result=FormatearDisco (§or0, fat, buffer, &cmd,
- &bytes_err, &sg)) {
- case 0: InformeDisco (§or0, &cmd, bytes_err, sg);
- if (!cmd.Silencioso) SonidoBaja();
- if (cmd.Tipoetiq==2) IncrementarEtiqueta (&cmd);
- disquetes++;
- break;
- case 1: DiagnosticoError (result);
- break;
- default: DiagnosticoError (result);
- if (!cmd.Silencioso) SonidoError(); break;
- }
- if (cmd.NoTecla)
- salir=1;
- else {
- if (sp)
- printf("\n Introduce otro disquete para formatear en");
- else
- printf("\n Please insert another disk to format in");
- printf(" %c:", cmd.UnidadLogica+'A');
-
- if (!EsperarCambioDisco(cmd.Unidad, cmd.NoFlash)) salir=1;
- }
- }
- printf("\r \r");
-
- ViejaInt24=getvect(0x24);
- setvect (0x24, NuevaInt24); /* evitar error crítico */
- CardWare (argv[0], disquetes); /* intentar actualizar 2MF.EXE */
- setvect (0x24, ViejaInt24);
- }
-
-
- void ProcesarParametros (int argc, char **argv, Parametros *cmd)
- {
- unsigned char drv[128];
- int pm, error=0, hlp=0, id=1, disco;
- union REGS r;
- struct SREGS s;
-
- cmd->Unidad=cmd->TipoFmt=cmd->ED=cmd->NoVerify=cmd->MarcaPoco=\
- cmd->FichRaiz=cmd->Silencioso=cmd->NoFlash=\
- cmd->NoPausa=cmd->NoTecla=cmd->Tipoetiq=cmd->Rapido=0;
- cmd->HD=-1; cmd->Pistas=82;
- cmd->X=cmd->Y=cmd->G=-1;
-
- for (pm=1; pm<argc; pm++)
- if (strstr(&argv[pm][1], "/")!=NULL) error=-1; /* parámetros unidos */
-
- if (!error) {
- for (pm=1; pm<argc; pm++) {
- if ((strstr(argv[pm],"/L")!=NULL) || (strstr(argv[pm],"/l")!=NULL)) {
- strncpy (cmd->Volumen, &argv[pm][3], 11);
- cmd->Volumen[11]=0;
- while (strlen(cmd->Volumen)<11) strcat(cmd->Volumen, " ");
- cmd->Tipoetiq=1;
- continue;
- }
- else if ((strstr(argv[pm],"/V")!=NULL) || (strstr(argv[pm],"/v")!=NULL)) {
- strncpy (cmd->Volumen, &argv[pm][3], 11);
- cmd->Volumen[11]=0;
- while (strlen(cmd->Volumen)<11) strcat(cmd->Volumen, " ");
- cmd->Tipoetiq=2;
- continue;
- }
- strupr (argv[pm]);
- if (strstr(argv[pm],"/?")!=NULL) hlp++;
- else if ((strstr(argv[pm],"/H")!=NULL) && (strlen(argv[pm])==2)) hlp++;
- else if (strstr(argv[pm],":")!=NULL)
- for (disco='A'; disco <= 'Z'; disco++) {
- drv[0]=disco; drv[1]=':'; drv[2]=0;
- if ((strstr(argv[pm], drv)!=NULL) &&
- (strstr(argv[pm], "/")==NULL)) cmd->Unidad=*argv[pm]-'A';
- }
- else if (strstr(argv[pm],"/HD")!=NULL) cmd->HD=1;
- else if (strstr(argv[pm],"/DD")!=NULL) cmd->HD=0;
- else if (strstr(argv[pm],"/D0")!=NULL) cmd->HD=2;
- else if (strstr(argv[pm],"/D1")!=NULL) cmd->HD=3;
- else if (strstr(argv[pm],"/F")!=NULL) cmd->TipoFmt=0;
- else if (strstr(argv[pm],"/M")!=NULL) cmd->TipoFmt=1;
- else if (strstr(argv[pm],"/ED")!=NULL) cmd->ED=1;
- else if (strstr(argv[pm],"/N")!=NULL) cmd->NoVerify=1;
- else if (strstr(argv[pm],"/W")!=NULL) cmd->MarcaPoco=1;
- else if (strstr(argv[pm],"/T")!=NULL)
- cmd->Pistas = atoi (&argv[pm][3]);
- else if (strstr(argv[pm],"/R")!=NULL)
- cmd->FichRaiz = atoi (&argv[pm][3]);
- else if (strstr(argv[pm],"/S")!=NULL) { cmd->Silencioso=1; id++; }
- else if (strstr(argv[pm],"/K")!=NULL) cmd->NoPausa=1;
- else if (strstr(argv[pm],"/J")!=NULL) cmd->NoTecla=1;
- else if (strstr(argv[pm],"/Z")!=NULL) cmd->NoFlash=1;
- else if (strstr(argv[pm],"/X")!=NULL) cmd->X=atoi(&argv[pm][3]);
- else if (strstr(argv[pm],"/Y")!=NULL) cmd->Y=atoi(&argv[pm][3]);
- else if (strstr(argv[pm],"/G")!=NULL) cmd->G=atoi(&argv[pm][3]);
- else if (strstr(argv[pm],"/I")!=NULL) { sp^=1; id++; }
- else if (strstr(argv[pm],"/Q")!=NULL) cmd->Rapido++;
- else error=1;
- }
- }
-
- cmd->UnidadLogica = cmd->Unidad;
-
- if (cmd->Unidad > 1) {
- r.x.ax = 0x440D; r.x.bx = cmd->Unidad+1; r.x.cx = 0x860;
- s.ds = r.x.si = FP_SEG (drv);
- r.x.dx = r.x.di = FP_OFF (drv); drv[0]=0;
- intdosx (&r, &r, &s);
- if ((!(r.x.flags & 1)) && (
- (drv[6]=='2'+'M') || (drv[6]=='2'+'M'+1)
- )
- ) cmd->Unidad = drv[6] - ('2'+'M'); /* unidad 2MGUI */
- }
-
- if (cmd->ED && (cmd->HD!=1)) cmd->HD=1; /* /DD ó /Dx + /E = /E */
-
- if ((argc<=1) || (argc==id)) hlp++;
-
- if (hlp) Ayuda();
-
- if (sp)
- printf("\n2MF 3.0 - Utilidad de formateo de disquetes 2M (ESC Salir)\n");
- else
- printf("\n2MF 3.0 - Format utility program for 2M diskettes (ESC Aborts)\n");
- if (error==1) {
- if (sp)
- printf(" Error de sintaxis. Ejecute 2MF /?.\n");
- else
- printf(" Incorrect parameter(s). Execute 2MF /?.\n");
- exit (2);
- }
- if (error==-1) {
- if (sp)
- printf(" Error: Los parámetros deben separarse por espacios.\n");
- else
- printf(" Error: Parameters must be separated by blank spaces.\n");
- exit (2);
- }
- if (cmd->Unidad > 1) {
- if (sp)
- printf(" La unidad lógica indicada no es una disquetera.\n");
- else
- printf(" Logical drive indicated does not is a diskette drive.\n");
- exit (2);
- }
- if (TipoDrive(cmd->Unidad)==0) {
- if (sp)
- printf(" La unidad física indicada no existe.\n");
- else
- printf(" Physical drive indicated does not exist.\n");
- exit (2);
- }
- if ((TipoDrive(cmd->Unidad)!=2) && (TipoDrive(cmd->Unidad)<4)) {
- if (sp)
- printf(" La unidad indicada no es de alta densidad.\n");
- else
- printf(" Drive indicated it is not high density one.\n");
- exit (2);
- }
- if ((TipoDrive(cmd->Unidad)<5) && (cmd->ED==1)) {
- if (sp)
- printf(" Necesaria unidad de 2.88M para formato ED.\n");
- else
- printf(" Needs a 2.88M drive to perform ED format.\n");
- exit (2);
- }
- if ((cmd->Pistas<80) || (cmd->Pistas>86)) {
- if (sp)
- printf(" Error: Número de pistas incorrecto.\n");
- else
- printf(" Error: Incorrect number of tracks.\n");
- exit (2);
- }
- if (cmd->FichRaiz && ((cmd->FichRaiz<1) || (cmd->FichRaiz>240))) {
- if (sp)
- printf(" Error: Nº de ficheros en directorio raiz erróneo.\n");
- else
- printf(" Error: Bad number of files in root directory.\n");
- exit (2);
- }
- }
-
-
- void Ayuda()
- {
- if (sp) {
- printf("\n\n"
- " 2MF 3.0 - UTILIDAD ESTANDAR DE FORMATEO DE DISQUETES PARA 2M\n"
- " (C) 1993-1995 Ciriaco García de Celis - Grupo Universitario de Informática\n"
- " C/Renedo, 2, 4-C; 47005 Valladolid (España) - ciri@gui.uva.es - 2:341/21.8\n\n"
- " 2MF U: [/HD|DD|ED] [/F|M] [/N] [/L|V=etiq] [/S] [/Z] [/R=nn] [/T=nn] [/K] [/J]\n\n"
- " Este programa formatea disquetes a una mayor capacidad y/o velocidad de la\n"
- " normal. Para que estos nuevos disquetes funcionen debe estar instalado 2M en\n"
- " memoria. Alternativamente, si son de alta densidad se pueden dejar dentro de\n"
- " la unidad A: y reinicializar el ordenador, que botará pese a todo del disco\n"
- " duro y podrá acceder a los disquetes 2M sin problemas en lectura/escritura.\n\n"
- " /HD Formateo en alta densidad (por defecto si 2MF no detecta la densidad).\n"
- " /DD Fuerza el formateo en doble densidad (aunque 2MF quizá la detecte).\n"
- " /ED Formatear disquetes de 3½-ED (3608K por defecto o 3772K indicando /M).\n"
- " /F Disquetes rápidos y seguros -por defecto- (5¼:820-1476K, 3½:984-1804K).\n"
- " /M Formatear disquetes a la máxima capacidad (5¼:902-1558K, 3½:1066-1886K).\n"
- " /N No verificar el disquete destino (peligroso en modo /M).\n"
- " /L Poner etiqueta de volúmen al disco destino (minúsculas permitidas).\n"
- " /V Etiqueta incremental en series de discos (si termina en número).\n"
- " /S Funcionamiento silencioso /Z Evitar parpadeo de LED de disco.\n"
- " /R Elegir nº ficheros raíz (1-240) /T Cambiar número de pistas (80-86).\n"
- " /K No realizar pausa inicial /J No realizar pausa final.\n");
- }
- else {
- printf("\n\n"
- " 2MF 3.0 - STANDARD FORMAT UTILITY FOR 2M DISKETTES\n"
- " (C) 1993-1995 Ciriaco García de Celis - Grupo Universitario de Informática\n"
- " C/Renedo, 2, 4-C; 47005 Valladolid (Spain) - ciri@gui.uva.es - 2:341/21.8\n\n"
- " 2MF U: [/HD|DD|ED] [/F|M] [/N] [/L|V=label] [/S][/Z] [/R=nn] [/T=nn] [/K][/J]\n\n"
- " This program formats diskettes at a higher capacity and/or speed than the\n"
- " normal ones. 2M must be installed on memory to provide support for the new\n"
- " diskettes. Also, high-density diskettes can be left into A: drive and then\n"
- " computer can be rebooted: really it will boot from hard disk and after this\n"
- " moment 2M diskettes will be supported in the standard read-write operation.\n\n"
- " /HD High density format (by default if 2MF can't detect diskette density).\n"
- " /DD Request a double-density format (but 2MF perhaps can detect DD disk).\n"
- " /ED Formats 3.5-ED diskettes at 3608K (or 3772K if /M option enabled).\n"
- " /F Fast and reliable diskettes -by default- (5¼:820-1476K, 3½:984-1804K).\n"
- " /M Formats diskettes up to maximum capacity (5¼:902-1558K, 3½:1066-1886K).\n"
- " /N Do not verify target diskette (dangerous in /M mode).\n"
- " /L Sets diskette volume label (case sensitive).\n"
- " /V Automatic sequencing of labels (if specified one is number terminated).\n"
- " /S Tells 2MF not to make sound effects /Z Turn disk LED «flashing» off.\n"
- " /R Sets root entries number (1-240) /T Sets number of tracks (80-86).\n"
- " /K No initial pause before formatting /J No end pause after formatting.\n");
- }
- exit (1);
- }
-
-
- int Hay2m() /* devolver 1 si 2M 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.0")) instalado=1;
- if (strstr (MK_FP(s.es, r.x.di),"2MX:3.0")) instalado=1;
- }
- return (instalado);
- }
-
-
- int Hay2mBoot() /* devolver 1 si 2M instalado en modo SuperBOOT */
- {
- return (strstr(MK_FP(((unsigned) peek(0x40, 0x13) * 64), 4),
- "2M-STV")!=NULL);
- }
-
-
- int FdswapOn() /* devolver 1 si FDSWAP 1.1+ está instalado y activo */
- {
- 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),":FDSWAP:")) instalado=1;
- }
- return ((instalado) && (peekb(s.es, peek(s.es,r.x.di-6)-1)==1));
- }
-
-
- void CrearSector0 (Boot *s0, Parametros cmd)
- {
- unsigned tipo, tabla, i, j, k, m, t, s, tam, ini, fin, inc;
- char id[8]="2M-STV00", ch, sum, far *p;
- struct time h;
- struct date f;
- static unsigned char infofis [2][3][2][4][20] =
- {{{{{10,176,7,0,1,1}, {9,80,1,1}, /* 5¼-DD /F */
- {5,100,3,1,1} },
- {{11,176,7,1,1,1}, {9,80,1,1}, /* /M */
- {32,4,5,3,1,4,2,0}, {4,2,4,3,0} }},
- {{{18,224,7,0,0,0}, {16,60,1,1}, /* 5¼-HD /F */
- {9,50,3,1,2} },
- {{19,224,7,1,0,0}, {17,25,1,2}, /* /M */
- {53,3,6,4,1,5,2,6,3}, {4,4,2,4,4,3} }},
- {{{0,0,0,0,0,0}, {0,0,0,0}, /* no usado */
- {0,0,0,0,0}, },
- {{14,192,7,1,2,1}, {9,80,1,1}, /* 3½-DD /D1 */
- {38,2,4,3,1,4,2}, {4,3,4,4} }}},
- {{{{12,192,7,0,2,1}, {9,80,1,1}, /* 3½-DD /F */
- {6,100,3,1,1} },
- {{13,192,7,1,2,1}, {9,80,1,1}, /* /M */
- {38,5,6,3,1,4,2,0,0}, {4,2,4,4,0,0} }},
- {{{22,224,7,0,0,0}, {19,70,1,1}, /* 3½-HD /F */
- {11,40,3,1,2} },
- {{23,224,7,1,0,0}, {19,70,1,1}, /* /M */
- {64,3,7,4,1,5,2,6,3,7}, {4,4,4,4,4,3,2} }},
- {{{44,240,7,0,3,3}, {36,108,1,1}, /* 3½-ED /F */
- {11,126,4,1,2} },
- {{46,240,7,1,3,3}, {36,108,1,1}, /* /M */
- {127,5,12,1,7,2,8,3,9,4,10,5,11,6,12},
- {4,4,4,4,4,4,4,4,4,4,4,3} }}}};
-
- /* Significado de la tabla /F:
- {SectLogPistaX, fichraiz, verFmt, flagWr, velpista0, velpistaX},
- {sectpista0, GAP3pista0, primsectpista0, interleavepista0},
- {SectFisPistaX, GAP3pistaX, tamsectpistaX, /X, /Y}
- Significado de la tabla /M:
- {SectLogPistaX, fichraiz, verFmt, flagWr, velpista0, velpistaX},
- {sectpista0, GAP3pista0, primsectpista0, interleavepista0},
- {Sectpreformat, GAP3pistaX, SectFisPistaX, sects numerados...},
- {tamaños de sectores por orden...}
- */
-
- if ((cmd.HD==2) && (TipoDrive(cmd.Unidad)>=4)) {
- cmd.HD=0; tabla=0; tipo=0;
- infofis[0][0][cmd.TipoFmt][0][4]=2; /* 3½-DD a 250 Kbps */
- infofis[0][0][cmd.TipoFmt][0][5]=2;
- }
- else if ((cmd.HD==3) && (TipoDrive(cmd.Unidad)>=4)) {
- cmd.HD=tipo=0;
- cmd.TipoFmt=1; tabla=2; /* 3½-DD con 1148K */
- }
- else {
- if (cmd.HD>1) cmd.HD=0;
- tabla=cmd.HD+cmd.ED; /* seleccionar tabla de datos */
- if (TipoDrive(cmd.Unidad)<3)
- tipo=0; /* 5¼ */
- else
- tipo=1; /* 3½ */
- }
-
- ch=1+cmd.HD;
- if (TipoDrive(cmd.Unidad)>2) ch+=2; if (!cmd.TipoFmt) ch+=4;
- if (cmd.ED) ch=10-cmd.TipoFmt;
- id[6]=(ch/10)+'0'; id[7]=(ch % 10)+'0'; strncpy (s0->IdSis, id, 8);
-
- s0->BytesSect=512;
- s0->SectCluster = s0->SectReserv = 1; s0->NumFats=2;
- if (cmd.ED) s0->SectCluster=2;
-
- if (!cmd.FichRaiz)
- s0->FichRaiz=infofis[tipo][tabla][cmd.TipoFmt][0][1];
- else
- if (cmd.FichRaiz % 16)
- s0->FichRaiz=((cmd.FichRaiz >> 4) + 1) << 4;
- else
- s0->FichRaiz=cmd.FichRaiz;
-
- if (ch==6)
- s0->MediaId=0xF0; /* compatible SCANDISK */
- else
- s0->MediaId=0xFA; /* compatible SCANDISK */
-
- s0->SectPista=infofis[tipo][tabla][cmd.TipoFmt][0][0];
- s0->Caras=2;
- s0->NumSect=cmd.Pistas*s0->Caras*s0->SectPista;
-
- j = 3 * (s0->NumSect - (s0->FichRaiz>>4) - 1);
- k = 6 + 1024 * s0->SectCluster;
- s0->SectFat = j/k; if (j % k) s0->SectFat++;
-
- s0->Unidad = s0->Reservado = 0; s0->Especiales = s0->Sect32 = 0L;
- s0->Flag=0x29; randomize();
- for (i=0; i<4; i++)
- s0->NumSerie = (s0->NumSerie<<8) | (unsigned char) random(32767);
-
- if (cmd.Tipoetiq)
- strncpy (s0->Titulo, cmd.Volumen, 11);
- else
- strncpy (s0->Titulo, "NO NAME ", 11);
-
- strncpy (s0->TipoFat, "FAT12 ", 8);
-
- s0->VersionFmt=infofis[tipo][tabla][cmd.TipoFmt][0][2];
- s0->FlagWr=infofis[tipo][tabla][cmd.TipoFmt][0][3];
- s0->VelPista0=infofis[tipo][tabla][cmd.TipoFmt][0][4];
- s0->VelPistaX=infofis[tipo][tabla][cmd.TipoFmt][0][5];
-
- s0->Flags=1; /* Fecha y hora de formateo almacenada */
- gettime (&h); getdate (&f);
- s0->FechaF=((f.da_year-1980)<<9) | (f.da_mon<<5) | f.da_day;
- s0->HoraF=(h.ti_hour<<11) | (h.ti_min<<5) | (h.ti_sec>>1);
-
- tam=BOOT2M; /* lo que precede a la primera tabla */
- s0->OffsetPista0=tam;
- s0->Resto[0]=infofis[tipo][tabla][cmd.TipoFmt][1][0];
- s0->Resto[1]=infofis[tipo][tabla][cmd.TipoFmt][1][1];
- ch=infofis[tipo][tabla][cmd.TipoFmt][1][2];
- inc=infofis[tipo][tabla][cmd.TipoFmt][1][3];
- ini=tam+2; fin=ini+s0->Resto[0]; k=0;
- for (i=j=0; j<s0->Resto[0]; j++) {
- s0->Salto[ini+i]=ch++; if (ch>s0->Resto[0]) ch=1;
- i+=inc; if (ini+i>=fin) i=++k;
- }
-
- ini=fin; s0->OffsetPistaX=ini;
- if (!s0->FlagWr) {
- k=infofis[tipo][tabla][cmd.TipoFmt][2][0]; j=5;
- for (i=0; i<j; i++)
- s0->Salto[ini+i]=infofis[tipo][tabla][cmd.TipoFmt][2][i];
- if (cmd.X!=-1) s0->Salto[ini+3]=cmd.X;
- if (cmd.Y!=-1) s0->Salto[ini+4]=cmd.Y;
- }
- else {
- k=infofis[tipo][tabla][cmd.TipoFmt][2][2]; j=(k+1)*3;
- for (i=0; i<3; i++)
- s0->Salto[ini+i]=infofis[tipo][tabla][cmd.TipoFmt][2][i];
- m=129;
- for (i=3; i<=k*3; i+=3) {
- s0->Salto[ini+i]=m;
- s=infofis[tipo][tabla][cmd.TipoFmt][2][i/3+2];
- s0->Salto[ini+i+1]=s;
- t=infofis[tipo][tabla][cmd.TipoFmt][3][s-1];
- switch (t) {
- case 0: m+=1; break; case 1: m+=2; break;
- case 2: m+=3; break; case 3: m+=6; break;
- case 4: m+=11; break; case 5: m+=22; break;
- }
- s0->Salto[ini+i+2]=t;
- }
- }
- if (cmd.G!=-1) s0->Salto[ini+1]=cmd.G;
- fin=ini+j;
-
- ini=fin; s0->OffsetListaTam=ini;
- if (!s0->FlagWr)
- for (i=0; i<k; i++)
- s0->Salto[ini+i]=infofis[tipo][tabla][cmd.TipoFmt][2][2];
- else
- for (i=0; i<k; i++)
- s0->Salto[ini+i]=infofis[tipo][tabla][cmd.TipoFmt][3][i];
- fin=ini+k;
-
- ini=fin; s0->OffsetJmp=ini;
- s0->Salto[0]=0xE9;
- s0->Salto[1]=(ini-3) % 256; s0->Salto[2]=(ini-3) >> 8;
-
- if (cmd.HD == 0) {
- p=(char far *) &BootDDPrg; k=BootDDPrgLong; }
- else {
- p=(char far *) &BootHDPrg; k=BootHDPrgLong; }
-
- for (i=0; (i<k) && (ini+i<509); i++) s0->Salto[ini+i]=*p++;
- fin=ini+i;
-
- for (i=fin; i<510; i++) s0->Salto[i]=0;
- if (fin<497) strncpy (&s0->Salto[496], "Made in Spain", 13);
- s0->Salto[509]=0; s0->Salto[510]=0x55; s0->Salto[511]=0xAA;
-
- for (sum=0, j=64; j<ini; j++) sum+=s0->Salto[j]; /* checksum */
- s0->CheckSum=-sum;
- }
-
-
- void DetectaMedio (Parametros *cmd, Boot *sector0)
- {
- int sg;
-
- if (sp)
- printf("\r Determinando densidad del disquete... ");
- else
- printf("\r Detecting diskette media density... ");
- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
-
- /* simular cambio de disco para inicialización plena de 2M */
-
- biosdsk (5, cmd->Unidad, 0, 0, 0xFF, 0x7F, NULL);
- biosdsk (2, cmd->Unidad, 0, 0, 1, 1, (unsigned char far *) sector0);
-
- for (sg=0; sg<2; sg++) {
- if (TipoDrive(cmd->Unidad)==2) /* en 5¼ intento pacífico */ {
- cmd->HD=1; sg=2;
- sg=biosdsk (0, cmd->Unidad, 0, 0, 0, 0, NULL);
- sg=biosdsk (2, cmd->Unidad, 0, 0, 1, 1, (void *) sector0);
- if (sg==6) /* cambio de disco */
- sg=biosdsk (2, cmd->Unidad, 0, 0, 1, 1, (void *) sector0);
- if (sg) break;
- if ((peekb (0x40, 0x8B) >> 6)!=0) cmd->HD=0; break;
- }
-
- cmd->ED=0; cmd->HD=1;
- if ((sg=ValeDensidad (sector0, cmd))==0) break; /* vale HD */
- if (kbhit()) if (getch()==27) break;
- if ((sg==3) || (sg==6) || (sg==128)) break; /* error */
- cmd->HD=0;
- if (!ValeDensidad (sector0, cmd)) break; /* vale DD */
- cmd->HD=1; if (kbhit()) if (getch()==27) break;
- cmd->HD=2;
- if (!ValeDensidad (sector0, cmd)) break; /* vale D0 */
- cmd->HD=1; if (kbhit()) if (getch()==27) break;
- cmd->ED=1;
- if (!ValeDensidad (sector0, cmd)) break; /* vale ED */
- cmd->HD=1; cmd->ED=0; if (kbhit()) if (getch()==27) break;
- }
-
- if (kbhit()) getch(); /* posible código de 2 bytes */
- }
-
-
- int ValeDensidad (Boot *sector0, Parametros *cmd)
- {
- CrearSector0 (sector0, *cmd);
- biosdsk (0, cmd->Unidad, 0, 0, 0, 0, NULL);
- biosdsk (5, cmd->Unidad, 0, 0, 0, 0x7F,
- (unsigned char far *) sector0);
- return (biosdsk (2, cmd->Unidad, 0, 0,
- cmd->HD==1?15:cmd->ED==1?36:9, 1,
- (unsigned char far *) sector0));
- }
-
-
- int FormatearDisco (sector0, fat, buffer, cmd, bytes_def, segundos)
- Boot *sector0;
- unsigned char far *fat;
- unsigned char far *buffer;
- Parametros *cmd;
- long *bytes_def;
- int *segundos;
- {
- unsigned long dir, tiempo, rest, tini, hist[86], i, fase, fases;
- int cilindros, cilindro, cabezal, intento, error=1, spista, t;
-
- if (cmd->Rapido)
- if (sp)
- printf("\r AVISO: ¡El formateo rápido no verifica!\n");
- else
- printf("\r WARNING: Quick Format does not verifies!\n");
-
- if (cmd->G!=-1)
- if (sp)
- printf("\r AVISO: ¡Valor de GAP alterado con opción /G!\n");
- else
- printf("\r WARNING: GAP value modified with /G switch!\n");
-
- if (cmd->HD==3)
- if (sp)
- printf("\r AVISO: ¡Parámetro indocumentado /D1 activo!\n");
- else
- printf("\r WARNING: Undocumented /D1 switch activated!\n");
-
- if (cmd->MarcaPoco)
- if (sp)
- printf("\r AVISO: ¡Parámetro indocumentado /W activo!\n");
- else
- printf("\r WARNING: Undocumented /W switch activated!\n");
-
- if ((cmd->X!=-1) || (cmd->Y!=-1))
- if (sp)
- printf("\r AVISO: ¡Parámetro indocumentado /X ó /Y activo!\n");
- else
- printf("\r WARNING: Undocumented /X or /Y switch activated!\n");
-
- if (sp)
- printf("\r Formateo de disquete ");
- else
- printf("\r Formatting ");
-
- switch (TipoDrive (cmd->Unidad)) {
- case 2: printf("%s", cmd->HD==1?"5¼-1.2M":"5¼-360K"); break;
- case 4: printf("%s", cmd->HD==1?"3½-1.44M":"3½-720K"); break;
- default: if (cmd->ED) printf("3½-2.88M");
- else printf("%s", cmd->HD==1?"3½-1.44M":"3½-720K");
- }
-
- if (sp)
- printf(" en %c: con %dK \n",
- cmd->UnidadLogica+'A', sector0->NumSect>>1);
- else
- printf(" diskette on %c: with %dK \n",
- cmd->UnidadLogica+'A', sector0->NumSect>>1);
-
- for (i=0; i<MAXFAT; i++) fat[i]=0; /* poner a 0 la futura FAT */
- fat[0]=sector0->MediaId; fat[1]=fat[2]=0xFF;
-
- for (i=0; i < ((unsigned long) MAXSECT <<9); i++) buffer[i]=0;
-
- cilindros=sector0->NumSect/(sector0->SectPista*sector0->Caras);
- spista=sector0->SectPista; *bytes_def=0L;
- fases=1L*cilindros*sector0->Caras*(1+(1-cmd->NoVerify)+sector0->FlagWr);
- fase=0L;
-
- tini=*cbios;
- for (cilindro=0; cilindro < cilindros ; cilindro++) {
- for (cabezal=0; cabezal<sector0->Caras; cabezal++) {
- for (intento=0; intento<3; intento++) {
- if (sp)
- printf("\r Cilindro %2d - Cara %d [F-] %3lu%%",
- cilindro, cabezal, fase*100/fases);
- else
- printf("\r Cylinder %2d - Side %d [F-] %3lu%%",
- cilindro, cabezal, fase*100/fases);
- if (error) biosdsk (0, cmd->Unidad, 0, 0, 0, 0, NULL);
- t=0; while (bioskey(1)) t=bioskey(0);
- if ((t & 0xFF)==0x1B) { error=1; goto AbortFormat; }
- else if (((t==0x1000) || (cmd->Rapido)) && (cilindro>1))
- goto FinFormat;
- error=biosdsk (5, cmd->Unidad, cabezal,
- cilindro, 0, 0x7F, (unsigned char far *) sector0);
- if (sector0->FlagWr==1) if (!error && (cilindro | cabezal)) {
- printf ("\b\b\b\b\b\b\b\b\bI-] %3lu%%",(fase+1)*100/fases);
- error=biosdsk (3, cmd->Unidad, cabezal | 0x80,
- cilindro, 1, spista, buffer);
- }
- if (!error&&(!cmd->NoVerify||(cmd->NoVerify && cilindro<2))) {
- printf ("\b\b\b\b\b\b\b\b\b-V] %3lu%%",
- (fase+1+sector0->FlagWr)*100/fases);
- error=biosdsk (2, cmd->Unidad, cabezal,
- cilindro, 1, spista, buffer);
- }
- if (!error) break;
- }
- if (error)
- if ((error==128) || (error==3) || (error==6))
- goto AbortFormat; /* error fatal */
- else
- if (!MarcaFat(cmd->Unidad, cmd->MarcaPoco, sector0,
- cilindro, cabezal, fat, buffer, bytes_def))
- goto AbortFormat; /* error en áreas del sistema */
- fase+=(1+(1-cmd->NoVerify)+sector0->FlagWr);
- }
- hist[cilindro]=*cbios;
- tiempo=(*cbios-tini)*10/182;
- printf(" [%2lu:%02lu ]", tiempo/60, tiempo % 60);
- if (cilindro>5) {
- rest=(*cbios-hist[cilindro-5])*(cilindros-cilindro)*10/910;
- printf("\b+%2lu:%02lu =%2lu:%02lu ]", rest/60, rest % 60,
- (tiempo+rest)/60, (tiempo+rest) % 60);
- }
- if (!error && (cilindro>79)) /* verificar siempre aquí */ {
- error=biosdsk (2, cmd->Unidad, 0, cilindro-1, 1, spista, buffer);
- if (error) { /* no soportadas tantas pistas */
- cilindros=cilindro; cilindro-=2;
- biosdsk (0, cmd->Unidad, 0, 0, 0, 0, NULL);
- }
- }
- }
-
- if (cmd->Pistas!=cilindros) { /* no soportadas tantas pistas */
- t=cmd->Pistas;
- cmd->Pistas=cilindros; /* nº pistas correcto */
- CrearSector0 (sector0, *cmd); /* sector de arranque final */
- cmd->Pistas=t; /* restaurar parámetro */
- }
-
- FinFormat: error=InicializaDisco(cmd->Unidad, sector0, fat, buffer);
-
- AbortFormat: printf("\r"); for (i=0; i<79; i++) printf(" ");
-
- *segundos=(*cbios-tini)*10/182;
-
- return (error);
- }
-
-
- void InformeDisco (s0, cmd, bd, tiempo)
- Boot *s0;
- Parametros *cmd;
- long bd;
- int tiempo;
- {
- unsigned long st, ua, bt;
- int cilindros;
- char label[12];
-
- st = s0->NumSect - s0->NumFats * s0->SectFat
- - s0->SectReserv - (s0->FichRaiz>>4);
- ua = st / (unsigned long) s0->SectCluster; bt = st*512L;
-
- cilindros=s0->NumSect/(s0->SectPista*s0->Caras);
-
- strncpy (label, s0->Titulo, 11); label[11]=0;
-
- if (sp) {
- printf ("\r Tiempo transcurrido formateando %2d:%02d\n",
- tiempo/60, tiempo % 60);
- printf (" Volúmen con número de serie %04X-%04X",
- (int) (s0->NumSerie >> 16), (int) s0->NumSerie);
- if (strstr(label, "NO NAME ")==NULL)
- printf (" y etiqueta %11s\n", label);
- else
- printf("\n");
- printf ("%9d ficheros permitidos en el raíz.\n",
- s0->FichRaiz);
- printf ("%9d unidades de asignación.\n", ua);
- printf ("%9d bytes por unidad de asignación.\n",
- s0->SectCluster*512);
- printf ("%9lu bytes totales en el disco.\n", bt);
- printf ("%9lu bytes en sectores defectuosos.\n", bd);
- printf ("%9lu bytes disponibles en el disco.\n", bt-bd);
- if (cilindros!=cmd->Pistas)
- printf(" Aviso: formateado con %dK (esta unidad sólo"
- " soporta %d pistas).\n", s0->NumSect>>1, cilindros);
- }
- else {
- printf ("\r Time elapsed in the process %2d:%02d\n",
- tiempo/60, tiempo % 60);
- printf (" Volume serial number is %04X-%04X",
- (int) (s0->NumSerie >> 16), (int) s0->NumSerie);
- if (strstr(label, "NO NAME ")==NULL)
- printf (" labeled %11s\n", label);
- else
- printf("\n");
- printf ("%9d file capacity of root directory.\n",
- s0->FichRaiz);
- printf ("%9d total clusters on disk.\n", ua);
- printf ("%9d bytes per cluster.\n",
- s0->SectCluster*512);
- printf ("%9lu total bytes on disk.\n", bt);
- printf ("%9lu bytes on bad sectors.\n", bd);
- printf ("%9lu bytes available on disk.\n", bt-bd);
- if (cilindros!=cmd->Pistas)
- printf(" Note: formatted with %dK (this drive supports"
- " only %d tracks).\n", s0->NumSect>>1, cilindros);
- }
- }
-
-
- void IncrementarEtiqueta (Parametros *cmd)
- {
- int j=10;
-
- while ((cmd->Volumen[j]==' ') && j) j--;
-
- while (j)
- if ((cmd->Volumen[j] >= '0') && (cmd->Volumen[j] <= '8')) {
- cmd->Volumen[j]++;
- break;
- }
- else if (cmd->Volumen[j] == '9') {
- cmd->Volumen[j]='0';
- j--;
- }
- else break;
- }
-
-
- void DiagnosticoError (int codigo)
- {
- if (sp) {
- switch (codigo) {
- case 1: printf("\r Formateo interrumpido por el usuario.");
- break;
- case 2: printf("\r La densidad seleccionada es incorrecta.");
- break;
- case 3: printf("\r Disquete protegido contra escritura.");
- break;
- case 6:
- case 128: printf("\r Unidad no preparada (¿puerta abierta?).");
- break;
- default: printf("\r Anomalía general: ¿densidad incorrecta?.");
- break;
- }
- }
- else {
- switch (codigo) {
- case 1: printf("\r Format aborted by user.");
- break;
- case 2: printf("\r Selected density is incorrect.");
- break;
- case 3: printf("\r Diskette is write-protected.");
- break;
- case 6:
- case 128: printf("\r Drive not ready (door open?).");
- break;
- default: printf("\r General failure: incorrect density?.");
- break;
- }
- }
- printf(" \n");
- }
-
-
- int MarcaFat (unidad, modosuave, sector0, cil, cab, fat, buffer, bytes_mal)
- Boot *sector0;
- int unidad, modosuave, cil, cab;
- unsigned char far *fat;
- unsigned char far *buffer;
- long *bytes_mal;
- {
- unsigned malclus, i, ini, tamsys;
-
- tamsys = sector0->NumFats*sector0->SectFat+(sector0->FichRaiz>>4)+1;
-
- for (i=1; i<=sector0->SectPista; i++) {
- ini=(cil*sector0->Caras+cab)*sector0->SectPista+i-1;
- if (modosuave)
- malclus=biosdsk (2, unidad, cab, cil, i, 1, buffer);
- else
- malclus=1; /* por defecto marcar la pista entera */
- if (malclus) {
- if (ini<tamsys) break; /* error en áreas del sistema */
- *bytes_mal+=sector0->SectCluster*512L;
- ini-=tamsys; ini=ini/sector0->SectCluster+2;
- if (ini % 2) { /* posición impar */
- fat [ini*3/2] = fat [ini*3/2] & 0x0F | 0x70;
- fat [ini*3/2+1] = 0xFF;
- }
- else { /* posición par */
- fat [ini*3/2] = 0xF7;
- fat [ini*3/2+1] = fat [ini*3/2+1] & 0xF0 | 0x0F;
- }
- ini=0x7FFF;
- }
- }
- return (ini>=tamsys);
- }
-
-
- int TipoDrive (int unidad)
- {
- union REGS r;
-
- r.h.ah=8; r.h.dl=unidad; int86 (0x13, &r, &r);
-
- if (r.x.flags & 1) { r.h.ah=8; r.h.dl=unidad; int86 (0x13, &r, &r);}
-
- return ((unsigned char) r.h.bl);
- }
-
-
- InicializaDisco (unidad, sector0, fat1, buffer)
- int unidad;
- Boot *sector0;
- unsigned char far *fat1;
- unsigned char far *buffer;
- {
- unsigned char far *p;
- int sectpista0=sector0->Salto[sector0->OffsetPista0],
- spraiz=sector0->SectFat*2+1,
- psr, nsr, cab, cil, error;
- Root raiz;
- struct time h;
- struct date f;
-
- memset (buffer, 0, (unsigned long) MAXSECT << 9);
- memset (&raiz, 0, sizeof (raiz));
-
- if (strstr(sector0->Titulo, "NO NAME ")==NULL) {
- strncpy (raiz.Etiqueta, sector0->Titulo, 11);
- raiz.Tipo=0x28;
- gettime (&h); getdate (&f);
- raiz.Fecha=((f.da_year-1980)<<9) | (f.da_mon<<5) | f.da_day;
- raiz.Hora=(h.ti_hour<<11) | (h.ti_min<<5) | (h.ti_sec>>1);
- }
-
- p=buffer;
- memcpy (p, sector0, 512); /* BOOT físico */
- p+=512;
- memcpy (p, fat1, sector0->SectFat*512); /* FAT1 (la 2 emulada) */
- p+=sector0->SectFat<<9;
- memcpy (p, sector0, 512); /* BOOT virtual */
- if (sector0->SectPista>=15) /* HD */ {
- p+=512;
- memcpy (p, &Boot2mCode, Boot2mLong); /* código SuperBOOT */
- }
- p=buffer+(spraiz<<9);
- memcpy (p, &raiz, sizeof(raiz)); /* 1ª entrada ROOT */
-
- biosdsk (0, unidad, 0, 0, 0, 0, NULL);
- error=biosdsk(3, unidad, 0x80, 0, 1, sectpista0, buffer);
- if (!error) {
- memset (buffer, 0, (unsigned long) MAXSECT << 9); /* ROOT */
- memcpy (buffer, &raiz, sizeof(raiz));
- psr = (spraiz % sector0->SectPista) + 1;
- nsr = sector0->SectPista - psr + 1;
- cil = 0; cab = spraiz/sector0->SectPista;
- error=biosdsk(3, unidad, cab, cil, psr, nsr, buffer);
- if (nsr < sector0->FichRaiz) {
- memset (buffer, 0, sizeof(raiz)); cab++; if (cab>1) { cab=0; cil++;}
- error=biosdsk(3, unidad, cab, cil, 1, sector0->SectPista, buffer);
- }
- }
- return (error);
- }
-
-
- void SonidoSube()
- {
- int frec=50;
-
- SonidoOn();
- while (frec<5000) {
- Sonido (frec); PicoRetardo(); Sonido (frec+1000); PicoRetardo();
- frec+=10;
- }
- SonidoOff();
- }
-
-
- void SonidoBaja()
- {
- int frec=6000;
-
- SonidoOn();
- while (frec>1050) {
- Sonido (frec); PicoRetardo(); Sonido (frec-1000); PicoRetardo();
- frec-=10;
- }
- SonidoOff();
- }
-
-
- void SonidoError()
- {
- int frec1=50, frec2=6000;
-
- SonidoOn();
- while (frec1<5000) {
- Sonido (frec1); PicoRetardo(); Sonido (frec1+1000); PicoRetardo();
- Sonido (frec2); PicoRetardo(); Sonido (frec2-1000); PicoRetardo();
- frec1+=10; frec2-=10;
- }
- SonidoOff();
- }
-
-
- void SonidoOn()
- {
- disable(); outportb (0x61, inportb (0x61) | 3); enable();
- outportb (0x43, 182); /* preparar canal 2 */
- }
-
-
- void SonidoOff()
- {
- disable(); outportb (0x61, inportb (0x61) & 0xFC); enable();
- }
-
-
- void Sonido (int frecuencia)
- {
- unsigned periodo;
-
- periodo=1193180L/frecuencia;
- outportb (0x42, periodo & 0xFF); outportb (0x42, periodo >> 8);
- }
-
-
- int EsperarCambioDisco (int disquetera, int flash)
- {
- int i, unidad, tec;
- long hora, iter;
-
- unidad=disquetera;
- if (FdswapOn()) unidad^=1; /* unidades intercambiadas por FDSWAP */
-
- while (kbhit()) (void) getch(); /* limpiar buffer teclado */
-
- pokeb(0x40,0x3F, peekb(0x40, 0x3F) & 0xF0); /* "motores apagados" */
-
- do { /* esperar que retiren el disquete */
- hora=*cbios+5;
- while (*cbios<hora);
- outportb (FD_DOR, (1<<(unidad+4)) | unidad | 4+8); /* encender */
- i=inportb (FD_DIR); /* leer línea de cambio */
- outportb (FD_DOR, unidad | 4+8); /* apagar motor */
- i = (i >> 7) | kbhit();
- } while (!i);
-
- if (flash) /* intento de bajar la línea de cambio */
- iter=2000000000L;
- else
- iter=8L;
- while (i && !kbhit()) { /* y parpadeo del LED */
- hora=*cbios+6;
- pokeb (0x40, 0x40, 0xFF); /* para BIOS pelmas no estándar */
- outportb (FD_DOR,(1<<(unidad+4)) | unidad | 4+8); /* encender */
- pokeb(0x40,0x3F, peekb(0x40, 0x3F) | (1<<unidad));
- posicionar (unidad, 1);
- while ((*cbios<hora) && !kbhit());
- posicionar (unidad, 0);
- i = inportb (FD_DIR) >> 7; /* leer línea de cambio */
- if (i && !iter) {
- outportb (FD_DOR, unidad | 4+8); /* apagar motor */
- pokeb(0x40,0x3F, peekb(0x40, 0x3F) & 0xF0);
- hora+=12;
- while ((*cbios<hora) && !kbhit());
- }
- if (iter) iter--;
- }
-
- /* simular cambio de disco para anular efecto de bajada de línea */
-
- biosdsk (5, disquetera, 0, 0, 0xFF, 0x7F, NULL); /* función de 2M */
-
- /* 3 segundos para detención del motor */
-
- pokeb (0x40, 0x40, 54);
- if (kbhit()) tec=getch(); else tec=13; if (!tec) tec=getch()<<8;
- return ((tec & 0xFF)==13);
- }
-
-
- void posicionar (int unidad, int cilindro) /* mover cabezal */
- {
- outfdc (0xF); /* comando 'Seek' */
- outfdc (unidad); /* byte 1 de dicho comando */
- outfdc (cilindro);
-
- EsperarInt(); /* esperar interrupción */
-
- outfdc (8); /* comando 'leer estado de interrupciones' */
-
- (void) infdc(); (void) infdc();
- }
-
-
- void outfdc (unsigned char dato) /* enviar byte al FDC */
- { /* no esperando más de 440 ms */
- int i=0, rd;
- long t;
-
- do {
- i++; t=*cbios;
- while ((t==*cbios) && ((rd=inportb(FD_STATUS)>>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 i=0, rd;
- long t;
-
- do {
- i++; t=*cbios;
- while ((t==*cbios) && ((rd=inportb(FD_STATUS)>>7)==0));
- } while ((i<8) && !rd);
-
- if (rd) return (inportb (FD_DATA)); else return (-1); /* fallo */
- }
-
-
- void EsperarInt() /* Esperar interrupción no más de 2 seg. */
- {
- int i=0;
- long t;
-
- do {
- i++; t=*cbios;
- while ((t==*cbios) && !(*irq6 & 0x80));
- } while ((i<37) && !(*irq6 & 0x80));
-
- *irq6=*irq6 & 0x7F;
- }
-
-
- void CardWare (char *nfich, int discos)
- {
- int fich, aviso=0, lcad;
- unsigned int i, contador;
- struct ftime fechahora;
- unsigned char chk[10],
- cmp[]="Cnt",
- num[]="00000",
- cw[]="000";
-
- lcad=strlen(cmp)+2;
- if ((fich=open(nfich, O_BINARY | O_RDWR))==-1) return;
- if (getftime (fich, &fechahora)==-1) { close(fich); return; }
- if (lseek (fich, -lcad, SEEK_END)==-1) { close(fich); return; }
- if (read (fich, chk, lcad)==-1) { close(fich); return; }
- chk[lcad-2]=0;
- if (strcmp(chk, cmp)) /* contador no inicializado */ {
- write (fich, cmp, strlen(cmp));
- contador=0; write (fich, &contador, sizeof(unsigned int));
- if (discos) discos--;
- }
- if (lseek (fich, -2L, SEEK_END)==-1) { close(fich); return; }
- if (read (fich, &contador, 2)==-1) { close(fich); return; }
-
- for (i=contador+1; i<=contador+discos; i++)
- if (((i % CARDWARE)==0) && (i>99)) aviso++; /* pasada frontera */
- contador+=discos;
-
- if (lseek (fich, -2L, SEEK_END)==-1) { close(fich); return; }
- if (write (fich, &contador, 2)==-1) { close(fich); return; }
- flushall();
- setftime (fich, &fechahora);
- close (fich);
-
- num[0]=contador / 10000 + '0'; contador%=10000;
- num[1]=contador / 1000 + '0'; contador%=1000;
- num[2]=contador / 100 + '0'; contador%=100;
- num[3]=contador / 10 + '0'; contador%=10;
- num[4]=contador+'0';
-
- i=CARDWARE;
- cw[0]=i / 100 + '0'; i%=100;
- cw[1]=i / 10 + '0'; i%=10;
- cw[2]=i+'0';
-
- if (aviso)
- if (sp) {
- clrscr();
- textcolor (LIGHTCYAN + BLINK); textbackground (BLUE);
- gotoxy (27, 5);
- cputs(" ¡¡AVISO MUY IMPORTANTE!! ");
- textcolor (LIGHTRED); textbackground (BLACK);
- gotoxy (15,7); cputs ("Esta copia de 2MF ya ha formateado ");
- textcolor (YELLOW);
- if (num[0]!='0') cputs (num);
- else if (num[1]!='0') cputs (&num[1]);
- else cputs (&num[2]);
- textcolor (LIGHTRED);
- cputs (" disquetes.");
- gotoxy (15,8); cputs ("Recuerda que 2M es un programa ");
- textcolor (LIGHTGREEN); cputs ("CardWare"); textcolor (LIGHTRED);
- cputs (". Si aún");
- gotoxy (15,9); cputs ("no has enviado tu ");
- textcolor (LIGHTMAGENTA); cputs ("tarjeta postal"); textcolor (LIGHTRED);
- cputs (" al autor, no");
- gotoxy (15,10); cputs ("deberías continuar utilizando estos discos.");
- gotoxy (15,12); cputs ("Si ya la has enviado, estoy ");
- textcolor (LIGHTCYAN); cputs ("muy contento"); textcolor (LIGHTRED);
- cputs (" contigo");
- gotoxy (15,13); cputs ("y dentro de otros ");
- cputs (cw); cputs(" volveré a felicitarte.");
- gotoxy (15,15); textcolor (LIGHTGREEN); cputs ("¡Suerte!");
- textcolor (WHITE);
- gotoxy (1,17);
- }
- else {
- clrscr();
- textcolor (LIGHTCYAN + BLINK); textbackground (BLUE);
- gotoxy (27, 5);
- cputs(" ¡¡VERY IMPORTANT NOTICE!! ");
- textcolor (LIGHTRED); textbackground (BLACK);
- gotoxy (15,7); cputs ("This 2MF program has already formatted ");
- textcolor (YELLOW);
- if (num[0]!='0') cputs (num);
- else if (num[1]!='0') cputs (&num[1]);
- else cputs (&num[2]);
- textcolor (LIGHTRED);
- cputs (" disks.");
- gotoxy (15,8); cputs ("Remember that 2M is a ");
- textcolor (LIGHTGREEN); cputs ("CardWare"); textcolor (LIGHTRED);
- cputs (" program. If you");
- gotoxy (15,9); cputs ("haven't send still your ");
- textcolor (LIGHTMAGENTA); cputs ("postcard"); textcolor (LIGHTRED);
- cputs (" to the author,");
- gotoxy (15,10); cputs ("you musn't continue on using this diskettes.");
- gotoxy (15,12); cputs ("If you have send it yet, I'm ");
- textcolor (LIGHTCYAN); cputs ("very happy"); textcolor (LIGHTRED);
- cputs (" with you");
- gotoxy (15,13); cputs ("and within next "); cputs (cw); cputs(" ones I will thank you again.");
- gotoxy (15,15); textcolor (LIGHTGREEN); cputs ("Good luck!");
- textcolor (WHITE);
- gotoxy (1,17);
- }
- }
-
-
- 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);
- }
-