Source file: /~heha/vt/viewers/vt080.zip/src/ESTIMATE.ASM

;Include-Datei "Videotextseiten-Errater-Routinen"

;Suche nach:
; - Weiteren Videotextseiten
; - Anzahl der Unterseiten zu einer Seite
; - Sendername

;############################################################
;### Abscannen einer Seite nach weiteren relevanten Daten ###
;############################################################

;PE: DI - Unterseiten-Nummer
;IR: interne Registerbelegung:
;    BH - Zahlzeichenzähler, FF=im Klötzchengrafikmodus
;    BL - Zeilenlängenzähler
;    AH - Anzahl der Angaben einer Unterseitennummer
;    bit7AH - Unterseitennummer-Schaltbit
;    DX - Videotextseitennummer
;PA: CH - maximale Unterseite
proc ScanLine		;Suche Zeile nach weiteren Seiten und nach der
			;maximalen Unterseite ab
	push	bx
	mov	bx,40		;Zeilenlänge
	mov	cl,4		;Standardschiebelänge
	xor	dx,dx		;Zahl-Default
	bres	ah,bit 7	;Kennbit-Default
@@l:	lodsb
@@l1:	cmp	bh,0ffh		;Grafikmode?
	jnz	@@ngr		;nein
	cmp	al,8		;Umschaltzeichen Text?
	jnc	@@le		;nein, weiter mit Grafik
	jr	@@5		;ja, BH löschen
@@ngr:
	cmp	al,'0'		;Ziffer?
	jc	@@2
	cmp	al,'0'+10
	jnc	@@2		;nein
	sub	al,'0'
	shl	dx,cl		;DX "erweitern"
	or	dl,al
	inc	bh
	jr	@@le		;zum Schleifenende
@@2:	;Folgt Slash? (Unterseiten-Kennung)
	or	bh,bh		;Zahlzeichen vorher?
	jz	@@3		;nein
	btst	ah,bit 7
	jnz	@@v		;Slash-Kennung
	cmp	al,'/'
	jnz	@@4		;Keine Unterseiten-Kennung
	cmp	bh,3		;Mehr als 79 Unterseiten sind unvernünftig!
	jnc	@@4		;mehr als 2 Ziffern nicht zulassen
	or	di,di		;Unterseite vorhanden?
	jz	@@5		;nein
	cmp	dx,di		;Zahl GLEICH Unterseite
	jnz	@@5		;nein
	bset	ah,bit 7	;Gültige Unterseitennummer mit Slash gefunden
	jr	@@5a
@@v:
	cmp	bh,3
	jnc	@@4
	cmp	dx,di		;Zahl kleiner als Unterseite?
	jc	@@5		;ja, kein Sinn
	mov	ch,dl		;Höchste Unterseite (BCD!!) abspeichern
	inc	ah
	jr	@@5
@@4:
	cmp	bh,3		;3 Ziffern hintereinander?
	jnz	@@5		;nein, verwerfen
	cmp	dx,100h		;kleiner 100?
	jc	@@5		;verwerfen!
	cmp	dx,900h		;größer/gleich 900?
	jnc	@@5		;verwerfen!
	btst	[ctrl0],bit 2	;Eintragung überhaupt erwünscht?
	jz	@@5		;nein,raus!
	and	dh,7		;auf "ganze" Seite begrenzen
	push	ax
	 call	PagePredict_Put	;Seite vorhersagen
	pop	ax
@@5:	bres	ah,bit 7
@@5a:	xor	dx,dx
	mov	bh,dh		;Zahl "löschen"
@@3:
	cmp	al,10h		;Grafik einschalten?
	jc	@@le
	cmp	al,18h
	jnc	@@le
	mov	bh,0ffh		;ja!
@@le:	sub	bl,1
	mov	al,' '		;Leerzeichen für 41. Spalte annehmen!
	jn	z,@@l1
	jn	nc,@@l
@@e:	pop	bx
	ret
endp ScanLine

