home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1995 November
/
PCWK1195.iso
/
inne
/
podstawy
/
dos
/
format
/
2m30src.exe
/
2MSYS.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-03-06
|
22KB
|
575 lines
;┌───────────────────────────────────────────────────────────────────┐
;│ │
;│ █████ █ █ █████ █ █ █████ │
;│ █ ██ ██ █ █ █ █ │
;│ █████ █ █ █ █████ █ █████ │
;│ █ █ █ █ █ █ │
;│ █████ █ █ █ █████ █ █████ │
;│ │
;│ │
;│ 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