PUBLIC CTRL_X_Sequence, L25Switch, MacroDefinition, MacroInvocation
PUBLIC MACPtr, MacCtr, MacBack, MacArg, Store, FillColumn

EXTRN	.ERROR0:Near, .Error1:Near, .Msg:Near, .InCh:Near, .CLRMsg:Near
EXTRN	.CAPS:Near, InsertCRLF:Near, $KBufPtr:Word, .Piss:Near
EXTRN	FSave:Near, .Text:Near, FVisit:Near
EXTRN	Sound:Near

EXTRN	SwitchWindow:Near, ToggleNumWindows:Near, SelectBuffer:Near
EXTRN	FindFile:NEAR
EXTRN	BufToggle:Near, $Repeat:Word
EXTRN	Directory:Near
EXTRN	LastLineUpdate:NEAR, NoMODELINE:Byte
;---------------------------------------------------------------------------
	Page ,132
TITLE CTRL-X-C: commands CTL-X ?

INCLUDE        FDEF.DEF

Program        SEGMENT PARA    PUBLIC  'code'
       ASSUME  CS:Program, DS:Program, ES:Program, SS:Program

;-------------------------------------------------------------------------
Free	=	Offset CXInvalid

CXJTable	dw	Free	; ^@
dw	Free			; ^A
dw	Offset BufToggle	; ^B
dw	Free			; ^C
dw	Directory		; ^D
dw	Free			; ^E
dw	Offset FindFile		; ^F
dw	Free			; ^G
dw	Free			; ^H
dw	Free			; ^I
dw	Free			; ^J
dw	Free			; ^K
dw	Free			; ^L
dw	Free			; ^M
dw	Free			; ^N
dw	Offset SwitchWindow	; ^O
dw	Free			; ^P
dw	Free			; ^Q
dw	Free			; ^R
dw	Offset SaveBuffer	; ^S
dw	Free			; ^T
dw	Free			; ^U
dw	Offset FVisit		; ^V
dw	Offset Writebuffer	; ^W
dw	Offset ExCursMark	; ^X
dw	Free			; ^Y
dw	Offset DOSExit		; ^Z
dw	Free			; ^[
dw	Free			; ^\
dw	Free			; ^]
dw	Free			; ^^
dw	Free			; ^_
dw	Free			; ' '
dw	Free			; !
dw	Free			; "
dw	Free			; #
dw	Free			; $
dw	Free			; %
dw	Free			; &
dw	Free			; `
dw	Offset DefineMacro	; (
dw	Offset EndDefineMacro	; )
dw	Free			; *
dw	Free			; +
dw	Free			; `
dw	Free			; -
dw	Free			; .
dw	Free			; \
dw	Free			; 0
dw	Offset ToggleNumWindows	; 1
dw	Offset ToggleNumWindows	; 2
dw	Free			; 3
dw	Free			; 4
dw	Free			; 5
dw	Free			; 6
dw	Free			; 7
dw	Free			; 8
dw	Free			; 9
dw	Free			; :
dw	Free			; ;
dw	Free			; <
dw	Free			; =
dw	Free			; >
dw	Free			; ?
dw	Free			; @
dw	Free			; A
dw	Offset SelectBuffer	; B
dw	Free			; C
dw	Offset Directory	; D
dw	Offset InvokeMacro	; E
dw	Offset SetFillColumn	; F
dw	Free			; G
dw	Free			; H
dw	Free			; I
dw	Free			; J
dw	Free			; K
dw	Offset WhereamI		; L
dw	Free			; M
dw	Free			; N
dw	Offset SwitchWindow	; O
dw	Free			; P
dw	Free			; Q
dw	Free			; R
dw	Free			; S
dw	Free			; T
dw	Free			; U
dw	Free			; V
dw	Free			; W
dw	Free			; X
dw	Free			; Y
dw	Free			; Z
dw	Free			; [
dw	Free			; \
dw	Free			; ]
dw	Free			; ^
dw	CreateMap		; _
dw	Free			; '
					; lowercase trapped

