; CSPATCH.ASM  CALC STAR PATCHES FOR TURBOROM 6-5-86
;
; Works with version 1.46
;
; These patches are intended to make the arrow key definitions
; match the Micropro "STANDARD".  As the Calc Star root module, CS.COM
; is overwritten, the "DE-INITIALIZATION" of the arrow keys on exit
; from CALC STAR is complicated.  These patches:
;
;    1. Save the current arrow key definitions in low memory.
;    2. Change the arrow key definitions to match the MicroPRO pattern.
;    3. Move a small piece of executable code up under the BDOS
;       to trap calls to the BIOS Warm Boot entry.
;    4. The Warm Boot vector (in the BIOS jump table) is saveed.  
;       The vector is changed to ensure that the trap code is
;	executed.
;    5. The BDOS pointer in low memory is saved; then modified to
; 	ensure that the trap code is not overwritten.
;
; The trap module when executed:
;
;    1. Restores the original arrow key definitons
;    2. Restores the orginal BIOS Warm Boot Vector.
;    3. Restores the orginal BDOS pointer in low memory
;    4. Exits to the acutal BIOS warm boot code. 
;
; USE DDT TO PATCH CS.COM:
;
; A>DDT CS.COM
; DDT VERS 2.1
; NEXT PC
; 0400 0100
; -ICSPATCH.HEX
; -R
; NEXT PC
; 0400 0100
; -G0
;
; Warm Boot 
; A>SAVE 4 CS.COM
;
OLDBIOS	EQU	50H	; WHERE OLD BIOS VECTOR #0 WILL BE STORED WHILE RUNNING
OLDBDOS	EQU	52H	; WHERE OLD BDOS VECTOR WILL BE STORED
DINIST	EQU	54H	; WHERE DEINIT STRING WILL BE FOR DEINITIALIZATION

BASE	EQU	0	; FOR REBOOTING AND REFERENCING
BDOS	EQU	5	; FOR BDOS REFERENCES


LDIR	MACRO
	DB	0EDH, 0B0H	; LDIR (MOVE) INSTRUCTION
	ENDM

	ORG	15AH	; ID STRING
	DB	'CS'

	ORG	100H
	JMP	INISUB		; INITIALIZE ARROW KEYS

	ORG	300H

INISUB:	LHLD	BASE+1		; GET BIOS VECTOR
	LXI	D,32H		; OFFSET TO KEYBOARD TABLE
	DAD	D		; HL--> KEYBOARD TABLE
	PUSH	H		; SAVE --> TO TABLE
	LXI	D,DINIST	; SAVE KEYBOARD TABLE IN LOW MEMORY
	LXI	B,4
	LDIR			; LDIR (MOVE) INSTRUCTION
;
	LXI	H,INISTR	; SOURCE --> TO NEW VALUES
	POP	D		; DEST --> IS KEYBOARD TABLE
	LXI	B,4		; LENGTH OF MOVE
	LDIR			; MOVE NEW VALUES INTO BIOS
;
	LHLD	BDOS+1		; GET BDOS VECTOR
	SHLD	OLDBDOS		; STORE IT ELSEWHERE IN BASE PAGE
	LXI	D,0-PATLEN-3	; NEGATIVE PATCH LENGTH
	DAD	D		; ADD OFFSET TO MAKE TPA THAT MUCH SMALLER
	SHLD	BDOS+1		; STORE NEW BDOS ADDRESS
	MVI	M,0C3H		; PUT JUMP THERE
	INX	H		; POINT TO NEXT ADDRESS
	XCHG			; INTO DE
	LHLD	OLDBDOS		; GET REAL BDOS ADDRESS
	XCHG			; INTO DE
	MOV	M,E		; MAKE JUMP TO REAL BDOS
	INX	H
	MOV	M,D
	INX	H
	PUSH	H
	XCHG			; START OF WHERE TO PUT CODE IN DE
	LXI	H,DEINIT	; POINT TO CODE TO MOVE IN HL
	LXI	B,PATLEN	; LENGTH IN BC
	LDIR			; LDIR (MOVE) INSTRUCTION
	POP	D		; ADDRESS OF PATCHES INTO DE
	LHLD	BASE+1		; GET BIOS ADDRESS
	INX	H		; ADD 1 FOR STORING NEW BIOS VECTOR 0
	PUSH	H		; SAVE IT FOR THE MOMENT: DE HAS ADDRESS OF
	PUSH	D		; PATCHES, HL HAS ADDRESS OF VECTOR
	MOV	E,M		; GET OLD VECTOR TO OLDBIOS
	INX	H
	MOV	D,M		; BIOS COLD BOOT INTO DE
	XCHG
	SHLD	OLDBIOS		; PUT THIS INTO OLDBIOS FOR RESTORATION LATER
	POP	D		; RESTORE REGS
	POP	H
	MOV	M,E		; PUT NEW VALUES IN
	INX	H
	MOV	M,D
	LHLD	BDOS+1		; DO THE CODE THAT WE OVERWROTE IN THE BGINING
	JMP	103H

DEINIT:	LHLD	OLDBDOS		; GET OLD BDOS VECTOR
	SHLD	BDOS+1		; STORE IT
	LHLD	OLDBIOS		; GET OLD BIOS VECTOR ADDRESS 0
	XCHG			; INTO DE
	LHLD	BASE+1		; GET BIOS ADDRESS
	INX	H		; POINT TO NEXT ADDRESS (WHERE VECTOR GOES)
	MOV	M,E		; STORE LOW ORDER
	INX	H		; POINT TO NEXT
	MOV	M,D		; STORE HI ORDER
	LHLD	BASE+1		; GET BIOS BASE ADDRESS
	LXI	D,32H		; NOW DEINITIALIZE KEYS...
	DAD	D		; THE SAME WAY WE DID ABOVE
	LXI	D,DINIST
	XCHG
	LXI	B,4
	LDIR			; LDIR (MOVE) INSTRUCTION
	JMP	0		; EXIT TO BIOS WARM BOOT
PATLEN	EQU	$-DEINIT

INISTR:	DB	5, 18H, 13H, 4

	END
