;------------------------------------------------------------------------
;     Split_Screen - SnapShot                                 release 1.0
;     Copyright (c) Ingo Eickmann, 1989                          06/14/89
;------------------------------------------------------------------------
;     Assemblieren mit MASM 5.x :
;            MASM split;                               I. Eickmann
;            LINK split;                               Im Leuchterbruch 8
;            EXE2BIN split.exe split.com               5000 K”ln 80
;     Getestet unter MS-DOS 3.3
;------------------------------------------------------------------------
      PAGE   65,80
      TITLE  Split_Screen

ALT_U       equ 1600h                  ; Scan-Code von <ALT-U>
ALT_D       equ 2000h                  ; Scan-Code von <ALT-D>
ALT_S       equ 1F00h                  ; Scan-Code von <ALT-S>
Snap_Buffer equ 1000h                  ; Offset der 2. Bildschirmseite
max_Lines   equ 400                    ; fЃr VGA-Textmode, EGA-Textmode: 350
if1
   include  split.mac
endif
;------------------------------------------------------------------------
KBDSEG segment at 40h                  ; Eintr„ge im System-Segment
   org 1Ah
      HEAD   dw ?                      ; Vektor auf „ltesten Eintrag im Buffer
      TAIL   dw ?                      ; Vektor auf freien Platz im Buffer
      Buffer dw 16 dup(?)              ; Tastatur-Buffer
   org 80h
      Buffer_Start dw ?                ; erste Speicherstelle des Buffers
      Buffer_End   dw ?                ; letzte Speicherstelle + 1
KBDSEG ends
;------------------------------------------------------------------------
code segment                           ; Segment des Programms
     assume cs:code,ds:code,es:KBDSEG
     org 100h                          ; Startadresse fЃr .com-File
start:    jmp Install
;------------------------------------------------------------------------
oldint09h    dd 0                      ; Vektor auf alte Interruptroutine 09h
oldint1Ch    dd 0                      ; Vektor auf alte Interruptroutine 1Ch
Line_Compare dw -1                     ; Wert fЃr Line_Compare_Register
Add_Word     dw 0
;------------------------------------------------------------------------
INT09h proc near                       ; Erweiterung fЃr Tastaturinterrupt
          pushf                        ; retten aller Register und Flags
          REG_PUSH <ax,bx,cx,dx,di,si,ds,es>
          pushf                        ; Aufruf der alten ISR 09h
          call  dword ptr cs:[oldint09h]
          cli
          push  cs                     ; Vorbelegung der Segmentregister
          pop   ds
          mov   ax,KBDSEG
          mov   es,ax
	  cmp	byte ptr es:[49h],3    ; Text-Mode 80x25 Color?
          jne   Raus
          mov   si,[Tail]              ; Vektor auf letzten Eintrag im
          cmp   si,[Head]              ; Tastatur-Buffer
          jz    Raus                   ; Scan-Code vorhanden? - Nein => Raus
          cmp   si,[Buffer_Start]
          jg    ok2
          mov   si,[Buffer_End]
ok2:      sub   si,2                   ; Scan-Code entnehmen
          mov   ax,es:[si]             ; und in ax speichern
          cmp   ax,ALT_U               ; Ist Scan-Code ALT-U?
          jne   ok3
          sub   Add_word,1             ; JA: nach oben beschleunigen
          jmp   Ende
ok3:      cmp   ax,ALT_D               ; Ist Scan-Code ALT-D?
          jne   ok4
          add   Add_word,1             ; JA: nach unten beschleunigen
          jmp   Ende