proc ScanPage
;- Sucht Puffer nach 3stelligen Seitennummern ab und
;  gibt sie dem Prädiktor, wenn Bit 2[CTRL0] gesetzt
;- Sucht Puffer nach der maximalen Unterseitennummer ab in der Form x/x,
;  x/xx oder xx/xx und gibt sie nach CX (CH=0)
;  Diese Angabe x/x (usw.) darf nur EINMAL auftreten!
;PE: (SI: Pufferadresse, mit Seitendaten im Header gefüllt)
;PA: CX: maximale Unterseite
	push	bx dx si di
	 add	si,40		;Mit Zeile 1 beginnen
	 xor	ah,ah		;Unterseitenfinde-Zähler nullsetzen
	 mov	di,[si-38]	;Aktuelle Unterseite nach DI parken
	 mov	bl,23		;23 Zeilen
@@l:	 call	ScanLine	;Zeilen 1 bis 23 parsen
	 mov	cl,ch
	 dec	bl
	 jnz	@@l
	 cmp	cl,2		;Angabe z.B. 1/1? (meist ungültig!!)
	 jc	@@k
	 dec	ah		;1maliges Auftreten?
	 mov	ch,ah
	 jz	@@u
@@k:	 xor	cx,cx		;CX=0: Kennung für NoMaxSub
@@u:	pop	di si dx bx
	ret
endp ScanPage

proc ModifyPage			;wie der Name schon sagt...
	;PE: DI: Zeiger auf Akquisitorspiegel
	;PA: CY=1: Seite kann wg. problematischer Kopfzeile
	;(anderer Sender) nicht weiterverwendet werden, Seite verwerfen!
	; (Falls nicht Bit 3[CTRL0] gesetzt ist)
	;
	;sonst:
	;Puffer (eingelesene Seite) modifizieren:
	;- Eintragen der 7 Bytes Headerinformation
	;- Sendernamen-Check
	;- Zeitcheck, Zeitübernahme bzw. Zeitrückschrift
	push	di
	 lea	si,[acq.fPage]
	 lea	di,[Buf]
	 mov	cx,7
	 rep	movsb		;Wohlgeordnete Infobits mitliefern!
	 mov	al,7
	 stosb			;ein korrektes Farbbyte setzen
	pop	di
	btst	[acq.fBits],bit 7 + bit 10 ;Unterdrücken der Kopfzeile oder Telesoftware
	jnz	@@1
	btst	[ctrl0],bit 3	;RTL4-Problembit gesetzt?
	jnz	@@1
	call	CheckHL		;Überschrift testen, CY=1: Überschrift fraglich
	jc	@@e		;Raus wenn Problem!!
@@1:
	mov	si,ofs Buf
	call	ScanPage
	or	cx,cx		;Unterseite angegeben?
	jz	@@2		;Nein, dann nicht eintragen
	mov	ax,[wo Buf]
	call	MSList_PutMS	;Maximale Unterseite in der (800-Byte-Tab eintragen)
@@2:	push	di
	 lea	di,[Buf+25*40+10]
	 xchg	ax,cx
	 mov	ah,bh		;Auch den Akquisitor vermerken!
	 stosw			;Maximale Unterseite BCD und Acq eintragen
	 call	GetTimeStamp
	 stosw
	 xchg	ax,dx
	 stosw			;diese Zeit hier eintragen
	 xor	ax,ax
	 mov	cx,4
	 rep	stosw		;Rest löschen (soweit sogut)
	pop	di
	clc
@@e:	ret
endp ModifyPage

	_ANUM
	_UPCASE

proc GetTimeStamp
	;PA: DXAX: DOS-üblicher Zeitstempel (DX=Datum, AX=Zeit)
	DOS	2ah	;Datum
	mov	ax,cx
	sub	ax,1980	;Jahr Null für DOS herstellen
	mov	cl,4
	shl	ax,cl
	or	al,dh	;Monat dazu
	inc	cl	;5
	shl	ax,cl
	or	al,dl	;Tag dazu - fertig!
	push	ax
	 DOS	2ch	;Zeit
	 mov	al,ch	;Stunde
	 mov	ch,cl	;Minute retten
	 mov	cl,6
	 shl	ax,cl
	 or	al,ch	;Minute dazu
	 dec	cl	;5
	 shl	ax,cl
	 shr	dh,1
	 or	al,dh	;Halbe Sekunden dazu
	pop	dx	;fertig!!
	ret
	endp

proc ExtractName
;- sucht Puffer mit Kopfzeile nach Sendernamen ab
;PE: SI: Pufferzeiger
;PA: [Buf2] Sendername
	push	si cx bx di
	 mov	cx,24
	 xor	bx,bx		;Buchstaben- und Ziffernflag (~zähler)
	 mov	di,ofs Buf2
