;*****************************************************************************
;	MICRO RESOURCES PCC2000 CP/M FORMAT CONVERTER FOR 3812
;*****************************************************************************
;
;
;	
;	THIS PROGRAM IS DESIGNED TO RUN WITH A 24K CP/M SYSTEM
;	ON AN ICOM 3812 UTILIZING LIFEBOAT DOUBLE DENSITY
;	CP/M 1.4. THE PROGRAM REQUIRES READ/WRITE RAM AT ADDRESS
;	06200H TO 063FFH. DO NOT ATTEMPT TO RUN THIS PROGRAM
;	WHILE SINGLEB IS IN EFFECT BECAUSE THIS IMPLIES A CONFLICT
;	OF IMPLIED FUNCTIONAL GOALS. NOTE THAT THIS PROGRAM UTILIZES
;	THE SAME OPERATIONAL PHILOSOPHY AT THE LIFEBOAT SINGLEB
;	PACKAGE.
;
;	COPYRIGHT 1980
;		MICRO RESOURCES
;		2468 HANSEN CT.
;		SIMI VALLEY, CA 93065
;		(805) 527-7922
;
;*****************************************************************************
;
;
CR	EQU	0DH		;CARRAGE RETURN
LF	EQU	0AH		;LINE FEED
;
;
;
	ORG 	0100H		;WE MUST START HERE TO SATISFY CP/M
;
;
;INIT PRIVATE STACK
;
	LXI	H,0		;HL=0
	DAD	SP		;HL=STACK FROM CP/M
	SHLD	STACK		;..SAVE IT
	LXI	SP,STACK 	;SP=MY STACK
;
	LXI	D,MESS1		;PRINT VERSION MESSAGE
	CALL	PRTMSG
;
	LXI	D,MESS2		;PRINT USAGE MESSAGE
	CALL	PRTMSG
;
	LHLD	WBOOT+1		;GET ADDRESS OF VECTOR TABLE
	DCX	H		;ADJUST TO CBOOT BASE
	DCX	H
	DCX	H
;
	MVI	A,05FH		;CHECK IF SYSTEM BIGGER THAN 24K
	CMP	H		;05E00H = BASE OF VECTOR TABLE FOR 24K
	JZ	SYSBIG		;EXIT IF SYSTEM TOO BIG
	JC	SYSBIG
;
	PUSH	H		;SAVE BASE ADDRESS OF VECTOR TABLE
	LXI	D,SETDSK+1
	DAD	D		;MAKE ADDRESS OF THE SET DISK ROUTINE
	LXI	B,NWSETDSK
	MOV	E,M		;GET VECTOR TABLE ADDRESS
	MOV	M,C		;PUT IN ADDR OF OUR ROUTINE
	INX	H
	MOV	D,M
	MOV	M,B
	LXI	H,NWSETDSK
	MOV 	A,D		;CHECK IF ALREADY IN EFFECT
	CMP	H
	JNZ	MOVCODE		;NOT SO ON WITH PROCESS
	MOV	A,E
	CMP	L
	JNZ	MOVCODE
;
	POP	H		;FIX STACK RIGHT
	LXI	D,MESS4		;GO PRINT ALREADY IN EFFECT MESSAGE
	CALL	PRTMSG
	JMP	EXIT		;BALE OUT
;
MOVCODE:			;ON WITH THE PROCESS
	PUSH	D		;SAVE SET DISK VECTOR FOR AFTER MOVE
	LXI	H,TRANPR	;BASE OF TRANSLATE PROGRAM
	LXI	D,START		;POINT TO START AREA OF THIS LISTING
	LXI	B,01FFH		;AMOUNT OF CODE TO MOVE
LOOP:
	LDAX	D		;GET A BYTE
	MOV	M,A		;PUT ABOVE 24K SYSTEM
	CMP	M		;CHECK IF IT WENT IN OK
	JNZ	ERROR		;EXIT IF ERROR
	INX	H
	INX	D
	DCX	B		;DECREMENT THE BYTE COUNT
	MOV	A,B
	ORA	C
	JNZ	LOOP		;DONE MOVING CODE YET?
;
	POP	D		;GET BACK SET DISK VECTOR
;
	XCHG			;GET DISK ROUTINE ENTRY FOR LIFEBOAT PROM
	SHLD	LBSETDSK+1
;
	POP	H		;GET BASE ADDRESS OF VECTOR TABLE
