home *** CD-ROM | disk | FTP | other *** search
-
- ;┌───────────────────────────────────────────────────────────────────┐
- ;│ │
- ;│ █████ █ █ █████ █ █ █████ │
- ;│ █ ██ ██ █ █ █ █ │
- ;│ █████ █ █ █ █████ █ █████ │
- ;│ █ █ █ █ █ █ │
- ;│ █████ █ █ █ █████ █ █████ │
- ;│ │
- ;│ │
- ;│ 2M 3.0 - (C) 1993-1995 Ciriaco García de Celis. │
- ;│ │
- ;│ SOPORTE PARA DISQUETES CON MAYOR CAPACIDAD DE LA NORMAL │
- ;│ CREADOS POR LA UTILIDAD 2MF │
- ;│ │
- ;│ * * * Versión instalable desde el CONFIG.SYS * * * │
- ;│ │
- ;│ - Sólo para AT y superiores con controladora y unidades de alta. │
- ;│ - Programación directa del controlador de disquetes y del DMA. │
- ;│ - Soporte para sectores de más de 512 bytes (economizar GAPs). │
- ;│ - Mezcla de sectores de distinto tamaño en la misma pista. │
- ;│ - Ruptura del límite habitual de 80 pistas (incluido 360K). │
- ;│ - Emulación de sectores de 512 bytes en INT 13h. │
- ;│ - Función 5 (INT 13h) reforzada para formatear los nuevos discos. │
- ;│ - El soporte residente opera eficazmente bajo DOS y WINDOWS 3.X │
- ;│ │
- ;│ Emplear TASM /m5, TLINK y EXE2BIN para obtener un fichero SYS │
- ;│ │
- ;└───────────────────────────────────────────────────────────────────┘
-
- .286 ; versión para AT o superior
-
- ON EQU 1 ; constantes booleanas
- OFF EQU 0
-
- ; ------------ Macros de propósito general.
-
- XPUSH MACRO regmem ; apilar lista de registros
- IRP rm, <regmem>
- PUSH rm
- ENDM
- ENDM
-
- XPOP MACRO regmem ; desapilar lista de registros
- IRP rm, <regmem>
- POP rm
- ENDM
- ENDM
-
- XPUSHA MACRO
- PUSHA
- ENDM
-
- XPOPA MACRO
- POPA
- ENDM
-
- XSHL MACRO regmem, cuenta
- SHL regmem,cuenta
- ENDM
-
- DELAY MACRO ; estados de espera
- JMP SHORT $+2 ; para AT obsoleto
- JMP SHORT $+2
- ENDM
-
- DDS MACRO
- PUSH 40h
- POP DS
- ENDM
-
- DES MACRO
- PUSH 40h
- POP ES
- ENDM
-
- PMICRO MACRO ; retardo de aprox. 15,09 µs
- LOCAL pmicro_iter ; (exactamente 18/1193180 sg.)
- pmicro_iter: DELAY
- IN AL,61h ; Esta macro puede ejecutarse
- AND AL,10h ; repetitivamente (se apoya en
- CMP AL,AH ; AX) para hacer retardos a
- JE pmicro_iter ; través de la temporización
- MOV AH,AL ; del refresco de la memoria
- ENDM ; dinámica de los AT.
-
- ; ------------ Programa.
-
- _PRINCIPAL SEGMENT
- ASSUME CS:_PRINCIPAL, DS:_PRINCIPAL
-
- ORG 0
-
- ini_residente EQU $
-
- DD -1 ; encadenamiento con otros drivers
- tipo_drive DW 8000h ; palabra de atributo:
- ; bit 15 a 1: dispositivo caracteres
- ; bit 14 a 0: sin control IOCTL
- DW estrategia ; rutina de estrategia
- DW interrupcion ; rutina de interrupción
- DB "2M$ " ; nombre del dispositivo
-
- estrategia PROC FAR
- MOV CS:pcab_pet_segm,ES
- MOV CS:pcab_pet_desp,BX
- RET
- estrategia ENDP
-
- interrupcion PROC FAR
- CALL main ; tras instalar: XPUSH <DS, BX> y MOV BX,??
- pcab_pet_segm DW ?
- MOV DS,BX
- DB 0BBh ; opcode de MOV BX,??
- pcab_pet_desp DW ?
- MOV WORD PTR [BX+3],8103h ; código de error
- XPOP <BX, DS>
- RET
- interrupcion ENDP
-
- ; ****************************************
- ; * *
- ; * D A T O S R E S I D E N T E S *
- ; * *
- ; ****************************************
-
- ; ------------ Identificación estandarizada del programa.
-
- program_id LABEL BYTE
- segmento_real DW 0 ; segmento real donde será cargado
- offset_real DW 0 ; offset real " " "
- longitud_total DW 0 ; zona de memoria ocupada (párrafos)
- info_extra DB 02h ; bits 0, 1 y 2-> 000: normal, con PSP
- ; 001: bloque UMB XMS
- ; 010: *.SYS
- ; 011: *.SYS formato EXE
- ; bit 7 a 1: «extension_id» definida
- multiplex_id DB 0 ; número Multiplex de este TSR
- vectores_id DW tabla_vectores
- extension_id DW 0
- DB "*##*"
- autor_nom_ver DB "CiriSOFT:2M:3.0",0
-
- DB 2 ; número de vectores de interrupción usados
- tabla_vectores EQU $
- vieja_i13 DB 13h ; INT 13h
- ant_int13 LABEL DWORD ; dirección original
- ant_int13_off DW 0
- ant_int13_seg DW 0
- DB 2Fh ; INT 2Fh
- ant_int2F LABEL DWORD ; dirección original
- ant_int2F_off DW 0
- ant_int2F_seg DW 0
-
- ; ***********************************************
- ; * *
- ; * C O D I G O Y D A T O S D E 2 M *
- ; * *
- ; ***********************************************
-
- INCLUDE 2MKERNEL.INC
-
- fin_residente EQU $ ; fin del área residente sin contar el buffer
-
- bytes_resid EQU fin_residente-ini_residente
-
-
- ; *****************************
- ; * *
- ; * I N S T A L A C I O N *
- ; * *
- ; *****************************
-
- main PROC
- ADD SP,2 ; quitar dirección de retorno
- XPUSH <AX, BX, CX, DX, SI, DI, BP, DS, ES>
- PUSH CS
- POP DS
- MOV WORD PTR interrupcion,531Eh ; opcode PUSH DS,BX
- MOV BYTE PTR interrupcion+2,0BBh ; opcode MOV BX,??
- PUSH CS
- POP ES
- CALL inic_general ; inicializar ciertas variables
- CALL pc_ok?
- TEST error,0FFFFh
- JNZ exit_ins
- CALL mx_get_handle ; obtener entrada Multiplex
- JNC handle_ok
- OR error,MX64FULL ; no quedan entradas
- JMP exit_ins
- handle_ok: MOV multiplex_id,AH ; entrada multiplex para 2M
- CALL preservar_ints ; tomar nota de vectores
- MOV AX,CS
- LEA BX,buffer_io
- CALL testDMA
- JNC dma_ml_ok ; no hay problemas con el DMA
- OR accion,BUFFERPLUS ; sí: aviso al usuario
- MOV CX,dma_fix
- ADD buffer,CX ; nuevo buffer
- MOV AX,longitud_total
- ADD AX,dma_fixp
- MOV longitud_total,AX ; nuevo consumo de memoria
- dma_ml_ok: MOV DI,100h
- CALL activar_ints ; interceptar vectores
- MOV AX,sbootseg
- AND AX,AX
- JZ exit_ins ; no hay copia SuperBOOT
- PUSH ES
- MOV ES,AX
- MOV BX,ES:[0]
- MOV ES:[BX].control2m_flag,OFF ; anularla control A:
- MOV BX,ES:[2]
- MOV ES:[BX].control2m_flag,OFF ; anularla control B:
- POP ES
- exit_ins: CALL info
- MOV BX,pcab_pet_segm
- MOV ES,BX
- MOV BX,pcab_pet_desp
- MOV WORD PTR ES:[BX+3],100h ; indicar retorno correcto
- MOV AX,longitud_total
- MOV CL,4
- SHL AX,CL
- TEST error,0FFFFh
- JZ exit_ok
- MOV WORD PTR ES:[BX+14],0 ; OFFSET 0: no quedará
- MOV WORD PTR ES:[BX+16],CS ; instalado en memoria
- JMP exit_interr
- exit_ok: MOV WORD PTR ES:[BX+14],AX ; OFFSET al último byte residente
- MOV WORD PTR ES:[BX+16],CS
- exit_interr: XPOP <ES, DS, BP, DI, SI, DX, CX, BX, AX>
- RETF
- main ENDP
-
-
- ;*********************************************************
- ;* *
- ;* SUBRUTINAS DE PROPOSITO GENERAL PARA LA INSTALACION *
- ;* *
- ;*********************************************************
-
- INCLUDE 2MUTIL.INC
-
- ; ------------ Inicializar ciertas variables.
-
- inic_general PROC
- MOV AX,(bytes_resid+tbuffer+15)/16
- MOV longitud_total,AX ; memoria necesaria
- MOV segmento_real,CS ; anotar segmento del bloque
- MOV offset_real,0 ; ídem con el offset
- MOV DL,0
- CALL tipo_disco
- JNC hay_unidad
- MOV DL,1
- CALL tipo_disco
- JNC hay_unidad
- OR error,MALBIOS ; no hay disqueteras
- RET
- hay_unidad: MOV DL,0
- CALL tipo_disco
- MOV info_A.tipo_drv,BL ; guardar tipo unidad A:
- MOV DL,1
- CALL tipo_disco
- MOV info_B.tipo_drv,BL ; guardar tipo unidad B:
- RET
- inic_general ENDP
-
- ; ------------ Informar al usuario.
-
- info PROC
- LEA DX,instalado_txt
- TEST error,0FFFFh
- JZ info_ins_ok
- LEA DX,noinstall_txt
- CALL print
- JMP info_err
- info_ins_ok: CALL print
- CALL info_drvs
- info_err: LEA DX,err_malpc
- TEST error,MALPC
- JNZ fin_info
- LEA DX,err_maldos
- TEST error,MALDOS
- JNZ fin_info
- LEA DX,err_malbios
- TEST error,MALBIOS
- JNZ fin_info
- LEA DX,err_maldrv
- TEST error,MALDRV
- JNZ fin_info
- LEA DX,err_mx64full
- TEST error,MX64FULL
- JZ info_war
- fin_info: CALL print
- info_war: TEST accion,BUFFERPLUS
- JZ no_warn
- LEA DX,dma_cross_txt
- CALL print
- no_warn: RET
- info ENDP
-
- ; --- Informar de las unidades controladas por 2M.
-
- info_drvs PROC
- MOV DL,0
- CALL tipo_disco
- CALL pr_tipo
- MOV DL,1
- CALL tipo_disco
- CALL pr_tipo
- LEA DX,crlf_txt
- CALL print
- RET
- info_drvs ENDP
-
- ; --- Imprimir unidad y su tipo.
-
- pr_tipo PROC
- CMP BL,2
- JE tp_ok
- CMP BL,4
- JE tp_ok
- CMP BL,5
- MOV BL,5
- JAE tp_ok
- RET
- tp_ok: PUSH BX
- ADD DL,'A'
- MOV AH,2
- INT 21h
- POP BX
- SUB BL,2
- MOV BH,0
- SHL BX,1
- ADD BX,OFFSET tabla_ndrvs
- MOV DX,[BX]
- CALL print
- RET
- pr_tipo ENDP
-
- ; ------------ Comprobar que la configuración es la adecuada. Para
- ; saber si la INT 13h de este ordenador acaba llamando a
- ; la INT 40h, se desvía la INT 40h y se provoca un inocuo
- ; reset de disquetes vía INT 13h para comprobar si pasa
- ; por la INT 40h. Si está cargado el código SuperBOOT, se
- ; utiliza no obstante siempre la INT 13h (para anularlo
- ; por completo).
-
- pc_ok? PROC
- CALL SuperBOOT?
- JNE no_superboot
- MOV sbootseg,AX ; segmento SuperBOOT
- JMP test_dos ; es SuperBOOT: usar INT 13h
- no_superboot: CALL test_i40
- TEST accion,I40
- JZ test_dos ; no soportada la INT 40h
- MOV nueva_i13,40h
- MOV vieja_i13,40h ; usar INT 40 en vez de INT 13
- test_dos: MOV AH,30h
- INT 21h
- XCHG AH,AL
- CMP AX,31Eh ; ¿DOS 3.30 o superior?
- MOV AX,MALDOS
- JB pc_nok
- CALL testAT
- MOV AX,MALPC
- JC pc_nok
- TEST error,MALBIOS
- JNZ pc_ok ; con ese error vale
- MOV AX,MALDRV
- CMP info_A.tipo_drv,2 ; ¿unidad A: de 1.2?
- JE pc_ok
- CMP info_A.tipo_drv,4 ; ¿unidad A: de 1.44 ó 2.88?
- JAE pc_ok
- CMP info_B.tipo_drv,2 ; ¿unidad B: de 1.2?
- JE pc_ok
- CMP info_B.tipo_drv,4 ; ¿unidad B: de 1.44 ó 2.88?
- JAE pc_ok
- pc_nok: OR error,AX
- pc_ok: RET
- pc_ok? ENDP
-
- ; --- Devolver ZF=1 si 2M está instalado en SuperBOOT.
- ; La rutina funciona aunque QEMM modifique de modo
- ; temporal el límite de memoria a casi un mega en
- ; la llamada a INT 12h.
-
- SuperBOOT? PROC
- PUSH ES
- INT 12h ; tamaño memoria convencional
- MOV BX,640
- CMP AX,256
- JB base_sc_ok ; dato extraño
- CMP AX,640
- JA base_sc_ok ; dato extraño
- MOV BX,AX
- base_sc_ok: MOV AX,BX
- ADD AX,127 ; redondeo
- MOV CL,7
- SHR AX,CL
- SHL AX,CL ; hacia frontera de 128K
- MOV CX,AX
- SUB CX,BX ; buscar en área posible
- DEC AX
- MOV BX,64
- MUL BX ; AX = segmento de SuperBOOT
- CLD
- scan_boot: MOV ES,AX
- MOV DI,6
- LEA SI,id_boot
- PUSH CX ; *
- MOV CX,id_boot_tam
- REP CMPSB
- POP CX ; *
- JE haysb_ret ; ZF = 1 -> 2M SuperBOOT
- SUB AX,64
- LOOPNZ scan_boot ; buscar 1K más abajo
- nohaysb_ret: CMP SP,0 ; ZF = 0 -> no es SuperBOOT
- haysb_ret: POP ES
- RET
- SuperBOOT? ENDP
-
- ; --- Comprobar si la INT 40h está en uso
-
- test_i40: XPUSH <DS, ES> ; *
- MOV AX,3540h
- INT 21h
- XPUSH <ES, BX> ; vector de INT 40h original
- LEA DX,i40_aux
- MOV AX,2540h
- INT 21h ; establecer nueva INT 40h
- XOR AX,AX
- MOV DL,0
- INT 13h ; reset de disco
- XPOP <DX, DS>
- MOV AX,2540h
- INT 21h ; restaurar INT 40h original
- XPOP <ES, DS> ; *
- RET
-
- i40_aux PROC
- OR CS:accion,I40 ; sí utilizada INT 40h
- IRET ; desde la INT 13h
- i40_aux ENDP
-
- ; --- Detectar 286 ó superior.
-
- testAT PROC
- PUSH AX
- PUSHF
- POP AX
- OR AH,70h ; intentar activar bit 12, 13 ó 14
- PUSH AX ; del registro de estado
- POPF
- PUSHF
- POP AX
- AND AH,0F0h
- CMP AH,0F0h
- JE testedAT
- STC
- testedAT: CMC ; CF = 0 en AT y 1 en PC/XT
- POP AX
- RET
- testAT ENDP
-
- ; ------------ Comprobar que el buffer para el DMA en la copia
- ; residente no cruza una frontera. En ese caso se emplea
- ; otro buffer ubicado tras el habitual, lo que aumenta el
- ; consumo de memoria de este área. A la entrada AX apunta
- ; al segmento que contendrá el buffer y BX el offset. Si
- ; se produce el cruce, dma_fix devuelve la cuantía en que
- ; hay que incrementar (en bytes) la dirección base para
- ; evitarlo y dma_fixp también (pero en párrafos).
-
- testDMA PROC
- XPUSH <AX, CX, DX>
- MOV CX,16
- MUL CX
- ADD AX,BX
- ADC DX,0 ; DX:AX = dirección 20 bits
- MOV CX,DX
- PUSH AX
- ADD AX,tbuffer-1 ; buffer para el mayor sector
- ADC DX,0
- POP AX
- CMP DX,CX
- JE dmatested
- NEG AX
- MOV dma_fix,AX
- ADD AX,15
- MOV CL,4
- SHR AX,CL
- MOV dma_fixp,AX
- STC ; CF=1 -> cruza frontera
- dmatested: XPOP <DX, CX, AX>
- RET
- testDMA ENDP
-
- ; ***********************************************
- ; * *
- ; * D A T O S N O R E S I D E N T E S *
- ; * *
- ; ***********************************************
-
- ; ------------ Gestión de memoria y control de instalación.
-
- dma_fix DW ? ; bytes para alargar buffer (por DMA)
- dma_fixp DW ? ; párrafos
-
- offsets_ints DW 2 ; número de vectores interceptados
- nueva_i13 DB 13h ; tabla de offsets de los vectores
- DW ges_int13 ; de interrupción interceptados
- DB 2Fh
- DW ges_int2F
-
- MALPC EQU 1 ; Códigos de error
- MALDOS EQU 2
- MALBIOS EQU 4
- MALDRV EQU 8
- MX64FULL EQU 128
- ERRSINTAX EQU 256 ; no usado (utilizado en 2MUTIL.INC)
-
- BUFFERPLUS EQU 8 ; códigos de acción e información
- I40 EQU 16
-
- error DW 0 ; variable para acumular errores
- accion DB 0 ; variable que indica lo sucedido
- param_ayuda DB ? ; no utilizado (usado en 2MUTIL.INC)
-
- sbootseg DW 0 ; segmento SuperBOOT (si presente)
-
- id_boot DB "2M-STV" ; marca de presencia SuperBOOT
- id_boot_tam EQU $-OFFSET id_boot
-
- ; ------------ Texto.
-
- instalado_txt DB 13,10,"2M 3.0 instalado en ",255
- DB 13,10,"2M 3.0 installed on ",0
-
- tabla_ndrvs DW t12
- DW 0
- DW t144
- DW t288
- t12 DB ":1.2M ",0
- t144 DB ":1.44M ",0
- t288 DB ":2.88M ",0
-
- noinstall_txt DB 13,10,"2M 3.0 no instalado.",13,10,255
- DB 13,10,"2M 3.0 not installed.",13,10,0
-
- err_malpc DB " - Error: Necesario ordenador AT. Utilice 2MX en esta máquina.",13,10,7,255
- DB " - Error: Needs AT system. Use 2MX on this computer.",13,10,7,0
-
- err_mx64full DB " - Error: Ya hay 64 programas residentes con la misma técnica.",13,10,255
- DB " - Error: There are already 64 TSR's with the same technique."
- crlf_txt DB 13,10,0
-
- err_maldos DB " - Error: necesaria versión DOS 3.30 ó posterior.",13,10,7,255
- DB " - Error: needs at least DOS 3.30 or above.",13,10,7,0
-
- err_malbios DB " - Error: No puedo detectar el tipo de las unidades. Instale 2M-ABIOS antes.",13,10,255
- DB " - Error: Impossible to detect drive types. Please install 2M-ABIOS before.",13,10,0
-
- err_maldrv DB " - Error: Necesaria(s) unidad(es) de alta densidad.",13,10,255
- DB " - Error: Needs high-density floppy drive(s).",13,10,0
-
- dma_cross_txt DB " - Nota: El buffer de E/S cruzaba una frontera de DMA y fue ampliado.",13,10
- DB " Cambie la ubicación en memoria de 2M para ahorrar unos bytes.",13,10,255
- DB " - Note: I/O buffer has been extended because 2M crosses a DMA boundary.",13,10
- DB " Modify the memory location of 2M to save a little memory.",13,10,0
-
- buffer_aux DB 64 DUP (0) ; buffer para alguna función del DOS
-
- _PRINCIPAL ENDS
- END
-