;;;;;;;;;;;              ;;;;;;;;;;;
;;;  SUPER MAD MAKER by Navi Dj. ;;;
;;;;;;;;;;;              ;;;;;;;;;;;
.MODEL SMALL
.STACK

.DATA
hFont     DB    0
hPantV    DB    0
Handle    DW    -1
Handle2   DW    -1
Pasadas   DW    0
Resto     DW    0
Variable  DW    0
Variable2 DB    0
Variable3 DD    0
MADFile   DB 80 DUP (0)
Fichero   DB 14 DUP (0)
FinMsg          DB      'ERROR: Uso incorrecto. Escribe',0Dh,0Ah
                DB      '   SMADMAK <fichero.mad>$'
Pantalla1       DB      '*cD*p*p*c7S*cDalir al DOS*p*c7A*cDnyadir fichero*0'
Pantalla2       DB      '*cD*pNumero maximo de campos:*0'
Pantalla3       DB      '*cD*pERROR: El fichero no existe*0'
Preg0           DB      '*cD*pCampo total: *0'
Preg1           DB      '*cD*p01 - Graficos*p02 - Sonido*p03 - Datos*pTipo de handle: *0'
Preg2           DB      '*cD*pNumero de handle: *0'
Preg3           DB      '*cD*p01 - Ninguna*p02 - RLE*p03 - Huffman*pTipo de compresion: *0'
Preg4           DB      '*cD*pSub-Tipo de fichero: *0'
Preg5           DB      '*cD*pNombre del fichero: *0'
CadenaHeader    DB      'SUPER MAD-MAKER                 ',01Ah
  Tamanyo       DD      42
  Identificador DB      'IGSX'
  Version       DB      1

.CODE
.386
LOCALS @@
INCLUDE GRFLIB2.INC

PonLetras MACRO msg
          MOV     SI, Offset msg
          MOV     BL, 0
          MOV     BH, 1
          MOV     CL, 10
          MOV     DL, 20
          MOV     AL, hFont
          CALL    Write           ;  Pregunta el n£mero de campos totales.
          ENDM

PreguntaB MACRO
          MOV     AL, hFont
          MOV     AH, 10
          MOV     BL, 0
          MOV     BH, 1
          MOV     CL, 10
          MOV     DL, 20
          MOV     DX, Offset Variable2
          CALL    LeeByte
          MOV     AL, Variable2
          ENDM

PreguntaW MACRO
          MOV     AL, hFont
          MOV     AH, 10
          MOV     BL, 0
          MOV     BH, 1
          MOV     CL, 10
          MOV     DL, 20
          MOV     DX, Offset Variable
          CALL    LeeWord
          MOV     AX, Variable
          ENDM

ClearScr  MACRO
          MOV     AL, hPantV
          XOR     CL, CL
          CALL    BorraPantalla
          XOR     DX, DX
          XOR     BX, BX
          CALL    SetCursor
          ENDM

GuardaB   MACRO
          MOV     Variable2, AL
          MOV     DX, Offset Variable2
          MOV     AH, 40h
          MOV     BX, Handle
          MOV     CX, 1
          INT     21h
          ENDM

GuardaW   MACRO
          MOV     Variable, AX
          MOV     DX, Offset Variable
          MOV     AH, 40h
          MOV     BX, Handle
          MOV     CX, 2
          INT     21h
          ENDM

GuardaD   MACRO
          MOV     Variable3, EAX
          MOV     DX, Offset Variable3
          MOV     AH, 40h
          MOV     BX, Handle
          MOV     CX, 4
          INT     21h
          ENDM

SeekSet   MACRO nHand
          MOV     AX, 4200h
          MOV     BX, nHand
          XOR     DX, DX
          XOR     CX, CX
          INT     21h
          ENDM

SeekEnd   MACRO nHand
          MOV     AX, 4202h
          MOV     BX, nHand
          XOR     DX, DX
          XOR     CX, CX
          INT     21h
          ENDM

GetPos    MACRO nHand
          MOV     AX, 4201h
          MOV     BX, nHand
          XOR     DX, DX
          XOR     CX, CX
          INT     21h
          ENDM