;
	PUSH	H		;SAVE BASE ADDRESS OF VECTOR
	LXI	D,SETTRK+1
	DAD	D		;MAKE ADDRESS OF THE SET SECTOR ROUTINE
	LXI	B,NWSETTRK
	MOV	E,M		;GET VECTOR TABLE ADDRESS
	MOV	M,C		;PUT IN ADDRESS OF OUR ROUTINE
	INX	H
	MOV	D,M
	MOV	M,B
	XCHG			;GET TRACK ROUTINE ENTRY FOR LIFEBOAT PROM
	SHLD	LBSETTRK+1
;
	POP	H		;GET BASE ADDRESS OF VECTOR TABLE
;
	LXI	D,SETSEC+1
	DAD	D		;MAKE ADDRESS OF THE SET SECTOR ROUTINE
	LXI	B,NWSETSEC
	MOV	E,M		;GET VECTOR TABLE ADDRESS
	MOV	M,C		;PUT IN ADDRESS OF OUR ROUTINE
	INX	H
	MOV	D,M
	MOV	M,B
	XCHG			;GET SECTOR ROUTINE ENTRY FOR LIFEBOAT PROM
	SHLD	LBSETSEC+1
	JMP	EXIT
;
ERROR:
	POP	D
	POP	H		;FIX UP STACK FOR EXIT
	LXI	D,MESS5		;PRINT MOVE ERROR MESSAGE
	CALL	PRTMSG
	JMP	EXIT
;
SYSBIG:
	LXI	D,MESS3		;PRINT THE BAD SYSTEM SIZE MESSAGE
	CALL 	PRTMSG
;
EXIT:
	LHLD	STACK		;GET BACK CCP STACK POINTER
	SPHL			;RESET THE STACK
	RET			;BACK TO CCP WITHOUT WARM BOOT
;
MESS1:
	DB	CR,LF,'PCC2000B VER 1.3 FOR USE WITH ICOM 3812 '
	DB	CR,LF,'DOUBLE DENSITY CP/M VERSION 1.4 '
	DB	CR,LF,'COPYRIGHT (C) 1980 MICRO RESOURCES','$'
MESS2:
	DB	CR,LF,LF
	DB	CR,LF,'THIS PROGRAM MAY BE USED WITH A 24K OR SMALLER'
	DB	CR,LF,'CP/M SYSTEM AND REQUIRES READ/WRITE MEMORY FROM'
	DB	CR,LF,'6200H TO 63FFH. DRIVE B: (ONLY) WILL BE SET'
	DB	CR,LF,'FOR PCC-2000 CP/M FORMAT UNTIL COLD BOOT.','$'
MESS3:
	DB	CR,LF,LF
	DB	'SYSTEM IS TOO LARGE - MAX ALLOWED IS 24K - BYE','$'
MESS4:
	DB	CR,LF,LF
	DB	'PCC2000B ALREADY IN EFFECT..COLD BOOT TO EXIT..','$'
MESS5:
	DB	CR,LF,LF
	DB	CR,LF,'MEMORY AT 6200H TO 63FFH SEEMS FAULTY...BYE','$'
;
;PRTMSG: PRINTS MSG POINTED TO BY (DE)
;
;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
;NO REGISTERS SAVED.
;
PRTMSG:
	MVI	C,PRINT		;GET BDOS FNC
	JMP	BDOS		;PRINT MESSAGE, RETURN
;
;
;
;SETUP A STACK AREA
;
	DS	40		;STACK AREA
STACK	DS	2		;STACK POINTER
;
START	EQU	$+2		;BASE TO MOVE HEX OF TRAN PROG TO FOR COM FILE
;
;
; BDOS EQUATES (VERSION 2)
;
WBOOT	EQU	0		;WARM BOOT ENTRY ADDRESS
PRINT	EQU	9		;CONSOLE PRINT STRING FUNCTION
SETDSK	EQU	01BH		;VECTOR OFFSET FOR SET DISK
SETTRK	EQU	01EH		;VECTOR OFFSET FOR SET TRACK
SETSEC	EQU	021H		;VECTOR OFFSET FOR SET SECTOR
BDOS	EQU	5
;
;
;
;TRANSLATE PROGRAM FOR PCC2000 DISK IN B: DRIVE
;
;	AT LOAD TIME THE SETDISK,SET TRACK, AND SET SECTOR
;	BIOS VECTOR TABLE ENTRIES ARE REPLACED WITH ENTRY
;	POINTS TO THREE NEW ROUTINES THAT OCCUPY MEMORY
;	SPACE ABOVE A 24K CP/M SYSTEM. ADDRESS SPACE USED
;	STARTS AT 6200H. WHEN MAKING A .COM FILE OUT OF
;	THIS MODULE IT IS NECESSARY TO USE DDT TO LOAD THE
;	HEX FILE VERSION OF PCC2000B. THEN A MOVE COMMAND
;	OF THE FOLLOWING FORM IS USED TO PUT THE 6200 BASED
;	CODE BLOCK IN THE POSITION OF THE LABEL "START" ABOVE.
;	THE COMMAND UNDER DDT WOULD BE:
;
;		-M6200,63FF,START
;			..WHERE START IS VALUE OF LABEL ABOVE.
;
;	SUBSEQUENT EXIT FROM DDT ALLOWS SAVING OF THE .COM VERSION
;	OF PCC2000B AS FOLLOWS:
;
;		A>SAVE 8 PCC2000B.COM
;
;
	ORG	06200H		;BASE OF PATCH PROGRAM