ok4:      cmp   ax,ALT_S               ; Ist Scan-Code ALT-S?
          jne   Raus
          REG_PUSH <si,ds,es>          ; JA: Register speichern
          mov   ax,0B800h              ;     Video-Segment laden
          mov   ds,ax
          mov   es,ax
          mov   si,0                   ;     Offset der 1. Bildschirmseite
          mov   di,Snap_Buffer         ;     Offset des Zwischenspeichers
          mov   cx,1000h shr 1         ;     Z„hler auf 1000h Bytes
          cld
          repnz movsw                  ;     Bildschirmseite kopieren
          REG_POP <es,ds,si>           ;     Register wiederherstellen
Ende:     mov   [Tail],si              ; Vektor auf n„chsten Eintrag zurЃck-
Raus:     REG_POP <es,ds,si,di,dx,cx,bx,ax>                     ; schreiben
          popf                         ; alle Register wiederherstellen
          iret                         ; RЃcksprung aus der ISR
INT09h endp
;------------------------------------------------------------------------
INT1Ch proc near                       ; Erweiterung des Zeitgeber-Interrupts
          sti
          pushf                        ; Register retten
          REG_PUSH <ax,bx,cx,dx,ds,es,cs>
          pop   ds                     ; Segmentregister vorbelegen
          mov   ax,Add_word
          or    ax,ax                  ; ist Verschiebung notwendig?
          jnz   pt0
          jmp   no_mov                 ; NEIN: => Raus
pt0:      add   ax,Line_Compare        ; Neuen Wert fЃr Line_Compare berechnen
          cmp   ax,-1                  ; oberste Zeile erreicht?
          jg    pt1
          mov   Add_word,0             ; JA: Verschiebung zurЃcksetzen
          mov   ax,-1
pt1:      cmp   ax,max_Lines           ; unterste Zeile erreicht?
          jl    pt2
          mov   Add_word,0             ; JA: Verschiebung zurЃcksetzen
          mov   ax,max_Lines
pt2:      mov   cx,Snap_Buffer         ; Offset fЃr Start_Address_Register
          push  ax
          cmp   ax,-1                  ; oberste Zeile?
          jg    pt3
          mov   ax,3FFh                ; JA: default fЃr Line_Compare
          mov   cx,0                   ;     Offset fЃr 1. Bildschirmseite
pt3:      mov   Line_Compare,ax
          Split_Screen cx,Line_Compare ; s. Listing der Macros (Bild 2)
          pop   ax
          mov   Line_Compare,ax        ; aktuellen Line_Compare speichern
no_mov:   REG_POP <es,ds,dx,cx,bx,ax>  ; Register wiederherstellen
          popf
          jmp dword ptr cs:[oldint1Ch] ; Sprung in die alte ISR
INT1Ch endp
;------------------------------------------------------------------------
Install:  push  cs                     ; ds-Segment vorbelegen
          pop   ds
          IRP n,<09h,1Ch>              ; Macro fЃr Interrupts 09h und 1Ch
             mov  ax,35&n
             int  21h                  ; alte ISR-Vektoren retten
             mov  word ptr oldint&n,bx
             mov  word ptr oldint&n+2,es
             mov  ax,25&n              ; neue ISR-Vektoren setzen
             mov  dx,offset Int&n
             int  21h
          endm
          mov   dx,offset InstMSG      ; Meldung ausgeben
          mov   ah,9
          int   21h
          mov   ax,3100h               ; resident beenden
          mov   dx,offset Install
          mov   cl,4
          shr   dx,cl
          inc   dx
          int   21h
InstMSG   db 'ЙННННННННННННННННННННННННННННННННННННННН'
          db 'ННННННННННННННННННННННННННННННННННННННН»'
          db 'є Split_Screen - SnapShot               '
          db '                           release 1.0 є'
          db 'є Copyright (c) I.Eickmann, 1989        '
          db '                              06/14/89 є'
          db 'є Press <ALT-U> to accelerate up, <ALT-D'
          db '> to acc. down, <ALT-S> for SnapShot   є'
          db 'ИННННННННННННННННННННННННННННННННННННННН'
          db 'НННННННННННННННННННННННННННННННННННННННј$'
code ends
end  start
