home *** CD-ROM | disk | FTP | other *** search
/ Bila Vrana / BILA_VRANA.iso / 005A / TDSK22SR.ZIP / BITDISK.ASM next >
Assembly Source File  |  1995-06-22  |  66KB  |  1,485 lines

  1.  
  2. ;┌───────────────────────────────────────────────────────────────────┐
  3. ;│                                                                   │
  4. ;│  BITDISK 1.1 - Source code for the 256-bytes Resizeable Ramdisk   │
  5. ;│                                                                   │
  6. ;│                 100% freeware  -  100% public domain              │
  7. ;│                                                                   │
  8. ;│ (C) 1994-1995 Ciriaco García de Celis   Email:   ciri@gui.uva.es  │
  9. ;│    Grupo Universitario de Informática   Fidonet: 2:341/21.8       │
  10. ;│          Facultad de Ciencias                                     │
  11. ;│    Universidad de Valladolid  (Spain)                             │
  12. ;│                                                                   │
  13. ;│  ■ Contributions to save memory, and German messages by:          │
  14. ;│       Axel Christoph Frinke  <acfrinke@uni-bonn.de>               │
  15. ;│  ■ Switchar support added by                                      │
  16. ;│       Matthias Paul  <mpaul@ibh.rwth-aachen.de>                   │
  17. ;│                                                                   │
  18. ;│  The world's smallest resizeable RamDisk driver for DOS/WINDOWS   │
  19. ;│                                                                   │
  20. ;│        - Only takes 256 bytes of conventional/upper memory!!      │
  21. ;│        - Supports XMS memory. Only for AT or better.              │
  22. ;│        - 100% English, Spanish and German messages.               │
  23. ;│        - Based on XDISK driver (published in spanish PC-WORLD     │
  24. ;│          edition, June 1993) and TDSK (article from spanish       │
  25. ;│          edition of Microsoft Systems Journal, November 1992).    │
  26. ;│                                                                   │
  27. ;│          Assembly with TASM/MASM and link with TLINK/LINK         │
  28. ;│              No warranties for damages or malfunction             │
  29. ;│                                                                   │
  30. ;└───────────────────────────────────────────────────────────────────┘
  31.  
  32. ; ------------  Please excuse spanish comments in some source
  33. ;               sections, if you don't understand them well.
  34.  
  35.                .286                    ; only 286 or better CPU
  36.  
  37. XPUSH          MACRO regmem            ; push a list of registers
  38.                  IRP rm, <regmem>
  39.                    PUSH rm
  40.                  ENDM
  41.                ENDM
  42.  
  43. XPOP           MACRO regmem            ; pop a list of registers
  44.                  IRP rm, <regmem>
  45.                    POP rm
  46.                  ENDM
  47.                ENDM
  48.  
  49. ; ************ Ramdisk: Init of resident area.
  50.  
  51. _BITDISK       SEGMENT
  52.                ASSUME CS:_BITDISK, DS:_BITDISK
  53.  
  54.                DD   -1            ; chain with other device drivers
  55.                DW    0            ; attributes word
  56.                DW    estrategia   ; strategy routine
  57.                DW    interrupcion ; interrupt routine
  58.                DB    1            ; number of drives
  59.  
  60. cs_bitdisk     DW    ?
  61. id_bitdisk     DB    "BDK"   ; this is BITDISK
  62. letra_unidad   DB    ?       ; ASCII drive letter of disk ('C',...)
  63.  
  64. status         EQU BYTE PTR StatPtr+2
  65.                              ; 0: disk not formatted
  66.                              ; 1: used XMS 2.0+ memory
  67.                              ; 0FFh: INIT still not run
  68.  
  69. cambiado       EQU BYTE PTR cambptr+3
  70.                              ; after formatting the RamDisk is set
  71.                              ; to 0FFh (to mean "disk change")
  72.  
  73. drv_media      EQU   0FAh    ; media descriptor byte
  74.  
  75. bpb_ptr        DW    bpb     ; points to disk BPB
  76.  
  77. bpb            LABEL BYTE    ; These BPB values are arbitrary, but
  78. bytes_sector   DW    512     ; they are correct (if not, DOS may
  79. sect_cluster   DB    1       ; hang while loading the device driver
  80. sect_reserv    DW    1       ; and performing its internal calcs).
  81. num_fats       DB    1
  82. entradas_raiz  DW    128
  83. num_sect       DW    128
  84. media_byte     DB    drv_media
  85. sectores_fat   DW    4
  86. fin_bpb        EQU   $
  87.  
  88. ; ------------ Strategy and interrupt routines of RamDisk.
  89. ;              Important: It is assumed that DOS calls first the
  90. ;                         strategy routine, and then (without
  91. ;                         modifying ES:BX) the interrupt one.
  92.  
  93. interrupcion   PROC  FAR
  94.                PUSHA                   ; *
  95.                PUSH  DS                ; **
  96.                PUSH  ES
  97.                POP   DS                ; DS:BX -> request header
  98.                XPUSH <BX, DS>
  99.                MOV   AX,2              ; AH = 0, AL = 2
  100. StatPtr:       CMP   AH,0FFH           ; patched area (location of status)
  101.                JE    exit_error        ; unformatted disk: error
  102.                XLAT                    ; AX = [BX+2] = order (AH = 0)
  103. patch_init:    JMP   init              ; after install: XOR BP,BP/DEC AX
  104.                JNZ   no_media_chk      ; the order is not 1
  105. cambptr:       MOV   BYTE PTR [BX+14],0; patched area (location of cambiado)
  106.                MOV   CS:cambiado,1     ; the disk will not change more...
  107.                JMP   exit_ok
  108. no_media_chk:  DEC   AX
  109.                JNZ   no_build_bpb      ; the order is not 2
  110.                MOV   WORD PTR [BX+18],OFFSET bpb
  111.                MOV   [BX+20],CS
  112. exit_ok:       MOV   AX,100h
  113.                JMP   exit_
  114. no_build_bpb:  SUB   AL,6
  115.                JZ    prep_io           ; order 8: write (BP=0)
  116.                DEC   AX
  117.                JZ    prep_io           ; order 9: write verify
  118.                INC   BP
  119.                ADD   AL,5
  120.                JZ    prep_io           ; order 4: read (BP=1)
  121.                MOV   AL,3              ; unsupported order
  122. exit_error:    MOV   AH,81h
  123. exit_:         XPOP  <DS, BX>
  124. exit_final:    MOV   [BX+3],AX
  125.                POP   DS                ; **
  126.                POPA                    ; *
  127. estrategia:    RET
  128. interrupcion   ENDP
  129.                                            ; prepare registers for I/O
  130. prep_io:       LES   DI,[BX+14]            ; * buffer adrress in ES:DI
  131.                LDS   AX,[BX+18]            ; number of sectors in AX
  132.                MOV   BX,DS                 ; first sector, DS undefined!
  133. direct_io:     MOV   SI,CS:bytes_sector
  134.                ADD   AX,BX
  135.                JNC   io_ok?                ; last sector < 65536
  136. io_no_ok:      MOV   AL,8                  ; «sector not found»
  137.                JMP   exit_error
  138. io_ok?:        CMP   AX,CS:num_sect
  139.                JA    io_no_ok              ; ending sector outside!
  140.                SUB   AX,BX
  141.                MUL   SI                    ; DX(CF):AX = block size
  142.                RCR   AX,1                  ; CF:AX/2 -> AX = words
  143.                MOV   CX,DI
  144.                NEG   CX                    ; 10000h-CX: CF=1 if CX<>0
  145.                CMC                         ; CF:CX bytes to the end of
  146.                RCR   CX,1                  ; segment = (10000h-DI)/2
  147.                CMP   AX,CX
  148.                JAE   io_cx_ok
  149.                MOV   CX,AX                 ; * size: CX words
  150. io_cx_ok:      JCXZ  io_no_ok              ; CX=0 if DI=0FFFFh (fatal)
  151.                MOV   AX,BX                 ; initial sector
  152.                MUL   SI                    ; * offset in DX:AX
  153.  
  154.                DEC   BP                ; read/write in the disk
  155.                JNZ   xms_escribe
  156.                XPUSH <ES,DI,BP>        ; segm:offs and destination handle
  157. xms_escribe:   XPUSH <DX,AX>           ; offset DX:AX
  158.                DB    68h               ; opcode of «PUSH inmediate»
  159. xms_handle     DW    ?                 ; source/destination handle
  160.                JZ    xms_general
  161.                INC   BP                ; this makes BP = 0
  162.                XPUSH <ES,DI,BP>        ; segm:offs and source handle
  163. xms_general:   SHL   CX,1              ; words -> bytes
  164.                RCL   BP,1              ; BP was 0
  165.                XPUSH <BP,CX>           ; block size in BP:CX
  166.                MOV   SI,SP
  167.                PUSH  SS
  168.                POP   DS                ; DS:SI pointing to stack
  169.                MOV   AH,0Bh            ; function to move EMB
  170.                DB    9Ah               ; opcode of CALL FAR SEG:OFF
  171. xms_driver     LABEL DWORD             ; address of XMS driver
  172. xms_desp       DW    ?
  173. xms_segm       DW    ?
  174.                ADD   SP,16             ; equilibrate stack
  175.                SHR   AX,1              ; bit 0 from AX -> CF
  176.                JC    exit_ok
  177. trans_error:   XPOP  <DS, BX>
  178.                MOV   WORD PTR [BX+18],AX  ; 0 sectors moved (AX=0)
  179.                MOV   AX,810Ch          ; error code
  180.                JMP   exit_final
  181.  
  182.                ; <<< Ends of resident code for RamDisk >>>
  183.  
  184.  
  185. ; ************ Instalación (desde CONFIG.SYS).
  186.  
  187. init           PROC
  188.                MOV   WORD PTR CS:patch_init,0ED31h ; código XOR BP,BP
  189.                MOV   BYTE PTR CS:patch_init+2,48h  ; código DEC AX
  190.                INC   CS:status              ; 0: disco no formateado
  191.                MOV   CS:cs_bitdisk,CS       ; inicializar esa variable
  192.                MOV   BYTE PTR [BX+13],1     ; una unidad de disco
  193.                LEA   AX,bpb_ptr
  194.                MOV   [BX+18],AX
  195.                MOV   [BX+20],CS             ; inicializado puntero BPB
  196.                MOV   AL,[BX+22]             ; unidad en DOS 3.0+
  197.                ADD   AL,'A'
  198.                PUSH  CS
  199.                POP   DS
  200.                MOV   letra_unidad,AL        ; guardar letra de unidad
  201.                MOV   inf_drv_conf,AL
  202.                LEA   DX,install_txt
  203.                CALL  imprimir
  204.                LEA   DX,inf_drv_conf
  205.                CALL  imprimir
  206.                XPOP  <DS, BX>               ; DS:BX -> request header
  207.                XPUSH <BX, DS>
  208.                MOV   WORD PTR [BX+14],OFFSET init  ; área residente
  209.                MOV   [BX+16],CS
  210.                JMP   exit_ok
  211. init           ENDP
  212.  
  213. ; ************ Redefinición (invocada desde el AUTOEXEC.BAT o el DOS).
  214.  
  215. main           PROC  FAR
  216.                MOV   AX,_BITDISK            ; programa de un segmento
  217.                MOV   DS,AX                  ; DS: -> _BITDISK
  218.                MOV   BX,81h                 ; ES:BX línea de órdenes
  219.                CALL  ges_param              ; procesar parámetros
  220.                CMP   param_h,ON
  221.                JE    exit_instalar          ; piden ayuda
  222.                MOV   AX,DS
  223.                MOV   ES,AX                  ; ES: --> _BITDISK
  224.                CALL  reside_bitdsk?         ; ¿instalado BITDISK?
  225.                CMP   segm_bitdisk,0
  226.                JE    salida_fatal           ; no instalado aún
  227.                MOV   ES,segm_bitdisk        ; ES: --> disco residente
  228.                TEST  lista_err,ERROR0       ; ¿error sintaxis?
  229.                JNZ   exit_instalar          ; sí: no modificar disco
  230.                CMP   param_unidad,0
  231.                JE    disco_defecto          ; no indicada letra unidad
  232.                CALL  obtener_segm           ; segmento de la unidad
  233.                JC    salida_fatal           ; fallo (no es un BITDISK)
  234. disco_defecto: CMP   param_tdiscof,ON
  235.                JNE   exit_instalar          ; no indicado nuevo tamaño
  236.                CMP   ES:status,0
  237.                JE    cont_instalar          ; no estaba formateado aún
  238.                CALL  desinstala             ; liberar memoria ocupada
  239. cont_instalar: CALL  info_xms               ; evaluar memoria XMS
  240.                CMP   tdisco,0               ; ¿se reservará memoria?
  241.                JE    exit_instalar          ; no: no hay más que hacer
  242.                CALL  reserva_xms            ; reservar memoria
  243.                JC    exit_instalar          ; fallo reservando memoria
  244.                CALL  params_disco           ; adaptar parámetros disco
  245.                CALL  formatear              ; BOOT, FAT y ROOT
  246. exit_instalar: CALL  info_bitdisk           ; informar sobre el disco
  247.                MOV   AX,4C00h
  248.                INT   21h                    ; final
  249. salida_fatal:  LEA   DX,bitdisk_noins
  250.                JNC   mens_ok
  251.                LEA   DX,bitdisk_noes
  252. mens_ok:       CALL  imprimir
  253.                MOV   AX,4C00h
  254.                INT   21h
  255. main           ENDP
  256.  
  257. ; ------------ Leer los parámetros de la línea de comandos (ES:BX).
  258.  
  259. ges_param      PROC
  260.                CALL  swc_patch         ; align to switchar
  261.                CALL  busca_param       ; saltar delimitadores
  262.                JC    fin_param         ; no hay más parámetros
  263. swchr0:        CMP   AX,"i/"
  264.                JE    cod_tel
  265. swchr1:        CMP   AX,"?/"
  266.                JE    si_ayuda
  267. swchr2:        CMP   AX,"h/"
  268.                JNE   no_ayuda
  269. si_ayuda:      MOV   param_h,ON
  270.                JMP   fin_param
  271. cod_tel:       ADD   BX,3
  272.                CMP   BYTE PTR ES:[BX-1],'='
  273.                JE    p_id_ok
  274.                CMP   BYTE PTR ES:[BX-1],':'
  275.                JE    p_id_ok
  276. p_id_ok:       CALL  obt_num           ; leer código telefónico
  277.                MOV   param_i,ON
  278.                MOV   codigo_tfno,AX
  279.                JMP   ges_param
  280. no_ayuda:      CMP   AH,':'
  281.                JNE   no_unidad
  282.                AND   AL,255-32         ; poner en mayúsculas
  283.                MOV   param_unidad,AL
  284.                ADD   BX,2
  285.                CALL  busca_param
  286.                JC    fin_param
  287. no_unidad:     CALL  obt_num
  288.                MOV   param_tdisco,AX   ; es numérico: tamaño del disco
  289.                MOV   param_tdiscof,ON  ; parámetro de tamaño indicado
  290.                CALL  busca_param
  291.                JC    fin_param
  292.                CALL  obt_num
  293.                MOV   param_tsect,AX    ; tamaño de sector
  294.                CALL  busca_param
  295.                JC    fin_param
  296.                CALL  obt_num
  297.                MOV   param_tdir,AX     ; entradas al directorio
  298.                CALL  busca_param
  299.                JC    fin_param
  300.                CALL  obt_num
  301.                MOV   param_tcluster,AX ; tamaño de cluster
  302. fin_param:     CALL  validar
  303.                RET
  304. ges_param      ENDP
  305.  
  306. validar        PROC
  307.                MOV   AX,param_tdisco   ; ¿números correctos?
  308.                OR    AX,param_tsect
  309.                OR    AX,param_tdir
  310.                OR    AX,param_tcluster
  311.                CMP   AX,0FFFFh
  312.                JE    sintax_err
  313.                CMP   param_tdisco,0
  314.                JE    valida_tsect      ; no indicado tamaño (o 0)
  315.                CMP   param_tdisco,4
  316.                JB    sintax_err
  317.                CMP   param_tdisco,32768
  318.                JA    sintax_err
  319. valida_tsect:  CMP   param_tsect,0
  320.                JE    valida_tclus      ; no indicado tamaño de sector
  321.                CMP   param_tsect,64
  322.                JE    valida_tclus
  323.                CMP   param_tsect,128
  324.                JE    valida_tclus
  325.                CMP   param_tsect,256
  326.                JE    valida_tclus
  327.                CMP   param_tsect,512
  328.                JNE   sintax_err
  329. valida_tclus:  CMP   param_tcluster,256
  330.                JB    fin_validar
  331. sintax_err:    MOV   param_tdiscof,OFF  ; no definir disco ahora
  332.                MOV   param_tdisco,0
  333.                MOV   param_tsect,0
  334.                MOV   param_tdir,0
  335.                MOV   param_tcluster,0
  336.                OR    lista_err,ERROR0   ; aviso de error de sintaxis
  337. fin_validar:   RET
  338. validar        ENDP
  339.  
  340. busca_param    PROC                    ; saltar delimitadores
  341.                DEC   BX
  342. p_delimit:     INC   BX
  343.                MOV   AX,ES:[BX]
  344.                CMP   AL,' '
  345.                JE    p_delimit         ; espacio en blanco
  346.                CMP   AL,9
  347.                JE    p_delimit         ; tabulador
  348.                CMP   AL,13
  349.                JE    p_final           ; CR ó LF indican el final
  350.                CMP   AL,10
  351.                JE    p_final
  352.                OR    AX,"  "           ; poner en minúsculas
  353.                CLC
  354.                RET
  355. p_final:       STC                     ; se acabaron los parámetros
  356.                RET
  357. busca_param    ENDP
  358.  
  359. obt_num        PROC                    ; leer número: devolver 65535
  360.                XPUSH <CX,DX,SI>        ; si hay error
  361.                XOR   AX,AX             ; número en proceso de creación
  362. otro_digito:   MOV   CL,ES:[BX]
  363.                CMP   CL,'0'
  364.                JB    no_digito
  365.                CMP   CL,'9'
  366.                JBE   digito_ok
  367. no_digito:     CMP   CL,' '            ; posibles delimitadores...
  368.                JE    fin_num
  369.                CMP   CL,9
  370.                JE    fin_num
  371.                CMP   CL,13
  372.                JE    fin_num
  373.                CMP   CL,10
  374.                JE    fin_num
  375. swchr3:        CMP   CL,'/'
  376.                JE    fin_num
  377.                JMP   num_incorr
  378. digito_ok:     XOR   DX,DX
  379.                MOV   SI,10
  380.                MUL   SI                ; AX = AX * 10
  381.                JC    num_incorr
  382.                XOR   CH,CH
  383.                SUB   CL,'0'
  384.                ADD   AX,CX             ; AX = AX + dato
  385.                JC    num_incorr
  386.                INC   BX
  387.                JMP   otro_digito
  388. num_incorr:    MOV   AX,65535          ; indicar valor incorrecto
  389. fin_num:       XPOP  <SI,DX,CX>
  390.                RET
  391. obt_num        ENDP
  392.  
  393. swc_patch      PROC
  394.                XPUSH <AX,CX,DX,DI,ES>
  395.                MOV   DL, '/'           ; assume default, if no switchar-supported
  396.                MOV   AX, 3700h
  397.                INT   21h
  398.                CMP   AL, 00h           ; should indicate 'function supported'
  399.                JNE   swc_nosup
  400.                CMP   DL, ' '           ; couldn't be valid switchar below space
  401.                JNA   swc_nosup
  402.                MOV   BYTE PTR [swchr0+1],DL
  403.                MOV   BYTE PTR [swchr1+1],DL
  404.                MOV   BYTE PTR [swchr2+1],DL
  405.                MOV   BYTE PTR [swchr3+2],DL
  406.                MOV   AL, '/'
  407.                CLD
  408.                MOV   DI, OFFSET bitdisk_noins
  409.                MOV   CX, bitdisk_noes-bitdisk_noins; length
  410.                PUSH  CS
  411.                POP   ES
  412. swc_loop:      REPNZ SCASB             ; adapt this, if the help pages text will
  413.                CMP   BYTE PTR [DI], '?'; change in the future.
  414.                JNE   swc_nosup         ; by the moment it scans only for '/?'
  415.                MOV   BYTE PTR [DI-1],DL; replace occurence with current switchar
  416.                CMP   CX, 0
  417.                JA    swc_loop
  418. swc_nosup:     XPOP  <ES,DI,DX,CX,AX>
  419.                RET
  420. swc_patch      ENDP
  421.  
  422. ; ------------ Obtener el segmento de la unidad BITDISK indicada.
  423.  
  424. obtener_segm   PROC
  425.                CALL  lista_drv
  426.                LEA   SI,area_trabajo-4
  427. busca_ultimo:  ADD   SI,4
  428.                CMP   WORD PTR [SI],0
  429.                JNE   busca_ultimo      ; realmente, el primero
  430. recorre_dsks:  SUB   SI,4
  431.                CMP   SI,OFFSET area_trabajo
  432.                JB    bitdsk_no_hay
  433.                CMP   BYTE PTR [SI+3],1
  434.                JNE   recorre_dsks
  435.                PUSH  DS
  436.                MOV   DS,[SI]
  437.                MOV   AL,letra_unidad
  438.                POP   DS
  439.                CMP   AL,param_unidad   ; disco BITDISK ¿es el buscado?
  440.                JNE   recorre_dsks
  441.                MOV   letra_unidad,AL   ; inicializar letra de unidad
  442.                MOV   AX,[SI]
  443.                MOV   segm_bitdisk,AX   ; inicializar segmento
  444.                MOV   ES,AX
  445.                CLC
  446.                RET
  447. bitdsk_no_hay: STC
  448.                RET
  449. obtener_segm   ENDP
  450.  
  451. ; ------------ Verificar la presencia en memoria de BITDISK.
  452.  
  453. reside_bitdsk? PROC
  454.                XPUSH <AX,DX,SI>
  455.                CALL  lista_drv
  456.                LEA   SI,area_trabajo-4
  457. busca_final:   ADD   SI,4
  458.                CMP   WORD PTR [SI],0
  459.                JNE   busca_final       ; ir al final de la tabla
  460. busca_bdsk:    SUB   SI,4
  461.                CMP   SI,OFFSET area_trabajo
  462.                JB    fin_busca         ; no reside (segm_bitdisk = 0)
  463.                CMP   BYTE PTR [SI+3],1
  464.                JNE   busca_bdsk
  465.                MOV   AX,[SI]           ; encontrada unidad BITDISK
  466.                MOV   segm_bitdisk,AX
  467.                PUSH  DS
  468.                MOV   DS,AX
  469.                MOV   AL,letra_unidad
  470.                POP   DS
  471.                MOV   letra_unidad,AL
  472. fin_busca:     XPOP  <SI,DX,AX>
  473.                RET
  474. reside_bitdsk? ENDP
  475.  
  476. ; ------------ Crear lista con todos los dispositivos de bloque.
  477.  
  478. lista_drv      PROC
  479.                XPUSH <BX,CX,DI,ES>
  480.                MOV   AH,52h            ; "Get list of lists"
  481.                INT   21h               ; obtener puntero en ES:BX
  482.                ADD   BX,22h            ; versiones del DOS 3.1+
  483.                LEA   DI,area_trabajo-4 ; tabla de dispositivos-4
  484. disp_otro:     ADD   DI,4
  485. disp_skip:     LES   BX,ES:[BX]        ; siguiente dispositivo
  486.                CMP   BX,-1
  487.                JE    disp_fin
  488.                TEST  BYTE PTR ES:[BX+5],80h
  489.                JNZ   disp_skip         ; es dispositivo de caracteres
  490.                MOV   CL,ES:[BX+10]     ; es de bloques
  491.                MOV   [DI],ES           ; anotar dirección
  492.                MOV   [DI+2],CL
  493.                MOV   BYTE PTR [DI+3],0 ; de momento, no es BITDISK
  494.                PUSH  DI
  495.                LEA   SI,id_bitdisk     ; identificación de BITDISK
  496.                MOV   DI,SI
  497.                MOV   CX,3
  498.                CLD
  499.                REP   CMPSB             ; ¿es BITDISK?
  500.                POP   DI
  501.                JNE   disp_otro         ; de bloques, pero no BITDISK
  502.                MOV   AX,ES:cs_bitdisk  ; segmento real de BITDISK
  503.                MOV   [DI],AX           ; corregir dirección en tabla
  504.                INC   BYTE PTR [DI+3]   ; indicar dispositivo BITDISK
  505.                JMP   disp_otro         ; buscar hasta completar tabla
  506. disp_fin:      MOV   WORD PTR [DI],0   ; final de la lista
  507.                XPOP  <ES,DI,CX,BX>
  508.                RET
  509. lista_drv      ENDP
  510.  
  511. ; ------------ Liberar la memoria ocupada por un BITDISK residente
  512.  
  513. desinstala     PROC
  514.                MOV   DX,ES:xms_handle
  515.                MOV   AH,0Ah
  516.                CALL  ES:xms_driver
  517.                CMP   AX,1
  518.                JE    desinstalado      ; éxito al liberar memoria XMS
  519.                STC
  520. desinstalado:  MOV   ES:status,0       ; disco «no formateado»
  521.                JNC   desins_ok
  522.                OR    lista_err,ERROR14 ; fallo al liberar memoria
  523.                STC
  524. desins_ok:     RET
  525. desinstala     ENDP
  526.  
  527. ; ------------ Determinar cantidad de memoria XMS que hay para BITDISK
  528.  
  529. info_xms       PROC
  530.                MOV   tdisco,0          ; ley de Murphy
  531.                PUSH  ES
  532.                MOV   AX,4300h
  533.                INT   2Fh
  534.                CMP   AL,80h            ; ¿hay controlador XMS?
  535.                JNE   xms_ok
  536.                MOV   AX,4310h          ; obtener su dirección
  537.                INT   2Fh
  538.                MOV   xms_segm,ES
  539.                MOV   xms_desp,BX
  540.                MOV   AH,8
  541.                CALL  xms_driver        ; preguntar memoria libre
  542.                AND   AX,AX
  543.                JNZ   xms_kb_ok         ; no hubo fallo
  544.                CMP   BL,0A0h
  545.                JE    xms_kb_ok         ; asignada ya toda la memoria
  546.                TEST  BL,80h
  547.                JZ    xms_kb_ok         ; no hay memoria XMS disponible
  548.                OR    lista_err,ERROR8  ; fallo real del controlador
  549. xms_kb_ok:     CMP   AX,4              ; mayor bloque XMS disponible
  550.                JB    xms_ok
  551.                MOV   xms_kb,AX         ; mínimo necesario: 4 Kb
  552. xms_ok:        POP   ES
  553.                MOV   AX,param_tdisco
  554.                MOV   BX,xms_kb
  555.                AND   BX,BX
  556.                JNZ   usara_xms
  557.                OR    lista_err,ERROR6  ; no hay memoria XMS disponible
  558.                JMP   mem_infoado
  559. usara_xms:     CMP   AX,BX
  560.                JBE   usar_xms          ; piden algo razonable
  561.                MOV   AX,BX
  562.                OR    lista_err,ERROR4  ; rebajado el tamaño
  563. usar_xms:      MOV   tdisco,AX
  564.                MOV   status,1          ; indicar memoria extendida
  565. mem_infoado:   RET
  566. info_xms       ENDP
  567.  
  568. ; ------------ Reservar la memoria llamando al controlador XMS.
  569.  
  570. reserva_xms    PROC
  571.                MOV   AH,9
  572.                MOV   DX,tdisco
  573.                CALL  xms_driver        ; pedir memoria XMS
  574.                AND   AX,AX
  575.                JNZ   mem_rda_xms
  576.                OR    lista_err,ERROR8  ; fallo del controlador XMS
  577.                STC                     ; indicar error
  578. mem_rda_xms:   MOV   xms_handle,DX
  579.                RET
  580. reserva_xms    ENDP
  581.  
  582. ; ------------ Definir valores por defecto y adaptar los parámetros.
  583.  
  584. params_disco   PROC
  585.                MOV   AX,tdisco     ; en Kb
  586.                MOV   BX,AX         ; entradas de directorio propuestas
  587.                MOV   CL,1          ; sectores por cluster propuestos
  588.                CMP   AX,128        ; ¿disco de 128 Kb o menos?
  589.                JBE   prop_ok
  590.                MOV   BX,128
  591.                CMP   AX,512        ; ¿disco de 512 Kb o menos?
  592.                JBE   prop_ok
  593.                MOV   BX,256
  594.                CMP   AX,2042       ; ¿disco de casi 2 Mb o menos?
  595.                JBE   prop_ok
  596.                MOV   CL,2          ; evitar FAT16
  597.                CMP   AX,4084       ; ¿disco de casi 4 Mb o menos?
  598.                JBE   prop_ok
  599.                MOV   CL,4          ; evitar FAT16 hasta 8 Mb
  600.                MOV   BX,384
  601.                CMP   AX,16384      ; ¿disco de menos de 16 Mb?
  602.                JB    prop_ok
  603.                MOV   BX,512
  604. prop_ok:       MOV   tdir,BX
  605.                MOV   tcluster,CL   ; inicializar valores recomendados
  606.                MOV   DX,1024       ; AX = tamaño del disco en Kb
  607.                MUL   DX            ; DX:AX = bytes totales del disco
  608.                MOV   CX,param_tsect
  609.                AND   CX,CX
  610.                JNZ   tsect_def     ; se ha definido tamaño de sector
  611. tsect_rec:     MOV   CX,tsect      ; tamaño por defecto
  612. tsect_def:     CALL  divCX
  613.                JNC   nsect_ok      ; menos de 65536 sectores: correcto
  614.                OR    lista_err,ERROR11
  615.                JMP   tsect_rec     ; asumir por defecto y recalcular
  616. nsect_ok:      MOV   tsect,CX
  617.                MOV   numsect,AX
  618.                MOV   BX,AX
  619.                SHR   BX,1          ; BX = 1/2 del nº total de sectores
  620.                MOV   CX,param_tdir
  621.                AND   CX,CX
  622.                JNZ   tdir_def      ; se ha definido nº entradas
  623. tdir_rec:      MOV   CX,tdir       ; nº por defecto
  624. tdir_def:      MOV   AX,tsect
  625.                XOR   DX,DX
  626.                MOV   SI,32         ; 32 bytes = tamaño entrada direct.
  627.                DIV   SI            ; AX nº entradas direct. por sector
  628.                XCHG  AX,CX
  629.                XOR   DX,DX         ; DX:AX = nº de entradas
  630.                DIV   CX            ; CX = entradas en cada sector
  631.                AND   DX,DX         ; AX = nº sectores del ROOT
  632.                JZ    dir_ok?
  633.                INC   AX            ; redondear tamaño de ROOT
  634. dir_ok?:       CMP   AX,BX         ; BX = 1/2 nº sectores del disco
  635.                JB    dir_ok
  636.                OR    lista_err,ERROR12  ; directorio excesivo
  637.                JMP   tdir_rec      ; directorio por defecto
  638. dir_ok:        MOV   sdir,AX
  639.                MUL   tsect
  640.                MOV   CX,32
  641.                CALL  divCX
  642.                MOV   tdir,AX       ; optimizar tamaño de directorio
  643.                MOV   AX,512
  644.                XOR   DX,DX
  645.                DIV   tsect         ; 512 / tamaño de sector
  646.                MOV   BL,tcluster
  647.                XOR   BH,BH
  648.                MUL   BX            ; ajustar tamaño de cluster
  649.                AND   AL,AL
  650.                JZ    propclus_ok
  651.                MOV   tcluster,AL
  652. propclus_ok:   MOV   BX,param_tcluster
  653.                AND   BX,BX
  654.                JNZ   tcluster_def  ; se ha definido tamaño de cluster
  655. tcluster_rec:  MOV   BL,tcluster   ; tamaño por defecto
  656.                XOR   BH,BH
  657. tcluster_def:  SHL   BX,1
  658.                CMP   BX,numsect    ; ¿cabe seguro un cluster?
  659.                JB    tcluster_ok
  660. tcluster_mal:  OR    lista_err,ERROR13 ; tamaño de cluster incorrecto
  661.                JMP   tcluster_rec
  662. tcluster_ok:   SHR   BX,1
  663.                MOV   AX,tsect
  664.                MUL   BX            ; DX:AX = tamaño de cluster
  665.                JC    tcluster_mal
  666.                CMP   AX,31744
  667.                JA    tcluster_mal  ; cluster de más de 31 Kb
  668.                MOV   tcluster,BL   ; sectores por cluster
  669.                MOV   tamcluster,AX ; tamaño de cluster
  670.                MOV   SI,3
  671.                CALL  eval_clust    ; obtener nº más alto de cluster
  672.                CMP   AX,4086
  673.                JAE   fat16         ; el nº más alto supera 4085
  674.                MOV   CX,3
  675.                MUL   CX            ; clusters * 3
  676.                SHR   DX,1
  677.                RCR   AX,1          ; clusters * 3 / 2 = clusters * 1,5
  678.                JMP   calc_sfat
  679. fat16:         MOV   SI,4
  680.                CALL  eval_clust
  681.                SHL   AX,1
  682.                RCL   DX,1          ; clusters * 2
  683. calc_sfat:     DIV   tsect         ; AX = nº sectores de FAT aprox.
  684.                AND   DX,DX
  685.                JZ    fat_ok
  686.                INC   AX            ; redondeo
  687. fat_ok:        MOV   sfat,AX
  688.                MOV   AX,numsect    ; nº total de sectores
  689.                DEC   AX            ; descontar BOOT
  690.                SUB   AX,sdir       ; descontar ROOT
  691.                SUB   AX,sfat       ; descontar FAT
  692.                MOV   CL,tcluster
  693.                XOR   CH,CH
  694.                XOR   DX,DX
  695.                DIV   CX            ; AX = número real de clusters
  696.                INC   AX            ; se numeran desde 2
  697.                MOV   ultclus,AX
  698.                RET
  699. params_disco   ENDP
  700.  
  701. eval_clust     PROC                ; obtener el nº más alto de cluster
  702.                MOV   AX,numsect
  703.                DEC   AX            ; restar BOOT
  704.                SUB   AX,sdir       ; restar ROOT
  705.                MUL   tsect         ; DX:AX = nsect * tamsect
  706.                SHL   AX,1
  707.                RCL   DX,1          ; DX:AX = nsect * tamsect * 2
  708.                MOV   CX,tamcluster
  709.                SHL   CX,1
  710.                ADD   CX,SI         ; CX = 2 * tamcluster + SI
  711.                DIV   CX
  712.                INC   AX            ; los clusters se numeran desde 2
  713.                AND   DX,DX         ; ¿sobra un «cacho» de cluster?
  714.                JZ    clust_eval    ; redondear: ¡es preferible que
  715.                INC   AX            ; sobre un poco de FAT a que falte!
  716. clust_eval:    XOR   DX,DX         ; resultado en DX:AX
  717.                RET
  718. eval_clust     ENDP
  719.  
  720. ; ------------ Inicializar la BOOT, FAT y ROOT del disco virtual.
  721.  
  722. formatear      PROC
  723.                MOV   AX,tsect          ; preparar BPB
  724.                MOV   bytes_sector,AX
  725.                MOV   AL,tcluster
  726.                MOV   sect_cluster,AL
  727.                MOV   AX,tdir
  728.                MOV   entradas_raiz,AX
  729.                MOV   AX,numsect
  730.                MOV   num_sect,AX
  731.                MOV   AX,sfat
  732.                MOV   sectores_fat,AX
  733.                MOV   AL,0FFh           ; ha habido «cambio» de disco
  734.                MOV   cambiado,AL
  735.                MOV   ES:cambiado,AL    ; actualizar variables...
  736.                MOV   AL,status
  737.                MOV   ES:status,AL
  738.                MOV   AX,xms_handle
  739.                MOV   ES:xms_handle,AX
  740.                MOV   AX,xms_desp
  741.                MOV   ES:xms_desp,AX
  742.                MOV   AX,xms_segm
  743.                MOV   ES:xms_segm,AX
  744.                LEA   CX,fin_bpb
  745.                LEA   SI,bpb            ; actualizar BPB
  746.                SUB   CX,SI
  747.                MOV   DI,SI
  748.                CLD
  749.                REP   MOVSB
  750.                PUSH  ES                ; *
  751.                MOV   AX,DS             ; formatear el disco
  752.                MOV   ES,AX
  753.                LEA   SI,boot_sect
  754.                LEA   DI,area_trabajo
  755.                MOV   CX,128
  756.                CLD
  757.                REP   MOVSB             ; primeros 128 bytes del BOOT
  758.                XOR   AX,AX
  759.                MOV   CX,512-128
  760.                REP   STOSB             ; a 0 resto del área de trabajo
  761.                LEA   DI,area_trabajo
  762.                ADD   DI,tsect
  763.                MOV   [DI-2],0AA55h     ; marca de sector válido
  764.                CALL  escribe_sectAX    ; escribir sector BOOT (AX=0)
  765.                LEA   DI,area_trabajo
  766.                MOV   CX,tsect
  767.                REP   STOSB             ; borrar area de trabajo
  768.                MOV   AX,sfat
  769.                ADD   AX,sdir           ; AX = sectores fat + dir. raiz
  770. ini_fat:       CMP   AX,1
  771.                JE    pfat
  772.                CALL  escribe_sectAX    ; inicializar directorio raiz
  773.                DEC   AX                ; y últimos sectores de la FAT
  774.                JMP   ini_fat
  775. pfat:          LEA   DI,area_trabajo
  776.                MOV   BYTE PTR [DI],drv_media
  777.                MOV   AX,0FFFFh         ; inicializar 3 bytes FAT...
  778.                MOV   DS:[DI+1],AX
  779.                CMP   ultclus,4086      ; ¿menos de 4085 clusters?
  780.                JB    pfat_ok
  781.                MOV   DS:[DI+3],AL      ; inicializar 4º byte FAT
  782. pfat_ok:       MOV   AX,1
  783.                CALL  escribe_sectAX    ; primer sector FAT preparado
  784.                LEA   SI,dir_raiz
  785.                LEA   DI,area_trabajo
  786.                MOV   CX,32
  787.                REP   MOVSB
  788.                MOV   AX,sfat
  789.                INC   AX
  790.                CALL  escribe_sectAX    ; primer sector raiz preparado
  791.                POP   ES                ; *
  792.                RET
  793. formatear      ENDP
  794.  
  795. escribe_sectAX PROC                    ; Escribir sector nº AX del disco
  796.                PUSHF                   ; *
  797.                PUSHA                   ; **
  798.                PUSH  ES                ; ***
  799.                MOV   ES,segm_bitdisk
  800.                PUSH  CS
  801.                LEA   BX,retf2
  802.                PUSH  BX                ; apilar segundo retorno
  803.                PUSH  ES
  804.                PUSH  WORD PTR ES:[8]   ; apilar rutina de interrupción
  805.                PUSH  CS
  806.                LEA   BX,retf1
  807.                PUSH  BX                ; apilar primer retorno
  808.                PUSH  ES
  809.                PUSH  WORD PTR ES:[6]   ; apilar rutina de estrategia
  810.                LEA   BX,orden_write
  811.                LEA   DX,area_trabajo
  812.                MOV   [BX+14],DX        ; dirección de transferencia
  813.                MOV   [BX+16],DS
  814.                MOV   [BX+20],AX        ; sector inicial
  815.                PUSH  CS
  816.                POP   ES
  817.                RETF                    ; ejecutar rutina de estrategia
  818. retf1:         RETF                    ; ejecutar rutina de interrupción
  819. retf2:         POP   ES                ; ***
  820.                POPA                    ; **
  821.                POPF                    ; * restaurar bit DF
  822.                RET
  823. escribe_sectAX ENDP
  824.  
  825. ; ------------ Informar sobre el disco virtual instalado.
  826.  
  827. info_bitdisk   PROC
  828.                LEA   DX,ayuda_txt
  829.                CMP   param_h,ON        ; ¿solicitud de ayuda?
  830.                JNE   cont_info         ; no
  831.                JMP   info_exit
  832. cont_info:     MOV   AL,letra_unidad
  833.                MOV   inf_unidad,AL
  834.                LEA   DX,info_txt
  835.                CALL  imprimir
  836.                LEA   DX,inf_unidad
  837.                CALL  imprimir
  838.                CMP   ES:status,0
  839.                JNE   info_reporte
  840.                LEA   DX,info_nof_txt   ; disco no formateado
  841.                CALL  imprimir
  842.                CMP   lista_err,0
  843.                JNE   info_err          ; mensajes de advertencia
  844.                JMP   info_ret
  845. info_reporte:  LEA   DX,inf_tdisco
  846.                CALL  imprimir
  847.                MOV   AX,ES:num_sect
  848.                MUL   ES:bytes_sector
  849.                MOV   BX,1024
  850.                DIV   BX
  851.                MOV   CL,5
  852.                CALL  print_32
  853.  
  854.                LEA   DX,inf_tsector
  855.                CALL  imprimir
  856.                MOV   AX,ES:bytes_sector
  857.                XOR   DX,DX
  858.                MOV   CL,5
  859.                CALL  print_32
  860.  
  861.                LEA   DX,inf_tdir
  862.                CALL  imprimir
  863.                MOV   AX,ES:entradas_raiz
  864.                XOR   DX,DX
  865.                MOV   CL,5
  866.                CALL  print_32
  867.  
  868.                LEA   DX,inf_tcluster
  869.                CALL  imprimir
  870.                MOV   AL,ES:sect_cluster
  871.                XOR   AH,AH
  872.                XOR   DX,DX
  873.                MOV   CL,5
  874.                CALL  print_32
  875.  
  876.                LEA   DX,inf_final
  877.                CMP   lista_err,0
  878.                JE    info_exit         ; sin mensajes de advertencia
  879.                CALL  imprimir          ; ... o con ellos
  880.                LEA   DX,cabec_adv_txt
  881.                CALL  imprimir          ; cabecera de advertencias
  882. info_err:      MOV   AX,lista_err
  883.                LEA   BX,tabla_mensajes-2
  884.                MOV   CX,16             ; 16 posibles mensajes
  885. busca_err:     ADD   BX,2
  886.                SHR   AX,1
  887.                JC    informa
  888. mas_mens:      LOOP  busca_err         ; no se produce ese error
  889.                JMP   info_ret
  890. informa:       MOV   DX,[BX]           ; dirección del mensaje
  891.                CALL  imprimir
  892.                JMP   mas_mens          ; acabar con todos
  893. info_exit:     CALL  imprimir
  894. info_ret:      RET
  895. info_bitdisk   ENDP
  896.  
  897. ; ------------ Dividir DX:AX / CX sin desbordamientos.
  898.  
  899. divCX          PROC                    ; Cociente en AX y resto en DX.
  900.                XPUSH <BX,SI,CX,AX,DX>  ; Si el cociente excede los
  901.                MOV   SI,32             ; 16 bits, CF=1 y todos los
  902.                XOR   BX,BX             ; registros intactos.
  903. divmas:        SHL   AX,1
  904.                RCL   DX,1
  905.                RCL   BX,1
  906.                CMP   BX,CX
  907.                JB    dividido          ; "no cabe"
  908.                SUB   BX,CX
  909.                INC   AL                ; 1 al cociente
  910. dividido:      DEC   SI
  911.                JNZ   divmas
  912.                AND   DX,DX
  913.                JZ    div_ok
  914.                XPOP  <DX,AX>           ; error
  915.                STC
  916.                JMP   div_fin
  917. div_ok:        MOV   DX,BX             ; resto en DX y cociente en AX
  918.                ADD   SP,4              ; «sacar» sin sacar DX y AX
  919.                CLC
  920. div_fin:       XPOP  <CX,SI,BX>        ; recuperar CX, SI y BX
  921.                RET
  922. divCX          ENDP
  923.  
  924. ; --- Imprimir un nº decimal de 32 bits en DXAX formateado por CL.
  925. ;
  926. ; Entradas:
  927. ;       Si bit 4  = 1 --> se imprimirán signos separadores de millar
  928. ;       bits  0-3 = nº total de dígitos (incluyendo separadores de
  929. ;                   millar y parte fraccional)
  930. ;       bits  5-7 = nº de dígitos de la parte fraccional (cuantos
  931. ;                   dígitos de DXAX, empezando por la derecha,
  932. ;                   se consideran parte fraccional, e irán precedidos
  933. ;                   del correspondiente separador)
  934. ;
  935. ; Salidas: nº impreso, ningún registro modificado.
  936. ;
  937. ; * Ejemplo, si DXAX=9384320 y  CL=010 1 1011
  938. ;   se imprimirá ( '_' representa un espacio en blanco ):  __93.843,20
  939.  
  940. print_32       PROC
  941.                PUSH  DS
  942.                PUSH  ES
  943.                PUSH  CS
  944.                PUSH  CS
  945.                POP   DS
  946.                POP   ES
  947.                PUSH  AX                ; preservar todos los registros
  948.                PUSH  BX
  949.                PUSH  CX
  950.                PUSH  DX
  951.                PUSH  SI
  952.                PUSH  DI
  953.                PUSHF
  954.                MOV   formato_pr32,CL   ; byte del formato de impresión elegido
  955.                MOV   CX,idioma_seps
  956. separ_pr32:    MOV   millares_pr32,CH  ; separador de millares
  957.                MOV   fracc_pr32,CL     ; separador parte fraccional
  958.                MOV   BX,OFFSET tabla_pr32
  959.                MOV   CX,10
  960. digit_pr32:    PUSH  CX
  961.                PUSH  AX
  962.                PUSH  DX
  963.                XOR   DI,DI
  964.                MOV   SI,1              ; DISI = 1
  965.                DEC   CX                ; CX - 1
  966.                JCXZ  hecho_pr32
  967. factor_pr32:   SAL   SI,1
  968.                RCL   DI,1              ; DISI * 2
  969.                MOV   DX,DI
  970.                MOV   AX,SI
  971.                SAL   SI,1
  972.                RCL   DI,1
  973.                SAL   SI,1
  974.                RCL   DI,1              ; DISI * 8
  975.                ADD   SI,AX
  976.                ADC   DI,DX             ; DISI = DISI*8 + DISI*2 = DISI*10
  977.                LOOP  factor_pr32       ; DISI = DISI*10*10* ... (CX-1 veces)
  978. hecho_pr32:    POP   DX                ; luego DISI = 10 elevado a (CX-1)
  979.                POP   AX                ; CX se recuperará más tarde
  980.                MOV   CL,0FFh
  981. rep_sub_pr32:  INC   CL
  982.                SUB   AX,SI
  983.                SBB   DX,DI             ; DXAX = DXAX - DISI
  984.                JNC   rep_sub_pr32      ; restar el factor cuanto se pueda
  985.                ADD   AX,SI             ; subsanar el desbordamiento:
  986.                ADC   DX,DI             ; DXAX = DXAX + DISI
  987.                ADD   CL,'0'            ; pasar binario a ASCII
  988.                MOV   [BX],CL
  989.                POP   CX                ; CX se recupera ahora
  990.                INC   BX
  991.                LOOP  digit_pr32        ; próximo dígito del número
  992.                STD                     ; transferencias (MOVS) hacia atrás
  993.                DEC   BX                ; BX apunta al último dígito
  994.                MOV   final_pr32,BX     ; último dígito
  995.                MOV   ent_frac_pr32,BX  ; frontera parte entera/fraccional
  996.                MOV   CL,5
  997.                MOV   AL,formato_pr32
  998.                SHR   AL,CL             ; AL = nº de decimales
  999.                AND   AL,AL
  1000.                JZ    no_frac_pr32      ; ninguno
  1001.                MOV   CL,AL
  1002.                XOR   CH,CH
  1003.                MOV   SI,final_pr32
  1004.                MOV   DI,SI
  1005.                INC   DI
  1006.                REP   MOVSB             ; correr cadena arriba (hacer hueco)
  1007.                INC   final_pr32
  1008.                MOV   AL,fracc_pr32
  1009.                MOV   [DI],AL           ; poner separador de parte fraccional
  1010.                MOV   ent_frac_pr32,SI  ; indicar nueva frontera
  1011. no_frac_pr32:  MOV   AL,formato_pr32
  1012.                TEST  AL,16             ; interpretar el formato especificado
  1013.                JZ    poner_pr32        ; imprimir como tal
  1014. entera_pr32:   MOV   CX,final_pr32     ; añadir separadores de millar
  1015.                SUB   CX,ent_frac_pr32
  1016.                ADD   CX,3
  1017.                MOV   SI,final_pr32
  1018.                MOV   DI,SI
  1019.                INC   DI
  1020.                REP   MOVSB             ; correr cadena arriba (hacer hueco)
  1021.                MOV   AL,millares_pr32
  1022.                MOV   [DI],AL           ; poner separador de millares
  1023.                INC   final_pr32
  1024.                MOV   ent_frac_pr32,SI  ; usar esta variable como puntero
  1025.                SUB   SI,OFFSET tabla_pr32
  1026.                CMP   SI,3
  1027.                JAE   entera_pr32       ; próximo separador
  1028. poner_pr32:    MOV   BX,final_pr32
  1029.                MOV   BYTE PTR [BX+1],0 ; delimitador de fin de cadena
  1030.                MOV   BX,OFFSET tabla_pr32
  1031.                MOV   principio_pr32,BX ; inicio de cadena
  1032. limpiar_pr32:  MOV   AL,[BX]
  1033.                CMP   AL,'0'
  1034.                JE    blanco_pr32       ; cero a la izda --> poner " "
  1035.                CMP   AL,millares_pr32  ; separador millares a la izda
  1036.                JE    blanco_pr32
  1037.                CMP   AL,fracc_pr32
  1038.                JNE   acabar_pr32
  1039.                MOV   BYTE PTR [BX-1],'0' ; reponer 0 antes de la coma
  1040.                DEC   principio_pr32
  1041. acabar_pr32:   MOV   AL,formato_pr32   ; imprimir
  1042.                AND   AL,00001111b
  1043.                XOR   AH,AH
  1044.                MOV   DX,final_pr32
  1045.                SUB   DX,AX
  1046.                INC   DX                ; DX = offset 'principio'
  1047.                AND   AX,AX
  1048.                JNZ   format_pr32       ; longitud especificada por el usuario
  1049.                MOV   DX,principio_pr32 ; longitud obtenida del número
  1050. format_pr32:   CALL  imprimir
  1051.                POPF                    ; restaurar todos los registros
  1052.                POP   DI
  1053.                POP   SI
  1054.                POP   DX
  1055.                POP   CX
  1056.                POP   BX
  1057.                POP   AX
  1058.                POP   ES
  1059.                POP   DS
  1060.                RET                     ; salida del procedimiento
  1061. blanco_pr32:   MOV   BYTE PTR [BX],' ' ; sustituir 0 ó separador de millares
  1062.                INC   BX                ; a la izda. por espacio en blanco
  1063.                INC   principio_pr32
  1064.                CMP   BX,final_pr32
  1065.                JB    limpiar_pr32
  1066.                MOV   DX,BX             ; es el número 0.000.000.00X
  1067.                JMP   SHORT acabar_pr32 ; imprimir
  1068. formato_pr32   DB    0
  1069.                DB    5 DUP (' ')       ; espacios en blanco para cubrir la
  1070.                                        ; mayor plantilla que pueda ser espe-
  1071.                                        ; cificada en el formato
  1072. tabla_pr32     DT    0                 ; reservar 14 bytes (nº más ., más ASCIIZ)
  1073.                DW    0,0               ; aquí se solapa un buffer de 32 bytes
  1074. millares_pr32  DB    '.'               ; separador de millares
  1075. fracc_pr32     DB    ','               ;     "     parte fraccional
  1076. final_pr32     DW    0                 ; offset al último byte a imprimir
  1077. principio_pr32 DW    0                 ;  "     "  primer   "  "     "
  1078. ent_frac_pr32  DW    0                 ; offset a la frontera entero-fracc.
  1079.                DT    0                 ; $ - tabla_pr32 = 32 bytes usados por
  1080.                                        ; INT 21h al principio de print_32
  1081. print_32       ENDP
  1082.  
  1083. ; ------------ Imprimir cadena en DS:DX delimitada por un 0 ó un 255.
  1084. ;              Si acaba en 0, se imprime como tal; en caso contrario,
  1085. ;              se supone que el mensaje es multilingüe y los diversos
  1086. ;              idiomas (1, 2, ... N) separan sus cadenas por sucesivos
  1087. ;              códigos 255. El carácter de control 127 realiza una
  1088. ;              pausa hasta que se pulsa una tecla.
  1089.  
  1090. imprimir       PROC
  1091.                XPUSH <AX, BX, CX, DX, SI, DI, ES>
  1092.                CMP   idioma,0
  1093.                JNE   pr_decidir
  1094.                PUSH  DX                ; *
  1095.                MOV   AH,30h
  1096.                INT   21h
  1097.                XCHG  AH,AL
  1098.                MOV   CX,AX             ; CX = versión del DOS
  1099.                CMP   param_i,ON
  1100.                MOV   AX,codigo_tfno
  1101.                MOV   BX,1234h
  1102.                JNE   pr_busca_cod      ; parámetro /I=cod no indicado
  1103.                MOV   BX,AX
  1104.                MOV   AL,0FFh
  1105.                CMP   BX,255
  1106.                JAE   pr_cod            ; código mayor o igual de 255
  1107.                MOV   AL,BL             ; código menor de 255
  1108. pr_cod:        CMP   CX,200h
  1109.                JAE   pr_cod_tfno       ; DOS >= 2.X
  1110. pr_busca_cod:  CMP   CX,200h
  1111.                MOV   AX,1              ; inglés para DOS < 2.X
  1112.                JB    pr_habla_ax
  1113.                MOV   AL,0
  1114. pr_cod_tfno:   LEA   DX,area_trabajo
  1115.                MOV   AH,38h
  1116.                XPUSH <BX, CX>
  1117.                INT   21h               ; obtener información del pais
  1118.                XPOP  <CX, AX>
  1119.                JC    pr_habla_ax       ; fallo en la función
  1120.                CMP   CX,20Bh
  1121.                JE    pr_habla_ax       ; DOS 2.11: AX cód. telefónico
  1122.                CMP   CX,300h
  1123.                MOV   AX,1
  1124.                JB    pr_habla_ax       ; 2.x excepto 2.11: mala suerte
  1125.                MOV   AX,BX
  1126.                LEA   BX,area_trabajo
  1127.                MOV   CH,[BX+7]         ; separador de millares
  1128.                MOV   CL,[BX+9]         ; separador de decimales
  1129.                MOV   idioma_seps,CX
  1130. pr_habla_ax:   LEA   BX,info_paises-2
  1131.                MOV   CX,1              ; supuesto idioma 1
  1132. pr_busca_idi:  ADD   BX,2
  1133.                MOV   DX,[BX]
  1134.                CMP   AX,DX
  1135.                JE    pr_habla_ese
  1136.                AND   DX,DX
  1137.                JNZ   pr_busca_idi
  1138.                INC   CX                ; será otro idioma
  1139.                CMP   [BX+2],DX
  1140.                JNE   pr_busca_idi      ; no es fin de la tabla
  1141. pr_habla_ese:  MOV   idioma,CL
  1142.                POP   DX                ; *
  1143.  
  1144. pr_decidir:    MOV   CL,idioma
  1145.                MOV   CH,0              ; nº de idioma a usar (1..N)
  1146.                MOV   BX,DX
  1147. pr_busca_msg:  MOV   DX,BX
  1148.                DEC   BX
  1149. pr_busca_ter:  INC   BX
  1150.                CMP   BYTE PTR [BX],0
  1151.                JE    pr_usar_ese       ; acaba en 0: no buscar más
  1152.                CMP   BYTE PTR [BX],255
  1153.                JNE   pr_busca_ter
  1154.                INC   BX
  1155.                LOOP  pr_busca_msg      ; acaba en 255 pero no es ese
  1156. pr_usar_ese:   MOV   BX,DX
  1157.                DEC   BX
  1158. pr_cad_lon:    INC   BX
  1159.                CMP   BYTE PTR [BX],0
  1160.                JE    prlong_ok
  1161.                CMP   BYTE PTR [BX],127 ; carácter de pausa
  1162.                JE    prpausa
  1163.                CMP   BYTE PTR [BX],255
  1164.                JNE   pr_cad_lon        ; calcular longitud
  1165.                JMP   prlong_ok
  1166. prpausa:       PUSH  BX
  1167.                MOV   CX,BX
  1168.                SUB   CX,DX
  1169.                CALL  pr_cad            ; imprimir hasta el código 127
  1170. pr_limpbuf:    MOV   AH,1
  1171.                INT   16h
  1172.                JZ    pr_notec
  1173.                MOV   AH,0
  1174.                INT   16h               ; limpiar buffer del teclado
  1175.                JMP   pr_limpbuf
  1176. pr_notec:      MOV   AH,0
  1177.                INT   16h               ; esperar tecla
  1178.                POP   BX
  1179.                INC   BX
  1180.                MOV   DX,BX
  1181.                CMP   AL,27             ; ¿tecla ESC?
  1182.                STC
  1183.                JE    pr_ret
  1184.                JMP   pr_cad_lon        ; imprimir el resto
  1185. prlong_ok:     MOV   CX,BX
  1186.                SUB   CX,DX
  1187.                CALL  pr_cad            ; terminar impresión
  1188.                CLC
  1189. pr_ret:        XPOP  <ES, DI, SI, DX, CX, BX, AX>  ; CF=1 si se pulsó ESC
  1190.                RET
  1191. pr_cad:        MOV   AH,40h
  1192.                MOV   BX,1
  1193.                INT   21h               ; imprimir con el DOS
  1194.                RET
  1195. imprimir       ENDP
  1196.  
  1197.  
  1198. ; ************ Datos no residentes para la instalación
  1199.  
  1200. ON             EQU   1            ; constantes booleanas
  1201. OFF            EQU   0
  1202.  
  1203. segm_bitdisk   DW    0            ; segmento donde reside BITDISK
  1204. param_unidad   DB    0            ; número de disco si indicada unidad
  1205. param_i        DB    OFF
  1206.  
  1207. param_tdiscof  DB    OFF          ; a ON si se define tamaño de disco
  1208. param_tdisco   DW    0            ; tamaño de disco (si se define)
  1209. param_tsect    DW    0            ; tamaño de sector (si se define)
  1210. param_tdir     DW    0            ; número de entradas (si se define)
  1211. param_tcluster DW    0            ; tamaño de cluster (si se define)
  1212. param_h        DB    OFF          ; a ON si indicado parámetro /? o /H
  1213.  
  1214. tdisco         DW    ?            ; tamaño de disco (Kb)
  1215. ultclus        DW    ?            ; número más alto de cluster
  1216. tamcluster     DW    ?            ; tamaño de cluster (bytes)
  1217. sdir           DW    ?            ; sectores para directorio raiz
  1218. xms_kb         DW    0            ; Kb de memoria XMS libres
  1219. idioma         DB    0            ; selecciona el número de idioma (1..N)
  1220. idioma_seps    DW    ",."         ; separadores de millares/decimales
  1221. codigo_tfno    DW    ?            ; valor de /I= si se indica
  1222.  
  1223.                ; --- Código telefónico de países de habla
  1224.                ;     hispana (mucha o poca).
  1225.  
  1226. info_paises    DW    54                ; Argentina
  1227.                DW    591               ; Bolivia
  1228.                DW    57                ; Colombia
  1229.                DW    506               ; Costa Rica
  1230.                DW    56                ; Chile
  1231.                DW    593               ; Ecuador
  1232.                DW    503               ; El Salvador
  1233.                DW    34                ; España
  1234.                DW    63                ; Filipinas
  1235.                DW    502               ; Guatemala
  1236.                DW    504               ; Honduras
  1237.                DW    212               ; Marruecos
  1238.                DW    52                ; México
  1239.                DW    505               ; Nicaragua
  1240.                DW    507               ; Panamá
  1241.                DW    595               ; Paraguay
  1242.                DW    51                ; Perú
  1243.                DW    80                ; Puerto Rico
  1244.                DW    508               ; República Dominicana
  1245.                DW    598               ; Uruguay
  1246.                DW    58                ; Venezuela
  1247.                DW    3                 ; Latinoamérica
  1248.                DW    0                 ; fin de la información
  1249.  
  1250.                ; --- Código telefónico de países de habla alemana.
  1251.  
  1252.                DW    41                ; Switzerland
  1253.                DW    43                ; Austria
  1254.                DW    49                ; Germany
  1255.                DW    0                 ; fin de la información
  1256.  
  1257.                DW    0                 ; no más idiomas
  1258.  
  1259. boot_sect      LABEL BYTE
  1260.                JMP   SHORT botar
  1261.                DB    90h,"BDSK 1.1"  ; NOP/identificación del sistema
  1262. tsect          DW    512          ; tamaño de sector por defecto
  1263. tcluster       DB    ?            ; sectores por cluster
  1264.                DB    1,0,1        ; sectores reservados/nº de FATs
  1265. tdir           DW    ?            ; número de entradas al dir. raiz
  1266. numsect        DW    ?            ; nº sectores del disco (<=32Mb)
  1267.                DB    drv_media    ; descriptor de medio
  1268. sfat           DW    ?            ; sectores por FAT
  1269.                DW    1, 1         ; sectores por pista / cabezas
  1270.                DB    15 DUP (0)   ; últimos datos
  1271. botar:         DB    0EAh         ; código de JMP FAR...
  1272.                DW    0,0FFFFh     ; ...FFFF:0000 (programa BOOT)
  1273.                DB    "(C)1994 CiriSOFT"; resto (de primeros 64 bytes)
  1274.                DB    ". Grupo Universitario de Informá"
  1275.                DB    "tica (GUI) - Valladolid (Spain)",0 ; (128 bytes)
  1276.  
  1277. dir_raiz       DB    "BITDISK    "  ; Directorio raiz: primera entrada
  1278.                DB    8              ; atributo de etiqueta de volúmen
  1279.                DB    10 DUP (0)     ; reservado
  1280.                DW    1*2048+10*32   ; hora  1:10
  1281.                DW    1+7*32+14*512  ; fecha 1/7/94
  1282.                DW    0,0,0          ; últimos bytes (hasta 32)
  1283.  
  1284. orden_write    DB    0, 1           ; longitud cabecera / nº unidad
  1285.                DB    8              ; orden write
  1286.                DW    0              ; palabra de estado devuelta
  1287.                DD    0, 0           ; uso interno
  1288.                DB    0FAh           ; descriptor de medio
  1289.                DD    ?              ; dirección E/S
  1290.                DW    1              ; 1 sector
  1291.                DW    ?              ; primer sector
  1292.                DD    0, 0           ; no usados
  1293.  
  1294. ; ------------ Areas de datos para información del disco virtual
  1295.  
  1296. install_txt    DB    13,10,"Disco virtual BITDISK instalado en ",255
  1297.                DB    13,10,"BITDISK 1.1 RAM-Disk installiert auf ",255
  1298.                DB    13,10,"BITDISK 1.1 RAM-Disk installed on ",0
  1299. inf_drv_conf   DB    "D:",13,10,0
  1300. info_txt       DB    13,10,"Unidad BITDISK ",255
  1301.                DB    13,10,"Laufwerk BITDISK ",255
  1302.                DB    13,10,"Drive BITDISK ",0
  1303. inf_unidad     LABEL BYTE
  1304.                DB    "D:",0
  1305. info_nof_txt   DB    " sin formatear.",13,10,255
  1306.                DB    " nicht formatiert.",13,10,255
  1307.                DB    " unformatted.",13,10,0
  1308.  
  1309. inf_tdisco     DB    13,10,"  - Tamaño del disco:  ",255
  1310.                DB    13,10,"  - Laufwerksgröße:   ",255
  1311.                DB    13,10,"  - Disk size:        ",0
  1312.  
  1313. inf_tsector    DB    " Kbytes   ",13,10,"  - Tamaño de sector:  ",255
  1314.                DB    " KB       ",13,10,"  - Sektorengröße:    ",255
  1315.                DB    " Kbytes   ",13,10,"  - Sector size:      ",0
  1316.  
  1317. inf_tdir       DB    " bytes",13,10,"  - Entradas raiz:     ",255
  1318.                DB    " Bytes",13,10,"  - Verz.-Einträge:   ",255
  1319.                DB    " bytes",13,10,"  - Root entries:     ",0
  1320.  
  1321. inf_tcluster   DB    13,10,"  - Sectores/cluster:  ",255
  1322.                DB    13,10,"  - Sektoren/Cluster: ",255
  1323.                DB    13,10,"  - Sectors/cluster:  ",0
  1324.  
  1325. inf_final      DB    13,10,0
  1326.  
  1327. ERROR0         EQU   1
  1328. ERROR4         EQU   16
  1329. ERROR6         EQU   64
  1330. ERROR8         EQU   256
  1331. ERROR11        EQU   2048
  1332. ERROR12        EQU   4096
  1333. ERROR13        EQU   8192
  1334. ERROR14        EQU   16384
  1335.  
  1336. lista_err      DW    0    ; palabra que indica los mensajes a imprimir
  1337. tabla_mensajes DW    m0,m0,m0,m0,m4,m0,m6,m0,m8,m0,m0,m11,m12,m13,m14
  1338.  
  1339. cabec_adv_txt  DB    "  - Advertencias y/o errores:",13,10,255
  1340.                DB    "  - Warnungen und/oder Fehler:",13,10,255
  1341.                DB    "  - Warnings and/or errors:",13,10,0
  1342.  
  1343. m0  DB "    + Error de sintaxis o parámetro fuera de rango (no",13,10
  1344.     DB "      se define el disco o no se altera el definido)",13,10,255
  1345.     DB "    + Syntaxfehler oder Parameter außerhalb des zulässigen",13,10
  1346.     DB "      Bereichs (Die RAM-Disk ist nicht verändert).",13,10,255
  1347.     DB "    + Syntax error or parameter out of range (the",13,10
  1348.     DB "      disk is not defined and is not modified).",13,10,0
  1349.  
  1350. m4  DB "    + La memoria solicitada no existe: rebajada.",13,10,255
  1351.     DB "    + Die angeforderte Speichergröße existiert nicht und wurde reduziert.", 13,10,255
  1352.     DB "    + Memory requested does not exist: size reduced.",13,10,0
  1353.  
  1354. m6  DB "    + No existe memoria XMS.",13,10,255
  1355.     DB "    + Kein XMS-Speicher verfügbar.",13,10,255
  1356.     DB "    + There is not XMS memory available.",13,10,0
  1357.  
  1358. m8  DB "    + Fallo del controlador XMS.",13,10,255
  1359.     DB "    + Fehler des XMS-Managers.",13,10,255
  1360.     DB "    + XMS controller failure.",13,10,0
  1361.  
  1362. m11 DB "    + Tamaño sector incorrecto: asignado por defecto",13,10,255
  1363.     DB "    + Ungültige Sektorengröße: wird durch Vorgabewert ersetzt.",13,10,255
  1364.     DB "    + Incorrect sector size: stablished by default.",13,10,0
  1365.  
  1366. m12 DB "    + Nº entradas erróneo: establecido por defecto.",13,10,255
  1367.     DB "    + Ungültige Anzahl von Verzeichniseinträgen: wird durch Vorgabewert ersetzt",13,10,255
  1368.     DB "    + Incorrect number of root entries: established by default.",13,10,0
  1369.  
  1370. m13 DB "    + Tamaño cluster erróneo: asignado por defecto.",13,10,255
  1371.     DB "    + Ungültige Clustergröße: wird durch Vorgabewert ersetzt..",13,10,255
  1372.     DB "    + Cluster size incorrect: stablished by default.",13,10,0
  1373.  
  1374. m14 DB "    + FATAL: fallo al liberar la memoria ocupada.",13,10,255
  1375.     DB "    + ACHTUNG: Freigabe des belegten Speichers unmöglich.",13,10,255
  1376.     DB "    + FATAL: impossible to free the allocated memory.",13,10,0
  1377.  
  1378. bitdisk_noins LABEL BYTE
  1379. DB    13,10,"BITDISK 1.1 - EL DISCO VIRTUAL XMS DE MENOR CONSUMO DE MEMORIA.",13,10
  1380. DB    "  - Instale primero BITDISK desde CONFIG.SYS (con DEVICE).",13,10
  1381. DB    "  - Este controlador sólo consume ¡256 bytes de memoria!",13,10
  1382. DB    "  - Puede solicitar ayuda con BITDISK /?",13,10,255
  1383. DB    13,10,"BITDISK 1.1 - Der verstellbare RAM-Disk-Treiber für XMS."
  1384. DB    13,10,"  - Installieren Sie erst BITDISK in der CONFIG.SYS (mit DEVICE)."
  1385. DB    13,10,"  - Dieser Treiber benötigt nur 256 Bytes konventionellen "
  1386. DB    "oder oberen Speicher!",13,10
  1387. DB    "  - Hilfe ist verfügbar mit BITDISK /?",13,10,255
  1388. DB    13,10,"BITDISK 1.1 - THE WORLD'S SMALLEST XMS RESIZEABLE RAMDISK."
  1389. DB    13,10,"  - Install first BITDISK from CONFIG.SYS (with DEVICE)."
  1390. DB    13,10,"  - This controller takes only 256 bytes of conventional "
  1391. DB    "or upper memory!",13,10
  1392. DB    "  - Help is available with BITDISK /?",13,10,0
  1393.  
  1394. ; switchar patching goes from bitdisk_noins until this area!!!
  1395.  
  1396. bitdisk_noes   DB    13,10,"BITDISK 1.1",13,10
  1397. DB    "   - La unidad indicada no es un dispositivo BITDISK 1.1",13,10,255
  1398. DB    "   - Angegebener Buchstabe kennzeichnet kein Laufwerk von BITDISK 1.1.",13,10,255
  1399. DB    "   - Drive letter indicated isn't a BITDISK 1.1 device.",13,10,0
  1400.  
  1401. ayuda_txt LABEL BYTE
  1402. DB 13,10,10," BITDISK 1.1  -  (C) Grupo Universitario de Informática "
  1403. DB "- Valladolid (España).",13,10,"(C) 1995 Ciriaco García de Celis "
  1404. DB "- Email: ciri@gui.uva.es - FidoNET 2:341/21.8",13,10
  1405. DB " Disco virtual en XMS para sistemas AT consumiendo sólo 256 bytes de memoria."
  1406. DB 13,10,"   * * * Este programa (sin cambios) es de DOMINIO PUBLICO "
  1407. DB "y GRATUITO * * *",13,10,10
  1408. DB "  Después de instalar BITDISK en el fichero CONFIG.SYS  (con una "
  1409. DB "línea similar",13,10,"a DEVICEHIGH=BITDISK.EXE) se le puede "
  1410. DB "ejecutar desde el DOS para formatearlo:",13,10,10,"   BITDISK 64 "
  1411. DB 9,9," (formatea un disco virtual de 64 Kb en memoria XMS)",13,10
  1412. DB "   BITDISK 256",9,9," (lo reformatea ampliándolo a 256 Kb)",13,10
  1413. DB "   BITDISK 0  ",9,9," (lo anula totalmente, recuperando toda la "
  1414. DB "memoria)",13,10,"   BITDISK E: 100",9," (formatea el BITDISK E: con "
  1415. DB "100 Kb)",13,10,"   BITDISK    ",9,9," (muestra información del disco "
  1416. DB "sin alterarlo)",13,10,10,"  Sintaxis:",13,10
  1417. DB "      BITDISK [U:] [tamaño [tamaño_sector [fich_raiz [tamaño_"
  1418. DB "cluster]]]]",13,10,10,"  El tamaño ha de estar comprendido entre "
  1419. DB "4 y 32768 Kb; el tamaño de sector ha",13,10,"de ser 64, 128, 256 ó"
  1420. DB " 512 (DRDOS sólo lo soporta 128 ó superior); los ficheros",13,10
  1421. DB "admitidos en el directorio raíz pueden oscilar desde 1 "
  1422. DB "hasta donde sea posible",13,10,"para el tamaño del disco;  el "
  1423. DB "tamaño de clúster indica el  nº  de sectores por",13,10
  1424. DB "cluster (en MS-DOS debe ser potencia de 2; no hay problemas "
  1425. DB "con DR-DOS).  Para",13,10,"indicar un parámetro hay que indicar los anteriores "
  1426. DB "(0-evaluación automática).",13,10,255
  1427.  
  1428. DB 13,10,10," BITDISK 1.1  -  (C) Grupo Universitario de Informática "
  1429. DB "- Valladolid (Spain).",13,10,"(C) 1995 Ciriaco García de Celis "
  1430. DB "- Email: ciri@gui.uva.es - FidoNET 2:341/21.8",13,10,"XMS-RAM-"
  1431. DB "Disk für AT-Systeme, benötigt 256 Bytes konventionellen/oberen Speicher"
  1432. DB 13,10,"* * * Dieses Programm ist PUBLIC DOMAIN und FREEWARE (ohne "
  1433. DB "Veränderungen) * * *",13,10,10,"  Nach der Installation in "
  1434. DB "CONFIG.SYS  (mit einer Zeile wie DEVICE=BITDISK.EXE)",13,10
  1435. DB "können Sie es zur Neuformatierung von der Kommandozeile aufrufen."
  1436. DB " Beispiele:",13,10,10,"   BITDISK 64 ",9,9,"(legt eine RAM-Disk von "
  1437. DB "64 KB im XMS an)",13,10,"   BITDISK 256",9,9,"(erhöht die Größe "
  1438. DB "auf 256 KB: Inhalte werden gelöscht!)",13,10,"   BITDISK 0  ",9
  1439. DB 9,"(gibt den belegten Speicher wieder frei)",13,10,"   BITDISK E: "
  1440. DB "100",9,"(legt BITDISK E: mit 100 KB an)",13,10,"   BITDISK    ",9,9
  1441. DB "(Anzeige der Informationen ohne Änderung)",13,10,10,"  Vollständige"
  1442. DB " Syntax:",13,10,10,"   BITDISK [U:] [Größe [Sektorengröße [Verzeichnis"
  1443. DB "einträge [Clustergröße]]]]",13,10,10,"  Die Größe muß in 4-32768 KB "
  1444. DB "liegen;  Sektorengröße  muß 64, 128, 256 oder 512",13,10,"Bytes sein "
  1445. DB " (DRDOS unterstützt nicht 64).  Verzeichniseinträge können von 1 bis"
  1446. DB 13,10,"Disk-Obergrenze sein;  die Clustergröße (Anzahl Sektoren pro "
  1447. DB "Cluster),  muß bei",13,10,"MS-DOS eine Zweierpotenz sein (keine "
  1448. DB "Probleme bei DRDOS). Falls ein Parameter 0",13,10,"ist, verwendet "
  1449. DB "BITDISK Vorgabewerte (außer bei der Disk-Größe).",13,10,255
  1450.  
  1451. DB 13,10,10," BITDISK 1.1  -  (C) Grupo Universitario de Informática "
  1452. DB "- Valladolid (Spain).",13,10,"(C) 1995  Ciriaco García de Celis "
  1453. DB "- Email: ciri@gui.uva.es - FidoNET 2:341/21.8",13,10,"  XMS RAM "
  1454. DB "Disk for AT systems taking 256 bytes of conventional/upper memory."
  1455. DB 13,10,"* * * This program (without modifications) is PUBLIC DOMAIN "
  1456. DB "and FREEWARE * * *",13,10,10,"  After install BITDISK in "
  1457. DB "CONFIG.SYS  (with a line like to DEVICE=BITDISK.EXE)",13,10
  1458. DB "you can execute it from DOS command line in order to format disk."
  1459. DB " Examples:",13,10,10,"   BITDISK 64 ",9,9,"(Formats a 64 Kb RAM "
  1460. DB "disk in XMS memory)",13,10,"   BITDISK 256",9,9,"(Reformats it "
  1461. DB "up to 256 Kb: all data will be lost!)",13,10,"   BITDISK 0  ",9,9
  1462. DB "(Unformat it freezing all memory ocupied)",13,10,"   BITDISK E: "
  1463. DB "100",9,"(Formats BITDISK E: with 100 Kb)",13,10,"   BITDISK    ",9
  1464. DB 9,"(Show disk information without modify it)",13,10,10,"  Complete"
  1465. DB " syntax:",13,10,10,"        BITDISK [U:] [size [sector_size "
  1466. DB "[files_root [cluster_size]]]]",13,10,10,"  Size must be in the "
  1467. DB "range 4-32768 Kb; sector size must be 64, 128, 256 or 512",13,10
  1468. DB "bytes (DRDOS does not support 64 bytes-sector).  Files on root "
  1469. DB "directory can be",13,10,"from 1 up to disk size limit;  the "
  1470. DB "cluster size  (number of sectors by cluster)",13,10,"must be "
  1471. DB "power of 2 in MS-DOS (there is no problem with DRDOS). If any "
  1472. DB "parameter",13,10,"except disk size is set to 0, BITDISK will "
  1473. DB "assume default values.",13,10,0
  1474.  
  1475. area_trabajo   EQU   $
  1476.                DB    4096 DUP (?)
  1477.  
  1478. _BITDISK       ENDS
  1479.  
  1480. _PILA          SEGMENT STACK 'STACK'
  1481.                DB    768 DUP (?)     ; 0,75 Kb de pila son suficientes
  1482. _PILA          ENDS
  1483.  
  1484.                END   main
  1485.