TRANPR:				;LABEL REFERENCE FOR START OF MOVE TO
;
;
;NEW SET DISK ROUTINE THAT SETS FLAG FOR DRIVE B:SELECT
;
NWSETDSK:
	PUSH	PSW
	MOV	A,C		;GET DRIVE CODE
	CPI	01H		;CHECK FOR DRIVE B:
	JZ	SETFLG		;GO TO SET FLAG
;
	XRA	A		;CLEAR FLAG FOR NON B: DRIVE
	STA	BDRV
	POP	PSW
	JMP	LBSETDSK
SETFLG:
	MVI	A,0FFH		;SET FLAG FOR B: DRIVE
	STA	BDRV
	POP	PSW
;
LBSETDSK:
	JMP	$		;JUMP TO NORMAL VECTOR TABLE ADDRESS
				;SET AT PROGRAM LOAD
;
;
;B: DRIVE SET FLAG FOR THE SET DISK ROUTINE
;
BDRV	DB	0
;
;
;
;NEW SET TRACK ROUTINE SETS TRACK ON B: +1 FOR PCC2000 FORMAT
;
;
NWSETTRK:
	PUSH	PSW		;SAVE OFF
	LDA	BDRV		;CHECK FLAG STATUS
	CPI	00H		;SEE IF EXIT WITHOUT TRK+1
	JZ	TRKXIT
;
	MOV	A,C		;GET TRACK NUMBER
	CPI	076H		;SEE IF IT IS ALREADY MAX AND LEAVE THERE
	JZ	TRKXIT
	INR	A		;SET TRK UP ONE
	MOV	C,A		;SET BACK TO PROPER REG FOR CP/M
;
TRKXIT:
	POP	PSW
LBSETTRK:
	JMP	$		;ADDRESS SET TO VECTOR TABLE ENTRY AT INIT
;
;
;NEW SET SECTOR ROUTINE FOR THE PCC2000 DIFFERENT SKEW FACTOR
;
NWSETSEC:
	PUSH	PSW		;SAVE OFF
	PUSH	H
	LDA	BDRV		;CHECK FLAG STATUS
	CPI	00H		;SEE IF EXIT WITH NO SKEW TRANSLATE
	JZ	SECXIT
;
	MOV	A,C		;GET SECTOR NUMBER
	DCR	A		;FIX SECTOR NUM..THEY START WITH ONE
	LXI	H,TRANTBL	;GET SKEW TABLE BASE
	ADD	L		;MAKE TABLE INDEX
	MOV	L,A
	MOV	A,H
	ACI	00H		;TAKE CARE OF CARRY TO H
	MOV	H,A
	MOV	C,M		;GET NEW SECTOR NUMBER
;
SECXIT:
	POP	H		;RESTORE
	POP	PSW
LBSETSEC:
	JMP	$		;ADDR TO VECTOR TBL SET AT INIT
;
TRANTBL:			;LIFEBOAT TO PCC-2000 SECTOR TRANSLATE
	DB	1
	DB	2
	DB	31
	DB	32
	DB	9
	DB	10
	DB	39
	DB	40
	DB	17
	DB	18
	DB	47
	DB	48
	DB	25
	DB	26
	DB	3
	DB	4
	DB	33
	DB	34
	DB	11
	DB	12
	DB	41
	DB	42
	DB	19
	DB	20
	DB	49
	DB	50
	DB	27
	DB	28
	DB	5
	DB	6
	DB	35
	DB	36
	DB	13
	DB	14
	DB	43
	DB	44
	DB	21
	DB	22
	DB	51
	DB	52
	DB	29
	DB	30
	DB	7
	DB	8
	DB	37
	DB	38
	DB	15
	DB	16
	DB	45
	DB	46
	DB	23
	DB	24
;
	END
