;RXSW: Satelliten-Receiver-Umschalter
;CTRL+ALT+U: Kanal hoch
; J: Kanal runter
; H: Kanalsteuerungs-Automatik
;Version 3 mit Auswertung der VT.INI, Sektion [RXSW3], Schlüssel schedule
;anstatt Patchen der .COM-Datei
include prolog.asm
include "asc2scan.asm"
REQfunc equ 4b48h ;in AX
REQcode equ 9879h ;in DX
ANScode equ 8764h ;in AX; DX=Segmentadresse
ResPara equ (ISRBase-PSPOrg+ISRE-ISRA+0fh)/16
org 5ch
ctrl0 db ?
ISRBase: ;FCB's überschreiben
ChIst db ?
ChSoll db ?
ChAuto db ?
ChHDrv db ?
TonL db ?
org 100h
PRINT Text0 ;Meldung
mov [ctrl0],0e0h ;erst mal Standard laden
;Bit4 ist Int13BusyFlag
call LoadIst ;Istwert von Platte laden, 1..48
call InstChk ;ggf. ES auf Fremdroutine
;nun ch=Statusregister:
;Bit0..3: Deinstallation nicht möglich
;Bit7: Noch nicht installiert
JUMPS
mov si,81h
cld
scancl: lodsb
cmp al,'/'
jz scancl
cmp al,'-'
jz scancl
cmp al,' '
jz scancl
cmp al,'?'
jz help
cmp al,0dh
jz install
BRES al,bit 5
cmp al,'H'
jz help
cmp al,'U'
jz UnInst
cmp al,'D'
jz DisAb
cmp al,'E'
jz setab
cmp al,'S'
jz Stat2
cmp al,'Q'
jz quiet
cmp al,'I'
jz zahlen
scanc0: jr scancl ;weiter in Kommandozeile
NOJUMPS
zahlen:
push cx
mov di,ofs SwTab
test ch,bit 7
jnz v0
mov di,ofs SwTab -ISRA+ISRBASE
v0: mov cx,24
v2: push cx
v1: lodsb
cmp al,' '
je v1
dec si
mov bl,10
call inw
jc te
stosb ;Zahl abspeichern
pop cx
loop v2
pop cx
mov al,[es:di-24]
stosb ;25. Stunde wie 1. Stunde
jr scanc0
te: mov dx,ofs TextE
jmp TxtOut
quiet: lodsb
cmp al,'-'
jnz sndoff
bset [es:ctrl0],bit 5 ;Tastaturpiepser ON
jr scanc0
sndoff: dec si
bres [es:ctrl0],bit 5
jr scanc0
help: ;Hilfe Option "H" oder "?"
mov dx,offset TextH
jr TXTOut
disab: test ch,80h
mov dx,ofs Text5
jnz TXTOut
mov dx,ofs Text4b
jr TXTOut
UnInst: ;Deinstallation(sversuch) Option "U"
mov dx,ofs Text5
test ch,80h
jnz TXTOut ;Wenn nicht nötig!
and ch,0fh
jz Raus
PRINT Text4b
mov dx,ofs Text4a
bres [es:Ctrl0],0e0h ;löschen (auch Tastatur sperren)
jr TXTOut
DisActiv:;Deaktivieren Option "D"
test ch,80h ;Schon installiert?
mov dx,ofs Text5
jnz TXTOut
mov dx,ofs Text4b
jr disab
;Deinstallation
Raus: lds dx,[es:ofs OldInt09-ISRA+ISRBASE]
DOS 2509h
lds dx,[es:ofs OldInt08-ISRA+ISRBASE]
DOS 2508h
lds dx,[es:ofs OldInt17-ISRA+ISRBASE]
DOS 2517h
lds dx,[es:ofs OldInt13-ISRA+ISRBASE]
DOS 2513h
DOS 49h ;den Speicher ab es freigeben
push cs
pop ds
mov dx,ofs Text3 ;removed...
;dx-adressierten Text ausgeben
TXTOut: DOS 9 ;Textausgabe
;Programm beenden
LFOut: PRINT NL$
DOS 4C00h
setab: test ch,80h
mov dx,ofs Text5
jnz TXTOut
bset [es:Ctrl0],bit 7 ;setzen
stat2: ;hier ist die Statusanzeige
call statmeld
test ch,80h
jnz sta1
PRINT Text6
sta1: jr lfout
proc InstChk
;Installationscheck, ES=Zeiger auf installierte Routine oder n.a.!,
;Bit7(CH)=0: Installationscheck erfolgreich, dann:
;ES: Segmentadresse der residenten Routine
;Bit0,1,2(CH)=0: Zeiger nicht von anderen verbogen
;Di=0 wenn nicht installiert, ISRBASE-ISRA wenn installiert
mov ax,REQfunc ;
mov dx,REQcode
int 17h
xor ch,ch
mov di,ISRBase-ISRA
cmp ax,ANScode ;gleich?
jz @@1
or ch,80h ;Z-Flag "retten"
xor di,di
mov dx,ds
@@1: push dx ;Segment der TSR
;Segment retten
DOS 3513h ;Get Int13
SES <OldInt13>,bx
cmp bx,ofs NewInt13-ISRA+ISRBASE
jnz @@13f
mov bx,es
cmp bx,dx
je @@13ok
@@13f: bset ch,bit 3 ;ch <>0 wenn andere TSR stört
@@13OK:
DOS 3517h ;Get Int17
SES <OldInt17>,bx
cmp bx,ofs NewInt17-ISRA+ISRBASE
jnz @@17f
mov bx,es
cmp bx,dx
je @@17ok
@@17f: inc ch ;ch <>0 wenn andere TSR stört
@@17OK:
DOS 3508h
SES <OldInt08>,bx
cmp bx,ofs NewInt08-ISRA+ISRBASE
jnz @@08F
mov bx,es
cmp bx,dx
je @@08ok
@@08f: bset ch,bit 1
@@08ok:
DOS 3509h
SES <OldInt09>,bx
cmp bx,ofs NewInt09-ISRA+ISRBASE
jnz @@09F
mov bx,es
cmp bx,dx
je @@09ok
@@09f: bset ch,bit 2
@@09ok:
pop es
ret
endp
proc LoadIst ;Istwert von Platte holen
mov bx,ofs SecBuf
mov cx,2 ;Sektor 2, Zyl. 0
mov dx,80h ;Festplatte C: Kopf 0
DRV 201h ;1 Sektor lesen
jc @@e ;Fehler ->Kanal 8 bleibt
mov al,[bx]
mov [ChHDrv+(ISRA-ISRBase)],al ;Platten-Istwert eintragen
or al,al
jz @@e
cmp al,49
jnc @@e ;AL ist nicht im Bereich 1..48
mov [ChIst+(ISRA-ISRBase)],al ;Sollte tatsächlicher Istwert sein!
mov [ChSoll+(ISRA-ISRBase)],al ;Sollte tatsächlicher Istwert sein!
mov [ChAuto+(ISRA-ISRBase)],al ;Sollte tatsächlicher Istwert sein!
@@e: ret
endp
;═══════════════════════════════════════
ISRA:
db 8 ;mit Einschalt-Kanalnummer belegt!
db 8
db 8
db 8 ;Festplatten-Inhalt
db 0 ;Initialisierungswerte
NewInt17: ;Neue INT17-Routine
cmp ax,REQfunc ;Installationscheck?
jne I17cont
cmp dx,REQcode
jne I17cont
mov ax,ANScode
mov dx,cs
iret
I17cont:
cmp dx,0 ;Schnittstelle 0?
jnz ToOld17
xor ah,ah ;Status: Drucker nicht bereit!
iret
ToOld17: JMPF
OldInt17 dd ?
NewInt13: ;Neue Int13-Routine: setzt Reentranz-Flag.
pushf
bset [cs:ctrl0],bit 4 ;Setzt Int13Busy-Flag
popf
pushf
callf
OldInt13 dd ?
pushf
bres [cs:ctrl0],bit 4 ;Löscht Int13Busy-Flag
popf
sti
retf 2
NewInt08:
push ax ds dx
mov ax,40h ;DS=Bios-Segment
mov ds,ax
mov dx,[8] ;LPT1-Adresse holen
cmp [wo 6ch],0 ;Volle Stunde?
mov al,[6eh] ;Stunde holen
LD ds,cs ;DS=Eignes Segment
jnz NoSw ;nein, nichts zu schalten
push bx
mov bx,ofs SwTab-ISRA+ISRBASE ;Schalttabelle adressieren
xlat ;Neue Kanalnummer holen
pop bx
mov [ChAuto],al
btst [ctrl0],bit 0 ;Auto-Modus?
jnz NoSw ;nein, Schaltverbot!
mov [ChSoll],al ;ja, auch zum Sollwert machen!
NoSw:
cmp [TonL],1 ;Läuft Ton?
jc NoTon ;nein
dec [TonL] ;Zeitzähler...
jnz NoTon ;Nicht Null
in al,61h ;Lautsprecher wieder ausschalten
and al,not 3
out 61h,al
NoTon:
btst [ctrl0],bit 7
jz EndInt08 ;Wenn abgeschaltet nichts tun!
in al,dx
test al,bit 1+bit 2 ;Interessierende Bits
jz NoBRes
bres al,bit 1+bit 2 ;abschalten (egal welches)
jr OutEnd
NoBRes:
mov ah,[ChSoll]
cmp [ChIst],ah
jz EndInt08 ;Nichts zu tun
jc IncIst ;Istwert zu klein - emulieren
dec [ChIst]
bset al,bit 2 ;-Bit
jr OutEnd
IncIst:
inc [ChIst]
bset al,bit 1 ;-Bit
OutEnd: out dx,al ;Ausgabe
EndInt08:
pop dx ds ax
pushf
callf
OldInt08 dd ? ;EOI an INT-Controller ausgeben lassen
sti
push ax bx cx dx ds es
LD ds,cs
LD es,cs
mov al,[ChIst]
cmp [ChHdrv],al ;Istwert auf Platte korrekt?
jz wrerr ;ja, nichts tun
btst [ctrl0],bit 4 ;Int13Busy?
jnz wrerr ;Kann (noch) nichts tun
mov bx,ofs SecBuf-ISRA+ISRBase
mov [bx],al ;ChIst als erstes Byte eintragen!
mov cx,2 ;Sektor 2 Zylinder 0
mov dx,80h ;Laufwerk C: Kopf 0
DRV 301h ;1 Sektor schreiben
jc wrerr
mov al,[ChIst]
mov [ChHdrv],al ;Kanal auf Platte angeglichen.
wrerr: pop es ds dx cx bx ax
iret
;##########################################
NewInt09:
push ax ds ;Ansprung durch Tastendruck
xor ax,ax
mov ds,ax
mov al,[417h] ;Tastatur-Statusbyte, AUSNAHMSWEISE mit DS=0!
LD ds,cs
btst [ctrl0],bit 6 ;Tastaturfunktion eingeschaltet?
jz i09cont
not al
and al,00001100b ;nur noch Ctrl & Alt - Flag
jnz i09cont
in al,60h ;AL=Scan-Code der gedr. Taste
cmp al,16h ;HotKey "U" () gedrückt ?
jz KP1
cmp al,24h ;"J" ()
jz KP2
cmp al,23h ;"H" (auto)
jz KP3
i09cont:
pop ds ax
JMPF
OldInt09 dd ?
KP1: ;HOCH-Funktion
bset [ctrl0],bit 0 ;HAND-Bit setzen
cmp [ChSoll],48 ;Maximal?
jz EndHot2 ;Nicht stellen!
inc [ChSoll] ;Neue Soll-Kanalnummer
mov ax,900 ;Tonhöhe
jr EndHotkey
KP2: ;RUNTER-Funktion
bset [ctrl0],bit 0 ;HAND-Bit setzen
cmp [ChSoll],1 ;Minimal?
jz EndHot2 ;Nicht stellen!
dec [ChSoll] ;Neue Soll-Kanalnummer
mov ax,1000 ;tieferer Ton
jr EndHotkey
KP3: ;AUTO-Funktion
bres [ctrl0],bit 0 ;HAND-Bit löschen
mov al,[ChAuto]
mov [ChSoll],al ;kopieren
mov ax,800 ;Höchster Ton
EndHotKey:
call Pieps
EndHot2:
mov al,20h ;EOI
out 20h,al
in al,61h ;Zeichen abholen
mov ah,al
or al,80h
out 61h,al ;Bit 7[61h] setzen
xchg al,ah
out 61h,al ;auf alten Wert zurück
pop ds ax
iret ;zurück zum Caller
proc Pieps ;Piepser (ES=40h, Tonhöhe AX, feste Länge 3 Ticks) sounden
;und dabei Null Rechenzeit nehmen!
btst [ctrl0],bit 5 ;Pieps ein?
jz @@e ;nein, schweigen
push ax
in al,61h
or al,3
out 61h,al
mov al,0b6h
out 43h,al
pop ax
out 42h,al
xchg al,ah
out 42h,al
xchg ah,al ;AX unverändert
mov [TonL],3
@@e: ret
endp
;#########################################
;SchaltTabelle
SwTab db 12,12,11,11,10,10,6,6,2,2,3,3 ;vormittags
db 7,5,4,4,8,13,9,9,22,22,28,28,12 ;nachmittags
SecBuf db 512 dup (?) ;Festplattensektor
ISRE:
;=== Ende residenter Code ===
proc Statmeld
PRINT TextS1
test ch,80h
mov dx,ofs Text5 ;Nicht installiert
jnz @@x
btst [es:ctrl0],bit 7
mov dx,ofs Text4b
jz @@x ;deaktiviert
btst [es:ctrl0],bit 0
mov dx,ofs Text2
jz @@a
mov dx,ofs Text2a
@@a: DOS 9
PRINT Text2b
mov al,[es:ChIst]
xor ah,ah
call axdez
PRINT Text2c
mov cx,24
mov si,ofs SwTab -ISRA+ISRBASE
@@l: PRINT Space
seges lodsb
xor ah,ah
call axdez
loop @@l
mov dx,ofs nl$
@@x: DOS 9
@@e: ret
endp
_OCHR
_AXDEZ
_ANUM
_INW
Install: test ch,80h
jn z,stat2
;ISR nach vorn schaufeln
cld
push cs
pop es
mov si,ofs ISRA
mov di,ofs ISRBase
mov cx,(ISRE-ISRA+1)/2
rep movsw
mov di,ISRBASE-ISRA
;Zeiger verbiegen
mov dx,ofs NewInt13-ISRA+ISRBASE
DOS 2513h ;Set Int13
mov dx,ofs NewInt17-ISRA+ISRBASE
DOS 2517h ;Set Int17
mov dx,ofs NewInt08-ISRA+ISRBASE
DOS 2508h ;Set Int08
mov dx,ofs NewInt09-ISRA+ISRBASE
DOS 2509h ;Set Int09
;Environment freigeben
mov es,[2ch] ;Segment Environment
DOS 49h ;ENV-Speicher ab es freigeben
;Test des Hochladens
mov ax,cs
mov es,ax ;Eigenes Programm=Resident!
cmp ax,0a000h
mov dx,ofs Text1
jc NoHi ;unten
mov dx,ofs Text1a
NoHi: ;enabeln
DOS 9
PRINT Text6a
mov al,[es:ChIst]
xor ah,ah
call axdez
PRINT Text6b
mov dx,ResPara
DOS 3100h
;═══════════════════════════════════════
_SCANTAB
macro dbd str ;;definiere Bytes doppelt mit Backstep für LESS
irpc x,<str>
db '&x&',8,'&x&'
endm
endm
macro dbu str
irpc x,<str>
db '_',8,'&x&'
endm
endm
Text0: dbd <RXSW3>
db ' 02/01 (haftmann#software): $'
Text1a db 'hoch'
Text1 db 'geladen, $'
Text6 db 'Hotkeys: CTRL+ALT+U[]/J[]/H[auto]$'
Text6a: dbu <Prüfe>
db ' Receiver auf Kanal'
Space db ' $'
Text6b db ' !',nl,'$'
Text6d db ' (Kein Piepsen)$'
Text2 db 'Automatik$'
Text2a db 'Handwahl$'
Text2b db ', Kanal $'
Text2c db nl,'Kanalliste:$'
TextE db 'Kanalnummern fehlerhaft!$'
Text3 db 'vom Speicher entfernt.$'
Text4b db 'deaktiviert.$'
Text4a db ' (Andere TSR stahl Int08, 09, 13 oder 17)$'
TextS1 db 'Status: $'
Text5 db 'Noch nicht installiert!$'
TextH db ' ++ FREEWARE ++',nl
db '(Satelliten-)Receiver-Umschalter für Videotext-Dekoder.',nl,10
db 'Parameter: - (keiner) laden oder Statusanzeige',nl
db ' - d oder 0 RXSW deaktivieren',nl
db ' - e .. aktivieren',nl
db ' - q{-} Hotkeypiepse {einschalten}',nl
db ' - s Status',nl
db ' - i<24 Zahlen> Kanalnummern pro Stunde',nl
db ' - u TSR entfernen',nl
db ' - ? oder h diese Hilfe$'
NL$ db nl,'$'
endc
Detected encoding: OEM (CP437) | 1
|
|