home *** CD-ROM | disk | FTP | other *** search
- ;* ------------------------------------------------------ *
- ;* CGA.ASM *
- ;* CGA-Emulator für Herculeskarten *
- ;* (c) 1989 Peter Plucinski & TOOLBOX *
- ;* ------------------------------------------------------ *
- cseg segment 'code'
- assume cs:cseg, ds:cseg;
-
- org 100h
-
- LF equ 0ah ; Linefeed
- CR equ 0dh ; Return
- Equip equ 10h ; Equipment-Bytes
- Video equ 10h ; Video-Interrupt
- Boot equ 19h ; Bootstrap
- Dos equ 21h ; Dos-Interrupt
- Index equ 3b4h ; 6845 Index Register
- Mode equ 3b8h ; 6845 Display Mode Ctrl Port
- Config equ 3bfh ; 6845 Configuration Switch
-
- main: jmp init
-
- Vec10 dd ? ; alter INT-10 Vektor
- tab dw offset tab200 ; 6845 Parametertabelle
-
- ;* ------------------------------------------------------- *
- ;* Neue Interrupt 10 Routine *
- ;* ------------------------------------------------------- *
- NewINT10: push ax ; Register sichern
- push bx ; "
- push cx ; "
- push dx ; "
- push ds ; "
- or ah, ah ; ah = 0 ?
- jnz OldINT ; nein -> alte Int-Routine
- cmp al, 7 ; al >= 7 ?
- jge OldINT ; ja -> alte Int-Routine
- cmp al, 3 ; Textmodus (0..3)?
- jg gr ; nein -> Grafik einschalten
- mov ax, 40h ; Equipment ändern
- mov ds, ax
- or word ptr ds:[Equip], 30h
- jmp OldINT
-
- gr: call graphic
-
- OldINT: pop ds
- pop dx
- pop cx
- pop bx
- pop ax
- jmp cs:[Vec10] ; alte Int-10 Routine
-
- ;* ------------------------------------------------------- *
- ;* Grafik einschalten (640*200) *
- ;* ------------------------------------------------------- *
- graphic: push ds
- mov ax, 40h
- mov ds, ax
- and ds:[Equip], 0ffcfh
- or word ptr ds:[Equip], 20h
- mov ax, Mode
- mov ds:[63h], ax
-
- ;* - 6845 neu programmieren ------------------------------ *
-
- mov dx, Index
- mov bx, word ptr cs:[tab]
- mov cx, 12
- mov ah, 0
- InitGr: mov al, ah ; al = 0..12
- out dx, al
- inc dx
- mov al, cs:[bx]
- out dx, al ; 3b5 = 6845 Datenregister
- inc ah
- inc bx
- dec dx
- loop InitGr
-
- mov dx, Config ; 6845 Konfiguration
- mov al, 3 ; Grafik, Seite 1
- out dx, al
- mov dx, Mode ; 6845 Modus ändern
- mov al, 8ah ; Seite 1, Bildschirm
-
- ;* - aktivieren, Grafikmodus ----------------------------- *
-
- out dx, al
- pop ds
- ret
-
- ;* ------------------------------------------------------- *
- ;* 6845 Parametertabelle *
- ;* ------------------------------------------------------- *
-
- ;* - Tabelle für 200 und 300 Zeilen ---------------------- *
-
- tab200: db 36h ; Gesamtzahl der Zeichen pro Zeile-1
- db 28h ; Anzahl der sichtbaren Zeichen
- db 2dh ; Position-1 des ersten Zeichens
- ; während HSYNC
- db 08h ; Anzahl Zeichen während HSYNC
- db 7fh ; Anzahl Zeilen-1
- db 1fh ; Anzahl Zeilendurchläufe zusätzlich
- db 64h ; Anzahl der sichtbaren Zeilen
- db 72h ; Zeilennummer-1 für VSYNC
- db 02h ; (immer 2)
-
- lines: db 01h ; Durchläufe/Zeile-1
- db 06h ; Cursorstart
- db 07h ; Cursorende
-
- ;* - Tabelle für 400 Zeilen ------------------------------ *
-
- tab400: db 6ah, 28h, 2bh, 07h, 67h, 0ah, 64h, 67h, 01h
- db 01h, 06h, 07h
-
- EndOfResident:
-
- ;* ------------------------------------------------------- *
- ;* Initialisierung, nichtresidenter Teil *
- ;* ------------------------------------------------------- *
- init: ; alten int10 Vektor sichern
- mov ax, 3510h
- int Dos
- mov word ptr cs:[Vec10], bx
- mov word ptr cs:[Vec10+2], es
-
- ;* - prüfen, ob bereits resident ------------------------- *
-
- call GraphMode ; Grafikmodus 6 einschalten
- mov ah, 0fh ; ist Grafik eingeschaltet?
- int Video
- cmp al, 7 ; nein, wenn al = 7
- je NotRes
- mov cs:[ResFlag], 1
-
- NotRes: mov ax, 2 ; Textmodus einschalten
- int Video
-
- ;* - Parameter prüfen ------------------------------------ *
-
- mov bx, 80h
- xor ch, ch
- mov cl, cs:[bx] ; Anzahl Parameter
- jcxz NoPara ; 0 = kein Parameter
-
- skipsp: inc bx ; Space überspringen
- cmp byte ptr cs:[bx], 20h
- je skipsp
-
- mov ah, cs:[bx] ; Parameter holen
- cmp ah, '?' ; = '?' ?
- jne l0 ; nein -> weiter
- call Help ; Hilfe ausgeben
- jmp Exit3 ; -> Ende
- l0: cmp ah, '2' ; = 2 ?
- jne l1 ; nein -> weiter
- call Update ; neue Werte speichern
- jmp Next ; nächster Parameter
- l1: cmp ah, '3' ; = 3 ?
- jne l2 ; nein -> weiter
- call Ln300 ; auf 300 Zeilen umschalten
- jmp Next ; nächsten Parameter
- l2: cmp ah, '4' ; = 4 ?
- jne l3 ; nein -> weiter
- call Ln400 ; auf 400 Zeilen umschalten
- jmp Next ; nächsten Parameter
- l3: and ah, 0dfh ; in Großbuchstaben umwandeln
- cmp ah, 'G' ; = G ?
- jne Next ; nächster Parameter
- push bx ; bx und cx sichern
- push cx
- call graphic ; Hercules umprogrammieren
- call graphmode ; Grafikmodus 6 einschalten
- pop cx ; bx und cx holen
- pop bx
- jmp Next ; nächsten Parameter
-
- Next: loop skipsp ; cl <> 0 -> weitere Parameter
-
- NoPara:
- Exit1: call StartMsg
- mov ah, cs:[ResFlag]
- or ah, ah
- jnz Exit2
-
- ;* - neuen int10 Vektor setzen --------------------------- *
-
- mov ax, 2510h
- mov dx, offset NewINT10
- int Dos
-
- ;* - Meldung ausgeben ------------------------------------ *
-
- mov dx, offset ResMsg
- call PrintMsg
-
- ;* - Programm resident machen ---------------------------- *
-
- mov dx, offset EndOfResident
- int 27h
-
- Exit2: mov dx, offset UpMsg
- call PrintMsg
- Exit3: ret
-
- ;* - Grafikmodus 6 einschalten (640*200) ----------------- *
-
- GraphMode proc near
-
- mov ax, 6
- int Video
- ret
-
- GraphMode endp
-
- ;* - Umschalten auf 300 Zeilen --------------------------- *
-
- Ln300 proc near
- push bx ; bx und cx sichern
- push cx
- mov ax, offset tab200
- mov word ptr cs:[tab],ax
-
- mov ah, 2 ; Tabelle ändern
-
- mov byte ptr cs:[lines],ah
-
- ;* - Bereich b800:4000 bis b800:7fff löschen ------------- *
-
- mov cx, 4000h ; Anzahl Bytes
- mov ax, 0bc00h ; Startsegment
- mov es, ax
- xor ax, ax
- xor di, di
- cld
- rep stosw ; löschen
- pop cx ; bx und cx holen
- pop bx
- call Update
- ret
-
- Ln300 endp
-
- ;* - Umschalten auf 400 Zeilen --------------------------- *
-
- Ln400 proc near
-
- mov ax, offset tab400
- mov word ptr cs:[tab],ax
- call Update
- ret
-
- Ln400 endp
-
- ;* - Werte im residenten Programm ändern ----------------- *
-
- Update proc near
-
- mov ah, cs:[ResFlag]
- or ah, ah
- jz NoUpd
- mov ds, word ptr cs:[vec10+2]
- mov ax, word ptr cs:[tab] ; Parametertabelle
- mov word ptr ds:[tab],ax
- mov ah, byte ptr cs:[lines] ; Anzahl Zeilen
- mov byte ptr ds:[lines],ah
- NoUpd: ret
-
- Update endp
-
- ;* - Startmeldung ausgeben ------------------------------- *
-
- StartMsg proc near
-
- mov dx, offset msg
- call PrintMsg
- ret
-
- StartMsg endp
-
- ;* - Hilfe ausgeben -------------------------------------- *
-
- Help proc near
-
- call StartMsg
- mov dx, offset HelpMsg
- call PrintMsg
- ret
-
- Help endp
-
- ;* - Text ausgeben, auf den dx zeigt --------------------- *
-
- PrintMsg proc near
-
- push cs
- pop ds
- mov ah, 9
- int Dos
- ret
-
- PrintMsg endp
-
- ResFlag db 0
- msg db CR, LF
- db '----------------', CR, LF
- db 'CGA Emulator 1.0', CR, LF
- db '----------------', CR, LF, '$'
-
- UpMsg db 'Emulator ist bereits installiert,', CR, LF
- db 'Werte werden geaendert.', CR, LF, '$'
-
- ResMsg db 'Emulator ist resident installiert.', CR, LF
- db '$'
-
- HelpMsg db 'Optionen: 2 - 200 Zeilen', CR, LF
- db ' 3 - 300 Zeilen', CR, LF
- db ' 4 - 400 Zeilen', CR, LF
- db ' G - Grafik einschalten', CR, LF
- db ' ? - Hilfe', CR, LF, '$'
-
- cseg ends
- end main
- ;* ------------------------------------------------------- *
- ;* Ende von CGA.ASM *