lunes, 24 de marzo de 2008

COMLOAD

El proyecto consiste en un cargador de archivos .COM, que demuestra como se implementa la función Cargar/Ejecutar usando llamadas al sistema DOS, incluidas en la tabla de interrupciones de servicios de este sistema operativo.

Para cargar y ejecutar un programa .COM se utilizaron estructuras de registros (SREGS y REGS) y varias subfunciones de las interrupciones 21h, las cuales se llevan a cabo en C++ con las funciones INTDOS() e INTDOSX(). La diferencia es que ésta última considera las estructuras de segmentos SREGS que se utiliza.

La interrupción 21h, con registro AH = 4a , permite reservar memoria para la rutina principal y liberar el resto para que la utilice el subproceso o programa a cargar, asi:
re.x.bx = 2000;
sr.es = _psp;
donde BX indica los párrafos en Hexadecimal (aquí se reservan 8 KB para la rutina principal) y ES apunta al PSP del programa COMLOAD.EXE.

Una vez que se ha considerado la memoria disponible se dispone a cargar y ejecutar el programa con registro AH = 4B, donde AL = 0 para cargar y ejecutar a la vez.
Se apunta DS:DX a la dirección del nombre del programa (una cadena ASCIIZ, esto es, terminada por cero) que puede incluir la ruta de directorios y debe incluir la extensión. Se Luego apuntamos ES:BX a una estructura de datos (bloque de parámetros) que se interpreta de la siguiente forma:

El subprograma cargado hereda los ficheros abiertos del programa padre.
Cuando se ejecuta un programa COM ordinario, toda la memoria del sistema está asignada al mismo (el mayor bloque en realidad, lo que en la práctica significa toda la memoria). Para ello, se calcula cuanta memoria necesita el programa y se llama a la
función del sistema para modificar el tamaño del bloque de memoria del propio programa (función 4Ah del DOS, pasando en ES la dirección del PSP).
Por ello, si el programa va a ocupar menos de 64 Kb, será preciso mover SP más abajo para que no se salga del futuro bloque de memoria del programa.


#include
#include
#include
#include

void ayuda()
{
printf("\nCOMLOAD: Carga en memoria y ejecuta archivos del tipo .COM\n con paso de parametros\n");
printf("\r\n");
printf("SINTAXIS: comload [ -c \ -h ]\n");
printf("-c Indica que se va a ejecutar un archivo .COM\n");
printf("archivo Nombre del archivo sin la extension .COM\n");
printf("lineacom Parametros para pasar al archivo .COM\n");
printf("-h Imprime esta ayuda\n");
}