PantPrincipal   PROC
                PUSH    DS
                MOV     SI, Offset Pantalla1
                MOV     BL, 0
                MOV     BH, 1
                MOV     CL, 10
                MOV     DL, 20
                MOV     AL, hFont
                CALL    Write
                POP     DS

        @@Bucle:XOR     AH, AH
                INT     16h
                CMP     AL, 's'
                JE    @@Salir
                CMP     AL, 'S'
                JE    @@Salir
                CMP     AL, 'a'
                JE    @@Anyadir
                CMP     AL, 'A'
                JE    @@Anyadir
                JMP   @@Bucle
        @@Salir:MOV     AL, 0
                RET
        @@Anyadir:
                MOV     AL, 1
                RET
PantPrincipal   ENDP

LeeParam        PROC
                MOV     DI, 80h
                MOVZX   CX, BYTE PTR [DI]
                INC     DI
                MOV     AL, ' '
                REP  SCASB
                JCXZ   ErrorParam
                DEC     DI
                INC     CX
                PUSH    ES
                POP     DS
                PUSH    CS
                POP     ES
                MOV     SI, Offset MADFile
                XCHG    SI, DI
                REP  MOVSB
                RET
        ErrorParam:
                CALL    EndGRAPH
                MOV     AX, @DATA
                MOV     DS, AX
                MOV     AH, 9
                MOV     DX, Offset FinMsg
                INT     21h
                MOV     AX, 4C00h
                INT     21h
LeeParam        ENDP

InicializaMAD   PROC
                MOV     AL, 8
                CALL    CambiaTipo
                CALL    CogeFuenteDOS
                MOV     hFont, AL
                MOV     AH, 48h
                MOV     BX, 65000/16    ;  Buffer de 64000 bytes aprox.
                INT     21h
                MOV     FS, AX          ;  FS = Segmento reservado.
                MOV     ES, AX
                MOV     CX, 64000/4
                XOR     EAX, EAX
                XOR     DI, DI
                REP  STOSD
                MOV     DX, Offset MADFile
                MOV     AX, 3D02h
                INT     21h             ;  Abrir el fichero si existe.
                JC    @@NuevoFichero
                MOV     Handle, AX
                PUSH    DS
                MOV     BX, Handle
                PUSH    FS
                POP     DS
                MOV     AH, 3Fh
                MOV     CX, 42
                XOR     DX, DX
                INT     21h             ;  Leemos la cabecera.
                CMP     DS:[0037], 'XSGI'
                POP     DS
                JNE    ErrorParam       ;  Si no es un MAD.
                JMP   @@CierraMAD
        @@NuevoFichero:
                XOR     CX, CX
                MOV     AH, 3Ch
                MOV     DX, Offset MADFile
                INT     21h
                MOV     Handle, AX
                MOV     SI, Offset Pantalla2
                MOV     BL, 0
                MOV     BH, 1
                MOV     CL, 10
                MOV     DL, 20
                MOV     AL, hFont
                CALL    Write           ;  Pregunta el n£mero de campos totales.
                MOV     AL, hFont
                MOV     AH, 10
                MOV     BL, 0
                MOV     BH, 1
                MOV     CL, 10
                MOV     DL, 20
                MOV     DX, Offset Variable
                CALL    LeeWord
                MOV     CX, Variable
                MOV     AX, 14
                MUL     CX
                MOV     ECX, Tamanyo
                AND     EAX, 0FFFFh
                ADD     ECX, EAX
                MOV     Tamanyo, ECX    ;  Se guarda el tama¤o total.
                MOV     BX, Handle
                MOV     AH, 40h
                MOV     CX, 42
                MOV     DX, Offset CadenaHeader
                INT     21h
                MOV     EAX, Tamanyo
                SUB     EAX, 42
                PUSH    DS
                MOV     BX, Handle
                PUSH    FS
                POP     DS
                MOV     ECX, EAX
                MOV     AH, 40h
                XOR     DX, DX
                INT     21h             ;  Leemos la cabecera.
                POP     DS
        @@CierraMAD:
                RET
InicializaMAD   ENDP