CXInvalidT0	db	'*** CTL-X '
CXInvalidT1	db	'? unknown ***'
ConfirmMsg1	db	'NOT CRASHPROOF: needs valid HELP file !! [CTL-Y]'
TellFill	db	'[Fill Column Set]'
TellFillDefault	db	'[Set Fill Column Default (=75)]'
Invalidfillcolumn db	'*** Range must be 25 to 255 ***'

Store		db	(Macmaximum+1) dup ( 7 )  ; if at all, then ctl-g !
MacMsg1		db	'[Defining Macro]'
MacMsg2		db	'[Macro Defined]'
MacMsg3		db	'[Macro Invoked]'
MacroErr2	db	'*** Already in Macro Definition: Restart ***'
MacroErr1	db	'*** Not in Macro Definition ***'
MacroErr3	db	'*** Invalid Nesting ***'

MacroDefinition	db	False
MacroInvocation	db	False
MACPtr		dw	Offset Store
MacCtr		db	0
MacBack		db	0
MacArg		dw	0

SERIALNUMBER	dw	1
L25Switch	db	1
Bye		db	'MAX [Version 1.01], '
		db	'(C) 1984, Ivo Welch. All Rights Reserved.'

WRITINGMSG	db	'[Writing File]'
SAVEDMSG	db	'[File Saved]'
AskFile		db	'WRITE FILE <CR>:'
ConfirmMsg	db	'! CONFIRM WITH CTL-Y !'
NOTCONFIRMED	db	'*** NOT CONFIRMED ***'
WrErrMsg	db	'*** No Filename ***'

PStart		dw	100h
PEnd		dw	101h

;---------------------------------------------------------------------------
Ctrl_X_Sequence	PROC	Near

	call	.CAPS

	cmp	AL, 'z'
	ja	CXInvalid1
	
CXParse:xor	AH, AH			; clear insignificant
	add	AX, AX			; dw index
	mov	BX, AX			; get the index
	jmp	CS:CXJTable [BX]	; and jump

CXInvalid:
	shr	AL, 1
CXInvalid1:
	mov	CS:CXInvalidT1, AL
        mov     SI, Offset CXInvalidT0
        mov     CX, 23
        jmp     .Error0

Ctrl_X_Sequence	ENDP

;-----------------------------------------------------------------
DOSExit	PROC	NEAR

if Confirm
	mov	SI, Offset ConfirmMsg	; ask for CTL-Y confirmation for exit
	mov	CX, 22
	call	.Error1			; beep and display
DOS1:	call	.Inch			; get one character
	jz	 DOS1
	cmp	AL, 25			; is it CTL-Y
	je	FinalExit		; if so, we will soon die
	mov	SI, Offset NOTCONFIRMED	; no, then print an error message
	mov	CX, 21
	jmp	.Error0			; and exit
endif
FinalExit:
	mov	AH, 2			; set cursor position to print a nice
	mov	BH, 0			; exit message on leave.
	mov	DX, 23*256
	int	10h
	call	.CLRMsg
	mov	SI, Offset Bye
	mov	CX, 61
	call	.Msg			; and say bye

	mov	CS:L25Switch, 0		; don't know if this is necessary
	mov	CS:NoModeLine, TRUE
	call	LastLineUpdate
if noblockexit
	mov	CH, 6
	mov	CL, 7
	mov	AH, 1			; set the cursor to block via BIOS
	int	10h
endif
	int	20h			; and exit to DOS

DOSExit	ENDP

;---------------------------------------------------------------------------
SaveBuffer	PROC	Near

	mov	SI, Offset WRITINGMSG	; say "Saving Buffer"
	mov	CX, 14
	call	.Msg
	call	FSave			; call the routine that does it
	mov	SI, Offset SAVEDMSG	; and say you have finished
	mov	CX, 12
	jmp	.Msg