int main( int argc, char near *argv[ ] )
{
// VARIABLES LOCALES
int i, j; // contadores
struct SREGS sregs, sr; // estructuras de registros para manejar segmentos
union REGS registros, re; // estructura de registros
int ret_codigo; // codigo retorno
char near* linea_comando; // linea de comandos como parametros
char near* parametros; //long ES_anterior, SS_anterior;
char *bloque_mem; // para reservar y liberar memoria
int pilaSS, pilaSP; // para guardar los segmentos de la rutina principal antes de ejecutar el .com

struct bloque_param { // estructura para pasar al PSP de poceso hijo (archivo .COM)
int ambiente_seg;
int linea_com_offset; // puntero (segmento:desplazamiento) para la linea de comandos
int linea_com_seg;
int fcb1_offset; // puntero al primer FCB
int fcb1_seg;
int fcb2_offset; // puntero al segundo FBC
int fcb2_seg;
} b_param;


// CODIGO

strcpy(&linea_comando[0],0); // limpiamos las cadenas de texto
strcpy(&parametros[0],0);
if( strcmp(argv[1], "-c")==0)
{
if (argc > 3)
// Hay linea de comando para comload
{
i = 3;
strcpy(&parametros[0],"");
do
{
strcat(&parametros[0], argv[i]);
i++;
if (i < argc)
{ strcat(&parametros[0]," "); }
Else
{ strcat(&parametros[0],"\r"); }
} while (i < argc);

linea_comando[0] = (char) (strlen(parametros)-1);
strcpy(&linea_comando[1],parametros);
}
else
{
linea_comando[0] = (char) 0;
strcat(&linea_comando[0], "\r");
}
// leemos los registros de segmentos y los guardamos antes de ejecutar el subproceso
segread(&sregs);
pilaSS = _SS;
pilaSP = _SP;
printf("\n...lectura registros OK");

// Reservamos 2000h bytes para la rutina principal y liberamos el resto para el subproceso
re.h.ah = 0x4a;
re.x.bx = 2000;
sr.es = _psp;
intdosx(&re,&re,&sr);
printf("\n... reservacion memoria OK\n\n");
if (re.x.cflag) { printf("\nNO SE PUDO LIBERAR LA MEMORIA. ERROR:0x%x\n",re.x.ax); }
else
{
b_param.linea_com_offset = (int) linea_comando; // apunta a la direccion donde
// esta la linea de comandos
b_param.linea_com_seg = sregs.ds;
b_param.fcb1_offset = 0x5c;
b_param.fcb1_seg = _psp; // apunta al segmento del PSP de comload.exe
b_param.fcb2_offset = 0x6c;
b_param.fcb2_seg = _psp;
b_param.ambiente_seg = *((int far *)(((long)_psp<<16) 0x2c));
// apunta al segmento de las variables de ambiente
// contatenamos la extension
strcat(&argv[2][0],".com");

// obtenemos un bloque de memoria
bloque_mem = malloc(60000);

/* re.h.ah = 0x48;
re.x.bx = 1000; // 1000h parrafos = 4096 * 16 = 64Kb
intdos(&re, &re);
if (re.x.cflag) { printf("\nNO SE PUDO RESERVAR LA MEMORIA");}
else { ES_anterior = re.x.ax; }
*/

// Cargamos en memoria y ejecutamos el subproceso
registros.h.ah = 0x4b;
registros.h.al = 0x00;

// buscamos el archivo en disco
registros.x.dx = (int) argv[2];

// segmento extra apunta al Segmento de pila
sregs.es = sregs.ss;

// inea de comandos asignamos la dir. del bloque de parametros al registro BX
registros.x.bx = (int) &b_param;

// Ejecutamos la interrupcion
ret_codigo = intdosx(&registros,&registros,&sregs);
printf("\n...interrupcion DOS OK\n");
// restauramos los registros de segmento de la rutina principal
_SS = pilaSS;
_SP = pilaSP;

if (!(registros.x.cflag ? ret_codigo : 0))
{
printf("Comando terminado: %s\n", argv[2]);
}
else
{
// Mostrar errores posibles, retornados en AX
switch (registros.x.ax)
{
case 0x0001: { printf("\nFuncion no Valida!\n"); break; }
case 0x0002: { printf("\nArchivo no encontrado!\n"); break; }
case 0x0005: { printf("\nAcceso Denegado!\n"); break; }
case 0x0008: { printf("\nMemoria Insuficiente!\n"); break; }
case 0x000A: { printf("\nArea de ambiente No Valido!\n"); break;}
case 0x000B: { printf("\nFormato No Valido!\n"); break; }
default: { printf("\nHa ocurrido un error, codigo: 0x%x!\n", registros.x.ax ); break; }
} // end switch
}

// obtenemos el codigo retornado por el subproceso
re.h.ah = 0x4d;
intdos(&re,&re);
switch (re.h.ah)
{
case 0x00: { printf("\nTerminacion Normal...\n"); break; }
case 0x01: { printf("\nAbortado por Ctrl-Break...\n"); break; }
case 0x02: { printf("\nTerminacion por error critico...\n"); break; }
case 0x03: { printf("\nTerminacion residente...\n"); break; }
}
// liberamos el bloque de memoria
free(bloque_mem);
printf("\n... liberacion de memoria OK\n");
}
}
else
{
if ( strcmp(argv[1], "-h") == 0 )
{
ayuda();
}
else
{
printf("\nSintaxis no valida!\nUtilice comload -h para ver la ayuda\n");
}
}
/*
re.h.ah = 0x49;
sr.es = ES_anterior;
intdosx(&re,&re,&sr);
if (re.x.cflag) { printf("NO SE PUDO LIBERAR LA MEMORIA\n"); }
*/
// libera el bloque de la rutina principal
freemem(_psp);
return 0;
}

domingo, 16 de septiembre de 2007

Sentencias DML

INSERCION DE AGENCIAS
INSERT INTO Agencias (cod_agencia,nombre,ubicacion,bodega) VALUES('SPS001','Sucursal 3ra. Avenida','San Pedro Sula',default);
....

INSERCION DE CATEGORIAS
INSERT INTO categorias (cod_categoria,categoria) VALUES(1,'Ropa infantil');
.....
INSERCION DE MARCAS
INSERT INTO Marcas (cod_marca,Marca) VALUES(1,'Perry Ellis');
INSERT INTO Marcas (cod_marca,Marca) VALUES(30,'LoveHome');
.....
INSERCION DE PRODUCTOS
INSERT INTO Productos (id_prod,descripcion, isv,consumo_sem,precio_fijo,precio_desc,precio_mayor,unidad_venta,existencia_max,existencia_min,cod_marca,cod_categoria,imagen) VALUES('CA400453','Camisa manga corta','N',100,499.0,380.0,380.0,'unidad',200,1,1,3,NULL);
.....

Sentencias DDL

create table Agencias (
cod_agencia varchar(20) not null,
nombre varchar(30) not null,
ubicacion varchar(50) not null,
bodega char(1) not null default 'N',
primary key(cod_agencia),
);
create table Usuarios (
usuario varchar(30) not null,
clave varchar(30) not null,
cod_agencia varchar(20) not null,
primary key(usuario),
);
Alter table Usuarios add Agencias_FK foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
create table Marcas (
Cod_marca integer not null;
Marca varchar(40) not null,
primary key(Cod_marca),
);
create table categorias (
cod_categoria integer not null,
categoria varchar(30) not null,
primary key(cod_categoria),
);
create table Productos (
id_prod varchar(20) not null,
descripcion varchar(40) not null,
isv char(1) not null,
consumo_sem integer,
precio_fijo double not null,
precio_desc double not null,
precio_mayor double not null,
unidad_venta varchar(20) ,
existencia_max integer ,
existencia_min integer ,
cod_marca integer not null,
cod_categoria integer not null,
primary key(id_prod),
);
Alter table Productos add Marcas foreign key(cod_marca) references Marcas(cod_marca) on update cascade;
Alter table Productos add categorias foreign key(cod_categoria) references categorias(cod_categoria) on update cascade;
create table Factura (
id_doc integer not null,
cliente varchar(30),
cod_agencia varchar(20) not null,
fecha date not null;
primary key(id_doc),
);
Alter table Factura add Agencias foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
create table proveedores (
cod_proveedor varchar(20) not null,
nombre varchar(40) not null,
direccion varchar(60),
telefono varchar(12),
primary key(cod_proveedor ),
);
create table Compra (
id_doc integer not null,
cod_agencia varchar(20) not null,
fecha date not null;
cod_proveedor varchar(20);
primary key(id_doc),
);
Alter table Compra add Agencias foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
Alter table Compra add proveedores foreign key(cod_proveedor) references proveedores(cod_proveedor) on update cascade;
create table Devolucion (
id_doc integer not null,
cod_agencia varchar(20) not null,
factura_id integer not null,
fecha date not null,
primary key(id_doc),
);
Alter table Devolucion add Agencias foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
Alter table Devolucion add Factura foreign key(factura_id) references Factura(id_doc) on update cascade;
create table traslado (
id_doc integer not null,
cod_agencia varchar(20) not null,
agencia_destino varchar(20) not null,
fecha_envio date not null,
fecha_llegada date default '0000-00-00',
primary key(id_doc),
);
Alter table traslado add Agencias foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
alter table traslado add Agencias2 foreign key(agencia_destino) references Agencias(cod_agencia) on update cascade;
create table vende (
id_doc integer not null,
id_prod varchar(20) not null,
cantidad integer not null,
primary key(id_doc,id_prod),
);
Alter table vende add Productos foreign key(id_prod) references Productos(id_prod) on update cascade;
Alter table vende add Factura foreign key(id_doc) references Factura(id_doc) on update cascade;
create table compra_de (
id_doc integer not null,
id_prod varchar(20) not null,
cantidad integer not null,
primary key(id_doc, id_prod),
);
alter table compra_de add Compra foreign key(id_doc) references Compra(id_doc) on update cascade;
alter table compra_de add Productos foreign key(id_prod) references Productos(id_prod) on update cascade;
create table es_devuelto (
id_doc integer not null,
id_prod varchar(20) not null,
cantidad integer not null,
primary key(id_doc,id_prod),
);
Alter table es_devuelto add Devolucion foreign key(id_doc) references Devolucion(id_doc) on update cascade;
Alter table es_devuelto add Productos foreign key(id_prod) references Productos(id_prod) on update cascade;