@@l:	 lodsb
	 call	upcase
	 cmp	al,21h		;Steuerzeichen?
	 jc	@@3		;Ende eines vermeintlichen Strings
	 inc	bl
	 mov	ah,al		;retten
	 call	anum
	 cmp	al,36		;Kein Buchstabe oder Ziffer?
	 jnc	@@2
	 cmp	al,16
	 jc	@@1		;Ziffer (Hexziffern sind möglich!)
	 mov	bh,al		;Buchstabe-Flag
@@1:	 mov	al,ah
	 stosb
	 jr	@@2
@@3:
	 or	bh,bh		;Mind. 1 Buchstabe?
	 jnz	@@5		;ja, raus aus der Schleife!
	 xor	bx,bx
	 mov	di,ofs Buf2
@@2:	 loop	@@l
	 jr	@@4
@@5:	;TEXT entdecken (NUR am Ende!)
	 cmp	[wo di-4],'ET'
	 jnz	@@7
	 cmp	[wo di-2],'TX'
	 jnz	@@7
	;und wegschnippeln
	 sub	di,4
@@7:	 cmp	bl,8		;Zeichen
	 jnc	@@4
	 cmp	al,' '		;Echtes Space als Trenner?
	 jnz	@@4		;wenn nein: kein weiterer Kommentar!
	 lodsw			;2 Folgezeichen
	 cmp	ah,21h		;2. Zeichen Trennzeichen?
	 jnc	@@4		;nein, RAUS
	 mov	ah,al
	 call	anum		;Buchstabe oder Ziffer?
	 cmp	al,36
	 jnc	@@4		;nein, raus
	 xchg	al,ah
	 call	Upcase		;Großbuchstabe draus machen!
	 stosb			;ein Extrazeichen anhängen
@@4:	;ausstieg
	 xor	al,al
	 stosb			;Abschluß-Null
	 mov	[Buf2+8],al	;Begrenzung auf max. 8 Zeichen
	pop	di bx cx si
	ret
	endp


proc ExtractTime		;Zeit nach DI...
	push	si cx
	 mov	cx,7
@@p:	 lodsw			;Vermeintliche Zahl lesen
	 dec	si
	 sub	al,'0'
	 cmp	al,10
	 jnc	@@2		;Zehner ist keine Zahl
	 xchg	al,ah
	 sub	al,'0'
	 cmp	al,10
	 jnc	@@2		;Einer ist keine Zahl
	 aad			;AL:=AH*10+AL
	 stosb			;als Binärzahl!
	 inc	si
	 dec	cx
	 jcxz	@@q
@@2:	 loop	@@p
@@q:	pop	cx si
	ret
	endp

proc PGTime_Init
	;Initialisieren von PGTStr
	;- Aufruf bei jedem Senderwechsel
	mov	si,ofs PGTStrOri
	mov	di,ofs PGTStr
Move8Bytes:
	mov	cx,4
	rep	movsw
	ret
	endp

proc PGTime_Check
	;- arbeitet fest mit BUF
	;- extrahiert die vermeintliche Uhrzeit nach "PGTime"
	;- Ist keine 3stellige Zeitangabe zu finden, wird PGTStr zurück-
	;  geschrieben
	;- Notwendig wegen der Tatsache, daß die Uhrzeit selten korrekt
	;  ausgelesen wird...
	push	di
	 mov	si,ofs Buf+32	;Uhrzeit-Stelle
	 mov	di,ofs PGTimeTmp
	 call	ExtractTime
	 cmp	di,ofs PGTimeTmp+3 ;3 oder 4 Bytes geschrieben?
	 mov	di,ofs PGTStr	;schon mal laden...
	 jnc	@@1		;ja, Hinzu kopieren!
	 xchg	di,si		;Andersherum kopieren
@@1:	;zum PGTStr hinkopieren
	 call	Move8Bytes	;hinschreiben
	 jc	@@2
	 mov	si,ofs PGTimeTmp
	 mov	di,ofs PGTime
	 movsw
	 movsw			;Richtige Zeit kopieren
@@2:	pop	di
	ret
	endp

;####################################################
;### Verwaltung einer maximalen Unterseitennummer ###
;####################################################

proc MSList_Init
	mov	di,ofs MSList
	xor	ax,ax
	mov	cx,400
	rep	stosw
	ret
	endp