SaveBuffer	ENDP

;---------------------------------------------------------------------------
WriteBuffer	PROC	Near
	call	.CLRMsg			; ask for the filename
	mov	SI, Offset AskFile
	mov	CX, 16
	call	.Msg

	mov	SI, CX			; prepare to enter .Text
	add	SI, SI			; SI holds the start of the cursor
	add	SI, StartofMsgField	; on the screen
	mov	DL, CR			; end input with CR
	mov	DI, Offset BCB.File	; and put result to File field
	call	.Text

	cmp	BX, 0			; if we received 0 characters, too bad
	je	WrErr

	call	FSave			; and now save it with the new file
					; name already in our field
	mov	SI, Offset SAVEDMSG	; write [Saved]
	mov	CX, 12
	jmp	.Msg

WrErr:	mov	SI, Offset WrErrMsg	; sorry we received no characters
	mov	CX, 19
	jmp	.Error0

WriteBuffer	ENDP
;---------------------------------------------------------------------------
ExCursMark	PROC	Near

	mov	AX, DS:BCB.FCursor	; simply exchange cursor and mark
	xchg	AX, DS:BCB.Mark
	mov	DS:BCB.FCursor, AX
	ret

ExCursMark	ENDP

;----------------------------------------------------------------------
DefineMacro	PROC	NEAR

	cmp	CS:MacroDefinition, TRUE
	jne	DM1
	mov	SI, Offset MacroErr2
	mov	CX, 44
	jmp	.Error0
DM1:	mov	CS:Macrodefinition, TRUE	; signal start of definition
	mov	CS:Macptr, Offset Store		; this is the offset of field
	mov	CS:Macctr, 0			; number of characters
	mov	CS:MacBack, 0			; as well
	mov	SI, Offset MacMsg1
	mov	CX, 16
	jmp	.Msg

DefineMacro	ENDP

;---------------------------------------------------------------------------
EndDefineMacro	PROC	NEAR

	cmp	CS:Macrodefinition, FALSE
	jne	EDM1
	mov	SI, Offset MacroErr1
	mov	CX, 31
	jmp	.Error0
EDM1:	mov	CS:Macrodefinition, FALSE
	dec	CS:MacBack
	dec	CS:Macctr
	mov	SI, Offset MacMsg2
	mov	CX, 15
	jmp	.Msg

EndDefineMacro	ENDP

;---------------------------------------------------------------------------
InvokeMacro	PROC	NEAR

	cmp	CS:$Repeat, 0
	je	IM1
		mov	AX, CS:$Repeat
		mov	CS:MacArg, AX
		mov	CS:$Repeat, 0
IM1:	cmp	CS:Macrodefinition, TRUE
	je	IMError
	mov	AL, CS:MacBack
	mov	CS:MacCtr, AL
	mov	CS:MACptr, Offset Store
	mov	CS:MacroInvocation, TRUE
	mov	SI, Offset MacMsg3
	mov	CX, 15
	call	.Msg
	ret
IMError:mov	SI, Offset MacroErr3
	mov	CX, 23
	jmp	.Error0

InvokeMacro	ENDP
;---------------------------------------------------------------------------
LocMsg		db	'[at Byte '
Location	db	'0000'
		db	']'

WhereamI	PROC	NEAR

	mov	BX, DS:BCB.FCursor
	sub	BX, 100h
	call	WhereSUB
	mov	SI, Offset LocMsg
	mov	CX, 14
	jmp	.Msg

