;                **************************************
;                ***                                ***
;                ***   Trainer zu *********         ***
;                ***                                ***
;                ***   (c) 1994 by DATA Becker      ***
;                ***                                ***
;                ***   Autor: Boris Bertelsons      ***
;                ***                                ***
;                **************************************
;
;

.286
  w equ word ptr
  b equ byte ptr
code segment public
public insthand
public handler21
public reslim
public oldint21
public oldint65
public kennung
public klen
public check_inst

assume cs:code,ds:code
kennung:  db 'DATA BECKER'
oldint21: dd 0
oldint65: dd 0
prozedur: dd ?
klen equ offset oldint21 - offset kennung


;  *********************************************************************
;  ***                                                               ***
;  ***  An dieser Stelle stehen die eigentlichen Trainer - Routinen  ***
;  ***                                                               ***
;  *********************************************************************


;  **********************************************************************
;  ***                                                                ***
;  ***  Der neue INT 21h. Die Procedure prft, ob an der angegebenen  ***
;  ***  Stelle im Speicher der Befehl  "in al,60h" steht, und erstzt  ***
;  ***  diesen ggf. durch  "int 65h" !                                ***
;  ***                                                                ***
;  **********************************************************************
handler21 proc pascal
  pushf
  push bp
  push ds
  push bx
  mov  bp,sp
  mov  bx,[bp+10]  ; cs zur Zeit des Interrupts nach BX, DOS !!!
                   ; WICHTIG ! Im TD [bp+16] !!!
  add  bx,0366h    ; CS des 1. INT 21h + 2136h = CS der Tastaturroutine
  mov  ds,bx       ; cs der Keyboard - Routine nach ds
  mov  bx,568Bh    ; 8B56h = mov dx,[bp+06]
  cmp  ds:word ptr [0005h],bx     ; steht es in der Tastaturroutine ?
  jne  nicht_aendern
  mov  ds:word ptr [0005h],9090h  ; Int 65h reinschreiben !
  mov  ds:word ptr [0007h],65CDh  ; Int 65h reinschreiben !
nicht_aendern:
  pop  bx
  pop  ds
  pop  bp
  popf
  jmp dword ptr cs:oldint21       ; alten Int 21h aufrufen
handler21 endp

;  *************************************************************************
;  ***                                                                   ***
;  ***  Die Int 65h - Procedure. Sie liest ein Zeichen ber "in al,60h"  ***
;  ***  ein, und prft, ob das eingelesene Zeichen als Trainer-Key       ***
;  ***  definiert wurde. Falls ja, werden die zugewiesenen Speicher-     ***
;  ***  ver„nderungen und Procedureaufrufe durchgefhrt. An dieser       ***
;  ***  Stelle máen Sie Ihre Trainingsvariablen eintragen !!!           ***
;  ***                                                                   ***
;  *************************************************************************

handler65 proc far
  pushf
  push bp
  push ds
  push bx
  mov  bp,sp
  mov  bx,[bp+10]  ; cs zur Zeit des Interrupts nach BX
  in  al,60h       ; Zeichen lesen
  cmp al,63        ; Taste F5
  je  Full_Shoots_j
  cmp al,64        ; Taste F6
  je  Full_Lives_J
  cmp al,65        ; Taste F7
  je Weapon_new_j  ;
  cmp al,66        ; Taste F6
  je Weapon_new_j  ;
  cmp al,67        ; Taste F9
  je Weapon_new_j  ;
  cmp al,68        ; Taste F10
  je  More_Points_J

Ende_Keyb:
  pop bx
  pop ds
  pop bp
  popf
  iret

Full_Shoots_j:
  jmp Full_Shoots
Full_Lives_j:
  jmp Full_Lives
More_Points_j:
  jmp More_Points
Weapon_new_j:
  jmp Weapon_new

Full_Shoots:
  pushf
  PUSHA
  sub  bx,0    ; da schon richtiges CS
  mov word ptr prozedur+2,bx
  mov  bx,1401h    ; es:[bx]  =  14EF:1401
  mov word ptr prozedur,bx
;--------
  mov ds:byte ptr [0DA3h],20h
  mov ax,20h
  push ax
  call dword ptr [prozedur]
  POPA
  popf
  jmp Ende_Keyb

Full_Lives:
  pushf
  pusha
  sub  bx,0  ;
  mov word ptr prozedur+2,bx
  mov  bx,1317h  ; es:[bx]  =  14EF:1317
  mov word ptr prozedur,bx
;-----------
  mov ds:byte ptr [0DA3h],0009
  mov ax,9
  push ax
  call dword ptr [prozedur]
  popa
  popf
  jmp Ende_Keyb

Weapon_new:
  pushf
  pusha
  sub  bx,0  ;
  mov word ptr prozedur+2,bx
  mov  bx,1454h  ; es:[bx]  =  14EF:1454
  mov word ptr prozedur,bx
;-----------
  sub al,65
  mov ah,0
  mov ds:byte ptr [0DA2h],al
  push ax
  call dword ptr [prozedur]
  popa
  popf
  jmp Ende_Keyb

More_Points:
  pushf
  pusha
  sub  bx,0  ;
  mov word ptr prozedur+2,bx
  mov  bx,1BD0h  ; es:[bx]  =  14EF:1BD0
  mov word ptr prozedur,bx
;-----------
  mov ax,1000
  push ax
  call dword ptr [prozedur]
  popa
  popf
  jmp Ende_Keyb

handler65 endp

insthand proc pascal
reslim label byte
	push ds
  pop ds
	mov ax,3521h                    ; alten INT 21 sichern
  int 21h
  mov w oldint21,bx
  mov w oldint21 + 2,es
	mov ax,3565h                    ; alten INT 65h sichern
  int 21h
  mov w oldint65,bx
  mov w oldint65 + 2,es
  mov ax,2521h                    ; INT 21h auf eigene Routine verbiegen
  lea dx,handler21
  int 21h
  mov ax,2565h                    ; INT 65h auf eigene Keyboard-Routine
  lea dx,handler65
  int 21h
 	ret
insthand endp

check_inst proc near
  mov ax,3521h                    ; Interrupt - Vektor ermitteln
  int 21h
  mov di,bx
  mov si,offset kennung
  mov di,si
  mov cx,klen
  repe cmpsb                      ; Auf Kennung prfen
	ret
check_inst endp

code ends
end