proc MSList_PutMS
	;Vermerkt zur Seite AX die max. Unterseitennummer BL (alles BCD!)
	;PE: AX: Seite, CL: Max. Unterseite
	;PA: -
	;VR: AX
	push	bx
	 call	PageBCD2Bin
	 jc	@@e
	 mov	[MSList+bx],cl
@@e:	pop	bx
	ret
	endp

proc MSList_GetMS
	;holt zur Seite AX die max. Unterseitennummer nach
	;PE: DX: Seite BCD
	;PA: AX: max. Unterseite BCD, CY=1 UND AX=0 wenn nicht in Tabelle
	;VR: AX
	push	bx
	 mov	ax,dx
	 call	PageBCD2Bin
	 mov	al,0
	 jc	@@e		;wenn hex.
	 mov	al,[MSList+bx]
@@e:	 mov	ah,0
	 cmp	al,1		;Carry setzen, wenn AX=0
	pop	bx
	ret
	endp

;##############################################
;### "Gültigkeit" einer Seitennummer testen ###
;##############################################
proc PageBCD2Bin
	;Wandelt BCD-Form in Binärform um
	;PE: AX: BCD-Seitennummer 0..7FFh
	;PA: BX: Binär-Seitennummer 0..799d
	;  CY=1: Pseudotetraden oder Nummer zu groß
	push	ax
	 mov	bx,ax
	 call	CheckPseudoPage
	 jc	@@e
	 xchg	al,bl	;BL: nur Einer, BH: Hunderter
	 shr	al,1
	 shr	al,1
	 shr	al,1
	 shr	al,1 	;Zehner
	 mov	ah,10
	 mul	ah	;AL: Zehner*10, AH=0
	 add	al,bl	;AX=Zehner*10+Einer (AH ist immer 0)
	 xchg	bx,ax	;AH=Hunderter
	 mov	al,100
	 mul	ah	;AX=Hunderter*100
	 add	bx,ax	;BX=Hunderter*100+Zehner*10+Einer, CY=0
@@e:	pop	ax
	ret
	endp

proc CheckPseudoSubPage
	;PE: AX: Unterseite
	;Eine (übliche) Unterseite muß <80 sein und darf keine
	; Pseudotetraden enthalten (z.B. "2F" ist verboten)
	;HINWEIS: Vorgesehen ist eine ZEITGESTEUERTE Unterseitenverwaltung,
	;wobei das High-Byte die Stunden beinhaltet! Allerdings macht es
	;kaum einer so (ich kenne KEINEN Sender!) wie es sich PHILIPS denkt...
	;PA: CY=1 wenn Pseudoseite
	;VR: AX (!)
	cmp	ax,80h
	jnc	@@e
CheckPseudoPage:
	;PE: AX: Seite
	;Eine Seite muß <800 sein und darf keine
	; Pseudotetraden enthalten (z.B. "72F" ist verboten)
	;PA: CY=1 wenn Pseudoseite
	;VR: AX (!)
	cmp	ax,800h
	jnc	@@e
@@u:	cmp	al,0a0h
	jnc	@@e
	and	al,0fh
	cmp	al,0ah
@@e:	cmc
	ret
	endp

;##################################################
;###   Verwaltung eines "Stimmungsbarometers"   ###
;### (History von "SearchHit" und "SearchMiss") ###
;##################################################
;32 bit Tiefe

;macro Barometer_Init
;	;Barometer auf Mittelwert setzen!
;	mov	ax,5555h	;abwechselnd 0- und 1-Bits!
;	STL	[Barometer],ax,ax
;	endm

Barometer_Shift1:
	stc
proc Barometer_Shift
	;PE: CY=1 wenn gefunden und CY=0 wenn nicht gefunden!
	rcl	[wo LOW Barometer],1
	rcl	[wo HIGH Barometer],1
	ret
	endp

proc Barometer_Get
	;PA: AX: Anzahl gesetzter Bits im Barometer (0..32)
	;VR: DX,AX
	xor	al,al
	mov	dx,[wo HIGH Barometer]
	call	@@1
	mov	dx,[wo LOW Barometer]
@@1:	mov	ah,16
@@l:	rol	dx,1
	adc	al,0	;Carries addieren
	dec	ah
	jnz	@@l
	ret
	endp
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded