;
;	PROGRAM  PATCHCPM
;	12-22-83 JOD
;
;	PURPOSELY WRITTEN IN 8080 CODE SO ALL CAN USE
;
;	FEEL FREE TO ADD ANY OTHER PATCHES YOU HAVE COME ACROSS - IF
;	YOU DO THEN HOW ABOUT SHARING THEM WITH ME? THANKS.
;
;			JIM DREHER
;			1937 ARMORY ROAD
;			BARSTOW, CA
;			92311
;
;	**********  PATCHCPM LIMITATIONS  **********
;
; 1.	THIS PROGRAM CANNOT LOAD PAST 08FFH OR IT WILL OVERWRITE
;	THE MEMORY IMAGE OF THE CCP YOU ARE PATCHING - IF NECESSARY
;	REMOVE SOME OF THE LESS USEFUL PATCHES TO INCLUDE YOURS
;
; 2.	IF YOU ANSWER 'N' TO A QUESTION IT WILL NOT RESTORE THE CCP
;	TO IT'S ORIGINAL STATE.  IF YOU WISH TO REMOVE THE PATCH THEN
;	START WITH A "FRESH" CP/M SYSTEM.
;
; 3.	NOTE THAT IF YOU DISABLE ONE OF THE BUILT-IN COMMANDS YOU MUST
;	HAVE A .COM FILE OF THAT NAME ON THE DISK FOR THAT COMMAND TO
;	WORK.  FOR EXAMPLE YOU MAY WANT TO DISABLE THE BUILT-IN "DIR"
;	COMMAND AND PUT "SD.COM" RENAMED TO "DIR.COM" ON THE DISK.
;


; *** CHANGE MEMSIZE AND BASE TO MEET YOUR SYSTEM REQUIREMENTS ***

MEMSIZE	EQU	64		; CP/M SYSTEM SIZE IN K BYTES
BASE	EQU	0		; START OF RAM ON YOUR SYSTEM

BIAS	EQU	(MEMSIZE-20)*1024
CCP	EQU	3400H + BIAS + BASE	; START OF CCP

TPABOOT EQU	0900H			; WHERE SYSGEN PUTS BOOT IN THE TPA
TPACCP	EQU	0980H			; AND THE CCP...
TPABDOS EQU	1180H			; AND THE BDOS...
TPABIOS EQU	1F80H			; AND THE BIOS

CTRLC	EQU	3
LF	EQU	10
CR	EQU	13
CTLZ	EQU	26
ESC	EQU	27
BEL	EQU	7

	ORG	0100H

START:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'PATCHCPM  22-DEC-83  JOD'
	DB	CR,LF
	DB	0

;.....

      	CALL	ILPRT
	DB	CR,LF,LF
	DB	'Need help (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF HELP NOT NEEDED
	JZ	ONE

;		 1234567890123456789012345678901234567890
HELP:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'PATCHCPM is a collection of useful patches'
	DB	' for CP/M 2.X systems.  To use:'
	DB	CR,LF,LF
	DB	'1.  Run SYSGEN to get your CP/M system into memory'
	DB	CR,LF
	DB	'2.  Run PATCHCPM and select the desired patches.'
	DB	CR,LF
	DB	'3.  When PATCHCPM finishes it prints '
	DB	'"Ready for SYSGEN or SAVE 34 CPMXX.PAT"'
	DB	CR,LF
	DB	'4.  Save your patches with SYSGEN or SAVE.'
	DB	CR,LF,LF
	DB	'Continue with PATCHCPM (Y/N)? '
	DB	0

	CALL	GETANS			; WARM START IF NOT READY
	JZ	0000H

;.....

ONE:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Do you want DELETE to work like BACK SPACE (Y/N)? '
	DB	0

	CALL	GETANS		; IF NO THEN SKIP
	JZ	TWO

; THANKS TO LEWIS MOSELEY

	LXI	H,TPACCP + 0A1BH	; HL = ADDRESS TO PATCH
	LXI	D,PAT1			; DE = ADDRESS OF NEW CODE
	MVI	B,3			; B  = NUMBER OF BYTES TO MOVE
	CALL	MOVE			; MAKE THE PATCH

;.....

TWO:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'If desired, the next patch causes drive A to'
	DB	' become the "system drive".'
	DB	CR,LF
	DB	'It will force the CCP to look on Drive A when'
	DB	' you are logged into a drive'
	DB	CR,LF
	DB	'other than A and call for a .COM file that does not'
	DB	' exist on that drive.'
	DB	CR,LF,LF
	DB	'* Do you want drive A to be the "system drive" (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF ANSWER IS NO

; THANKS TO ????

	LXI	H,TPACCP + 06DBH	; SAME AS ABOVE
	LXI	D,PAT2
	MVI	B,3
	CALL	MOVE

	LXI	H,TPACCP + 07F2H
	LXI	D,PAT2A
	MVI	B,14
	CALL	MOVE

;.....

THREE:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in DIR (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	THREEA

	LXI	H,TPACCP + 0310H
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

THREEA:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in ERA (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	THREEB

	LXI	H,TPACCP + 0314H
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

THREEB:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in TYPE (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	THREEC

	LXI	H,TPACCP + 0318H
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

THREEC:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in SAVE (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	THREED

	LXI	H,TPACCP + 031CH
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

THREED:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in REN (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	THREEE

	LXI	H,TPACCP + 0320H
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

THREEE:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'* Disable CCP built-in USER (Y/N)? '
	DB	0

	CALL	GETANS		; SKIP IF NO
	JZ	FOUR

	LXI	H,TPACCP + 0324H
	LXI	D,PAT3
	MVI	B,4
	CALL	MOVE

;.....

FOUR:	NOP			; PATCH NUMBER FOUR GOES HERE
	NOP
	NOP
	NOP

;.....

DONE:	CALL	ILPRT
	DB	CR,LF,LF
	DB	'Ready for SYSGEN or SAVE 34 CPMXX.PAT'
	DB	CR,LF
	DB	0

     	JMP	0		; WARM START

;
;	SUBROUTINE MOVE
;
;	FUNCTION:	MOVE A BLOCK OF MEMORY
;
;	ENTRY:		HL = SOURCE ADDRESS
;			DE = DESTINATION ADDRESS
;			B  = NUMBER OF BYTES TO MOVE
;
;	EXIT:		N/A
;

MOVE:	LDAX	D		; GET BYTE
	MOV	M,A		; MOVE IT
	INX	H		; ADVANCE POINTERS
	INX	D
	DCR	B		; DONE?
	JNZ	MOVE 		; NO - KEEP GOING
	RET			; YES- DONE

;
;	SUBROUTINE GETANS
;
;	FUNCTION:	GETS AN INPUT FROM THE CONSOLE, CHECKS FOR 'Y'
;			OR 'N' ONLY.  DOES A WARM START IF CTRL-C ENTERED.
;
;	ENTRY:		N/A
;
;	EXIT:		Z FLAG IS SET   IF ANSWER IS 'N'
;			Z FLAG IS CLEAR IF ANSWER IS 'Y'

GETANS:	MVI	C,1		; BDOS CONSOLE INPUT
	CALL	5		; GET ANSWER

	CPI	CTRLC		; WANT TO QUIT?
	JZ	0		; YES- WARM START

	CPI	'Y'
	JZ	GA1
	CPI	'N'
	JZ	GA1

	CALL	ILPRT
	DB	BEL,CR,LF
	DB	'Please answer Y or N : '
	DB	0
	JMP	GETANS

GA1: 	SUI	'N'		; SET Z FLAG ACCORDINGLY
	RET

;
;	VANILLA FLAVORED ILPRT ROUTINE
;
ILPRT:	POP	H		; GET ADDRESS OF CHARACTER
	MOV	A,M		; GET CHARACTER
	INX	H		; POINT TO NEXT CHARACTER
	ORA	A		; NULL?
	JZ	ILPRT$DONE	; YES- EXIT
	MOV	E,A		; GET CHAR IN E
	PUSH	H		; SAVE POINTER
	MVI	C,2		; BDOS CONSOLE OUTPUT
	CALL	5 		; SEND IT
	JMP	ILPRT		; DO ANOTHER CHARACTER
ILPRT$DONE:
	PCHL			; RETURN TO CALLING PROGRAM

;
;	STORAGE FOR PATCHES
;

PAT1:	JMP	CCP + 0A07H	; JUMP TO THE BACK SPACE ROUTINE (AFTER
				; DELETE IS ENTERED)

PAT2:	JZ	CCP + 07F2H
PAT2A:	LXI	H,CCP + 07F0H
	ORA	M		; ACCUM WAS 0 ON ENTRY, SO THIS FETCHES DRIVE
	JNZ	CCP + 076BH	; COMMAND HAS EXPLICIT DRIVE ... GIVE ERROR
	INR	M		; FORCE EXPLICIT REFERENCE TO DRIVE A
	LXI	D,CCP + 07D6H	; WE NEED TO SETUP DE TO RE-ENTER CCP
	JMP	CCP + 06CDH	;

PAT3:	DB	0,0,0,0		; WHOOPIE

ENDDAT:	END			; *** MUST BE < 0900H ***