Main            PROC
                CALL    LiberaMEM       ;  Liberamos la memoria asignada por
                CALL    LeeParam        ; el DOS.
                MOV     BX, 1
                MOV     EAX, 010b
                CALL    InicGRAPH
                MOV     AX, @DATA
                MOV     DS, AX
                CALL    InicializaMAD   ;  Se inicializan algunos par metros.

        @@Principal:
                XOR     DX, DX
                XOR     BX, BX
                CALL    SetCursor
                XOR     AL, AL
                XOR     CL, CL
                CALL    BorraPantalla
                CALL    PantPrincipal   ;  Dibuja la pantalla principal.
        @@Eleccion:
                CMP     AL, 0
                JE    @@Salir
                CMP     AL, 1
                JE    @@Anyadir
                JMP   @@Eleccion
        @@Salir:MOV     BX, Handle
                MOV     AH, 3Eh
                INT     21h             ;  Cerramos el fichero.
                MOV     BX, Handle2
                MOV     AH, 3Eh
                INT     21h             ;  Cerramos el fichero.
                MOV     AL, hFont
                CALL    DestFuente
                CALL    EndGRAPH
                MOV     AX, 4C00h
                INT     21h             ;  Salida al DOS.
        @@Anyadir:
                ClearScr
                PonLetras Preg0         ;  Campo Total
                PreguntaW
                MOV     BX, 14
                MUL     BX              ;  Conseguimos la posici¢n de inicio
                ADD     AX, 42          ; de la estructura.
                MOV     DX, AX
                XOR     CX, CX
                MOV     AX, 4200h
                MOV     BX, Handle
                INT     21h             ;  No movemos hasta la posici¢n.
                ClearScr
                PonLetras Preg1         ;  Tipo
                PreguntaB
                GuardaB
                ClearScr
                PonLetras Preg2         ;  Handle
                PreguntaW
                GuardaW
                ClearScr
                PonLetras Preg3         ;  Compresion
                PreguntaB
                GuardaB
                ClearScr
                PonLetras Preg4         ;  Subtipo
                PreguntaW
                GuardaW
                GetPos  Handle          ;  Cogemos la posici¢n donde estamos.
                PUSH    AX
                PUSH    DX
                SeekEnd Handle          ;  Nos vamos al final.
                SHL     EDX, 16
                MOV     DX, AX
                MOV     Variable3, EDX
                POP     CX
                POP     DX              ;  Recuperamos la posici¢n.
                MOV     AX, 4200h
                MOV     BX, Handle
                INT     21h
                MOV     EAX, Variable3
                GuardaD                 ;  Escribimos el desplazamiento.
                ClearScr
                PonLetras Preg5         ;  Nombre del fichero.
                MOV     AL, hFont
                MOV     BH, 1
                XOR     BL, BL
                MOV     DX, Offset Fichero
                MOV     CX, 12
                MOV     AH, 10
                CALL    LeeCadena
                MOV     DX, Offset Fichero
                MOV     AX, 3D00h
                INT     21h
                JC    @@NoExiste
                MOV     Handle2, AX
                SeekEnd Handle2
                PUSHAD
                SHL     EDX, 16
                MOV     DX, AX
                GuardaD                 ;  Guardamos el tama¤o.
                POPAD
                MOV     BX, 64000       ;  Tama¤o aprox. de nuestro buffer.
                DIV     BX              ;  En AX las pasadas que hay que hacer
                MOV     Pasadas, AX     ; y en DX el resto de bytes.
                MOV     Resto, DX
                SeekSet Handle2
                SeekEnd Handle
         @@BucleCopia:
                DEC     Pasadas
                JS    @@Ultima
                PUSH    DS
                MOV     AH, 3Fh
                MOV     BX, Handle2
                MOV     CX, 64000
                XOR     DX, DX
                PUSH    FS
                POP     DS
                INT     21h             ;  Leemos del fichero.
                POP     DS
                PUSH    DS
                MOV     AH, 40h
                MOV     BX, Handle
                MOV     CX, 64000
                XOR     DX, DX
                PUSH    FS
                POP     DS
                INT     21h             ;  Escribimos en el fichero.
                POP     DS
                JMP   @@BucleCopia
           @@Ultima:
                PUSH    DS
                MOV     AH, 3Fh
                MOV     BX, Handle2
                MOV     CX, Resto
                XOR     DX, DX
                PUSH    FS
                POP     DS
                INT     21h             ;  Leemos del fichero.
                POP     DS
                PUSH    DS
                MOV     AH, 40h
                MOV     BX, Handle
                MOV     CX, Resto
                XOR     DX, DX
                PUSH    FS
                POP     DS
                INT     21h             ;  Escribimos en el fichero.
                POP     DS
                ClearScr
                JMP   @@Principal
        @@NoExiste:
                PonLetras Pantalla3
                XOR     AH, AH
                INT     16h
                JMP   @@Principal
Main            ENDP
                END     Main