WhereamI	ENDP
;---------------------------------------------------------------------------
WhereSub	PROC	NEAR
	mov	DI, Offset Location

	mov	AL, BH
	and	AL, 11110000b		; digit 1
	shr	AL, 1
	shr	AL, 1
	shr	AL, 1
	shr	AL, 1
	call	WFormat
	mov	CS:[DI], AL
	inc	DI

	mov	AL, BH			; digit 2
	and	AL, 00001111b
	call	WFormat
	mov	CS:[DI], AL
	inc	DI

	mov	AL, BL			; digit 3
	and	AL, 11110000b
	shr	AL, 1
	shr	AL, 1
	shr	AL, 1
	shr	AL, 1
	call	WFormat
	mov	CS:[DI], AL
	inc	DI

	mov	AL, BL			; digit 4
	and	AL, 00001111b
	call	WFormat
	mov	CS:[DI], AL
	inc	DI
	ret
WFormat	PROC	NEAR
	cmp	AL, 9
	ja	Letter
Number:	add	AL, '0'
	jmp	WMerge
Letter:	add	AL, 'A'-10
WMerge:	ret
Finished:ret

WFormat	ENDP
Wheresub	ENDP
db ' createmap   '
;---------------------------------------------------------------------------
CreateMap	PROC	NEAR

	call	.CLRMsg
	mov	SI, Offset ConfirmMsg1
	mov	CX, 48
	call	.Msg
	call	Sound

CWait:	call	.Inch
	jz	CWait

	cmp	AL, 25			; ^Y
	je	CMOK
	mov	SI, Offset NotConfirmed
	mov	CX, 21
	jmp	.Error0

CMOK:	mov	CX, DS:BCB.FEnd
	sub	CX, 100			; do in entire file

	mov	SI, 0FFh

UntilEof:
	mov	AX, 00

CSLoop:	inc	SI
	cmp	Byte Ptr DS:[SI], newpage
	loopne	CSLoop

	call	.Inch
	jnz	Finished

	cmp	SI, DS:BCB.FEnd
	jae	Finished
	cmp	CX, 10
	je	Finished

	mov	BX, SI
	sub	BX, 2
	sub	BX, 100h
	call	WhereSub

	mov	BX, CS:$KBufPtr		; put up the name
	inc	SI

MAg:	mov	AL, DS:[SI]		; get a char from the name
	inc	SI
	cmp	AL, NUL
	je	Nametransferred
	mov	CS:[BX], AL		; and save it
	inc	BX
	jmp	MAg
Nametransferred:
	mov	Byte Ptr CS:[BX], 9		; a tab
	inc	BX
	push	SI
	mov	SI, Offset Location	; now the location
	mov	AX, CS:[SI]
	add	SI, 2
	mov	CS:[BX], AX
	add	BX, 2
	mov	AX, CS:[SI]
	mov	CS:[BX], AX
	add	BX, 2
	pop	SI

	mov	CS:$KBufPtr, BX
	push	SI
	push	CX

	call	BufToggle

	call	.Piss

	call	InsertCRLF

	call	BufToggle

	pop	CX
	pop	SI
	add	SI, 5
	jmp	UntilEOF

NodeName	dw	5 dup ('$')
CreateMap	ENDP
;---------------------------------------------------------------------------
FillDefault	equ	75
MaxFillColumn	equ	255
MinFillColumn	equ	25
FillColumn	dw	FillDefault

SetFillColumn	PROC	Near
	mov	AX, CS:$Repeat
	cmp	AX, 0
	je	SFCDefault
	cmp	AX, MaxFillColumn
	ja	SFCWrong
	cmp	AX, MinFillCOlumn
	jb	SFCWrong
	mov	CS:FillColumn, AX
	mov	CS:$Repeat, 0
	mov	SI, Offset TellFill
	mov	CX, 17
	jmp	.Msg
SFCDefault:
	mov	CS:FillColumn, FillDefault
	mov	SI, Offset TellFillDefault
	mov	CX, 31
	jmp	.Msg
SFCWrong:
	mov	SI, Offset InvalidFillCOlumn
	mov	CX, 31
	jmp	.Error0


SetFillColumn	ENDP

	PROGRAM	ENDS
END
