;Programm KeepVideoMode gegen das SetVideoMode03-Syndrom
;Aufruf: keepvm <programmname> <parameter>
;P.S.: Hiermit kann man auch Nicht-EXE-Programme mit MZ-Header
;ohne Umbenennung zum Abarbeiten bringen!
include prolog.asm
mov [parseg],ds
;Kommandozeile abscannen
cld
mov si,81h
mov di,80h
mov cl,[di]
sk1: lodsb
dec cl
cmp al,0dh ;Ende?
jz help
cmp al,21h
jc sk1 ;Trennzeichen
cmp al,'/'
jz sk11 ;für gebräuchliches /?
cmp al,'?'
jnz sk41
help: PRINT msgH
xor ax,ax
jmp hlp
sk11: cmp [by si],'x'
jz sk13
cmp [by si],'X'
jnz sk1
sk13: mov [keepscr],ax ;Image retten!
inc si
dec cl
jr sk1
sk41: dec si
inc cl
sk4: movsb ;um 1 Zeichen vorkopieren
dec cl ;immer restliche Zeichen mitzählen
cmp [byte si],21h
jnc sk4
;80h steht Dateiname
;SI= ^Parameter
;DI= ^Ende Dateiname+1
dec si
mov [si],cl ;Abschlußzeichen
;SI= ^Parameter MIT Anzahl Bytes
mov [byte di],0 ;Endekennung
mov [parofs],si
mov sp,100h ;erst DEC, dann Schreiben! (wie Z80)
test [keepscr],-1
jz NoSave
call OpenTmp
jc errm
call SaveImg
xchg bx,ax
jc Errm
NoSave:
ResizeM ;Speicherblockgröße verändern
mov ah,0fh
int 10h
call GetLines ;ah=Zeilenzahl
mov [VM],ax
mov dx,80h
mov bx,offset params
DOS 4b00h ;starten
mov bx,cs
mov ss,bx
mov sp,100h
mov ds,bx
mov es,bx
mov bl,al ;Exit- oder Errorcode
jnc bye
errm:
PRINT msgE
mov al,bl
call ahex
jmp Exi ;Kein CLS!
bye: ;bl=ExitCode
push bx
mov ah,0fh
int 10h ;VM ermitteln
mov bl,al
mov ax,[VM]
cmp al,bl
jz vmok
push ax
xor ah,ah
int 10h
pop ax
vmok: cmp al,4 ;Der multiple Modus?
jc vmx1
cmp al,7
jnz EndMode00
vmx1: xchg al,ah
cmp al,27
jz Mo28
cmp al,32
jz mo28
cmp al,49
jne EndMode00
mo28: push ax
int 10h ;Cursorpos
pop ax
sub dh,al ;CY=0 und Z=0: Cursor steht unter dem Fenster!
jbe noscroll
push ax
mov ah,8
int 10h
mov bh,ah ;Attribut
mov al,dh ;Rollweite
mov cx,0
call GetLines
mov dh,ah
mov dl,79
mov ah,6
int 10h ;rollen
mov ah,0fh
int 10h ;Seite ermitteln
mov ah,3
int 10h ;GetCursor
pop ax
push ax
mov dh,al
mov ah,2
int 10h
pop ax
noscroll:
cmp al,27
jz Mode28
cmp al,32
jz Mode33
VGAMode:
MOV AX,1112h
xor bx,BX
INT 10h
MOV AX,1200h
MOV BL,20h
INT 10h
mov ax,0714h
jr em01
EndMode00:
jr EndMode
Mode28:
mov ax,1111h
xor bl,bl
int 10h
mov ax,1202h
mov bl,30h
int 10h
mov cx,0b14h
mov ah,1
int 10h
mov dx,3d4h
mov ax,0d0eh
jr EM01
Mode33:
mov BH,2
mov AX,1130h
int 10h ;Adresse Font14x8 erhalten nach es:bp
inc BP ;immer oben 1 Scanzeile weg
mov CX,100h
mov DX,0
mov BX,0E00h
mov AX,1110h
int 10h
mov ax,0b09h ;unten auch noch 1 Zeile weg gibt 12 Zeilen
call pcrtc
xor ax,AX
mov ES,AX
mov [by es:484h],32
mov ax,LOW(33*12-1)*256+12h
call pcrtc
mov ax,0b14h
em01:
call pcrtc ;Underline-Bugfix nach RalfBrownIntList
EndMode:
test [keepscr],-1
jz noLoad
call GetImg
noload:
pop bx
Exi: mov al,bl
hlp: mov ah,4ch ;Programmende
int 21h
pcrtc: ;CRT-Controller-Register programmieren
;AL=Funktions-Adresse, AH=Ausgabe-Byte
push dx
push ax
mov ah,12h
mov bl,10h
int 10h ;{Get Monochrom-Bit to bit0(bh)}
mov dx,3d4h ;{Color CRTC Base Address}
test bh,1
jz @@1
mov dx,3b4h ;{Mono CRTC Base Address}
@@1: pop ax
cli
out dx,al
inc dx
xchg al,ah
out dx,al
sti
pop dx
ret
GetLines:;ah=Zeilenzahl-1
push ds
push bx
mov bx,40h
mov ds,bx
pop bx
mov ah,[84h] ;Letzte Bildschirmzeile
pop ds
ret
;-------------- Allgemeine UP-Sammlung ----------
ahex: push ax ;Werte erhalten
mov cl,4 ;oberes Nibble auf Bit 3...0
shr al,cl ; schieben
call ahex1
pop ax
ahex1: and al,0fh
add al,90h ;Hex -> ASCII
daa
adc al,40h
daa
mov dl,al
mov ah,2
int 21h
ret
GetImg: ;GetImage
mov dx,[curso]
mov ah,2
mov bh,0
int 10h ;Cursor setzen!
mov dx,ofs TmpFile
DOS 3d00h ;öffnen
jc GI1
push ds
mov bx,ax
mov cx,[ImgLng]
mov ds,[keepscr]
mov dx,0 ;Einschränkung
DOS 3fh ;lesen
pop ds
jc GI1
DOS 3eh ;schließen
jc GI1
mov dx,ofs TmpFile
DOS 41h ;löschen
GI1: ret
params dw 0
parofs dw 80h
parseg dw ?
VM dw 0
keepscr dw 0 ;Bilschirmswap-Segment
ImgLng dw ?
curso dw ?
msgE db 'DOS-Fehler #$'
TmpFile db 'C:/',60 dup(0) ;Temporäre Datei
ResEnd: ;Ab hier von Tochter überschreibbar
tmp$ db 'TEMP='
OpenTmp:;VR: AX, BX, DX
;ES=Ptr Environment
push di si cx
mov es,[2ch]
xor di,di
xor ax,ax
cld
lp3: mov cx,5 ;Länge von TEMP=
mov si,offset tmp$
repe cmpsb ;Vergleichen
je lp2 ;gleich
dec di
lp1: scasb
jnz lp1
scasb
dec di
jnz lp3
push ds
pop es
jr lp4
lp2: mov si,ofs TmpFile
EX ds,es
xchg si,di
lp5: lodsb ;StrCopy
stosb
or al,al
jnz lp5
push es
pop ds ;DS back!
mov [by di-1],'\' ;das Schlußzeichen wie intern
lp4: mov dx,ofs TmpFile
mov cx,0
DOS 5ah ;Temporäre Datei erstellen
mov bx,ax
pop cx si di
ret ;Mit oder ohne CY
SaveImg:
push ds bx ;Handle retten
mov ah,0fh
int 10h
push ax
mov ah,3
int 10h ;in bh noch die Seite
mov [curso],dx
pop ax
mov dx,0b000h
cmp al,7 ;Hercules?
jz JHerc
mov dh,0b8h
JHerc: mov [keepscr],dx
mov ds,dx ;Fernes Segment...
xchg al,ah ;Zeichen pro Zeile
call GetLines
or ah,ah
pushf
inc ah
mul ah ;Zeilenzahl
popf
jnz lngok
mov ax,80*25
lngok: shl ax,1 ;2 Bytes!
mov cx,ax
mov [es:ImgLng],cx
mov dx,0 ;Nur Bildseite Null!! (Einschränkung)
pop bx
DOS 40h ;write
jc SavI1
cmp ax,cx
stc
jnz SavI1
DOS 3eh ;close
SavI1: pop ds
ret
msgH db 'KeepVideoMode v1.33 (haftmann#software): Batch-Hilfsprogramm',nl
db 'Gebrauch: keepvm programmname [parameter]',nl
db 'stellt den Videomodus nach Programmausführung auf den vor dem Start.',nl
db '(Vollständiger Name mit Erweiterung notwendig!)',nl
db 'In dieser Version bitte nur *ausführbare* Programme angeben, also z.B.',nl
db 'KEINE Batch-Dateien!!!',nl
db 'Option /X rettet Bildschirm-Text in temporärer Datei',nl
db '$'
;
ENDC
Detected encoding: OEM (CP437) | 1
|
|