create table es_trasladado (
id_doc integer not null,
id_prod varchar(20) not null,
cantidad integer not null,
primary key(id_doc,id_prod),
);

Alter table es_trasladado add Productos foreign key(id_prod) references Productos(id_prod) on update cascade;
Alter table es_trasladado add traslado foreign key(id_doc) references traslado(id_doc) on update cascade;
create table kardex (
id_prod integer not null,
num integer not null,
entrada integer not null,
salida integer not null,
existencia integer not null,
debe double not null,
haber double not null,
saldo double not null,
costo_prom double not null,
unitario double not null,
cod_agencia varchar(20) not null,
id_doc_factura integer,
id_doc_devolucion integer,
id_doc_traslado integer,
id_doc_compra integer,
primary key(id_prod, num),
)
Alter table kardex add Productos foreign key(id_prod) references Productos(id_prod) on update cascade;
Alter table kardex add Agencias_FK_kardex foreign key(cod_agencia) references Agencias(cod_agencia) on update cascade;
Alter table kardex add traslado foreign key(id_doc_traslado) references traslado(id_doc) on update cascade;
Alter table kardex add Compra foreign key(id_doc_compra) references Compra(id_doc) on update cascade;
Alter table kardex add Factura foreign key(id_doc_factura) references Factura(id_doc) on update cascade;
Alter table kardex add Devolucion foreign key(id_doc_devolucion) references Devolucion(id_doc) on update cascade;

Modelo ER

MODELO ER

AGENCIAS (cod_agencia, nombre, ubicacion, bodega)
USUARIOS (usuario, clave, cod_agencia)
MARCAS (cod_marca, marca)
CATEGORIAS (cod_categoria, categoría)
PRODUCTOS (id_prod, descripción, isv, consumo_sem, precio_fijo, precio_desc, precio_mayor, unidad_venta, exitencia_max, existencia_min, cod_marca, cod_categoria, imagen)
FACTURA (id_doc, cliente, cod_agencia, fecha)
PROVEEDORES (cod_proveedor, nombre, dirección, teléfono)
COMPRA (id_doc, cod_agencia, fecha, cod_proveedor)
DEVOLUCION (id_doc, cod_agencia, factura_id, fecha)
TRASLADO (id_doc, cod_agencia, agencia_destino, fecha_envio, fecha_llegada)
VENDE (id_doc, id_prod, cantidad)
COMPRA_DE (id_doc, id_prod, cantidad)
ES_DEVUELTO (id_doc, id_prod, cantidad)
ES_TRASLADADO (id_doc, id_prod, cantidad)
KARDEX ( id_prod, num, entrada, salida, existencia, debe, haber, saldo, costo_prom, unitario, cod_agencia, id_doc_factura, id_doc_devolucion, id_doc_traslado, id_doc_compra)

lunes, 23 de julio de 2007

Proyecto

Hemos en conjunto con Elmer Manuel Ferrera y su servidor, Javier Montoya, crear el proyecto de Teoria de Base de Datos con el lenguaje Powerscript (Sybase Powerbuilder).