; AT&T dialer, by The Brain, 7-2-93, +31-74-425982
;
;     >>> DON'T SPREAD IT TO THE LAMERS! <<<
;
; Okay, now for the coders looking at this piece of shit...
; I did this one in just one day (a coded one before but it used keyboard
; stuffing and very long dial command which some programm did not like
; at all and some modems didn't catch the long dial string).
; It's a real messy due to this. 
; I used BIOS int 10h everywhere for screen control (YUUUUCK!) to get it
; working with DESQVIEW or any other programm having troubles with direct
; screen writes or register access.
; Hope ya like it, wait for more nice Brain stuff comin' up!
; Whah.... i spend a day on debugging!!! Aargh
;
		code	segment
		org	100h
		assume	cs:code, ds:code, es:code, ss:code
Start:		jmp	GoInit

IdString	db	'AT&T'			; ID-string of TSR
DataFile	db	80 dup(?)		; Full path/file of 'DIAL.DAT'
StringOK	db	2,'OK'			; 'OK' for waiting (^M)
AbortString	db	0			; Send when pressed Enter 2*
OldPos		dw	?			; Cursor position before TSR
OldShape	dw	?			; Cursor shape before TSR
OldScreen	dw	80*25 dup(?)		; Screen contents
ReceivePos	dw	?			; Cursor pos. in receive window
ReceiveBuf	db	20 dup(0)		; Last 20 received characters
SendPtr		dw	0			; Pointer dial-string (0=stop)
SendSub		dw	0			; Pointer sub-string (0=stop)
SendLineAdr	dw	?			; Address of entry to dial
SendCardAdr	dw	?			; Address of card to use
ComSaveLine	db	?			; Comport status before TSR

; Following data is stored in DIAL.DAT file
;
DataStart:
ComPort		dw	0			; 0=COM1, 1=COM2...
CardCur		db	1			; Current card
DialCur		db	1			; Position in dial list
DialOfs		db	0
ModemString	db	'ATDT06-022911,,,,,,,,'	; Dial string :
		db	';^MATDT^1#,^2#,,^M',0	; '^M' = send CR, wait for OK
						; '^1' = send choosen number
						; '^2' = send card number
		org	offset ModemString+60	; Buffer = 60 characters
CardList	db	10*20 dup(0)		; 10 card numbers
DialList	db	256*70 dup(0)		; board names/nubers/comments
DialLast	equ	$-70
DataSize	equ	$-offset DataStart	; Size of the data file

; Yoho, just try +31-74-425982

SaveOk		db	28,12,23,1,2Eh
		db	' DATA FILE IS SAVED... '

SaveErr		db	24,12,32,1,4Eh
		db	'>> ERROR WRITING DATA FILE!!! <<'

ModemScreen	db	9,8,62,7,1Bh
		db	'ЪДДДДДДДДДДДДДДДДДДДД[',7,'Enter modem string',11,']ДДДДДДДДДДДДДДДДДДДДї'
		db	'і                                                            і'
		db	'ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ'
		db	'і A ^M is replaced by a CR and the dialer will wait for a    і'
		db	'і OK-string. ^1 is replaced by the selected telephone number.і'
		db	'і ^2 is replaced by the current card number and pin.         і'
		db	'АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ'
		
CardScreen	db	28,6,25,13,1Bh
		db	'ЪДДВДДД[',7,'Card List',11,']ДДДДДДї'
		db	'і',14,'Nr',11,'і',14,'  Card/Pin number   ',11,'і'
		db	'і01і                    і'
		db	'і02і                    і'
		db	'і03і                    і'
		db	'і04і                    і'
		db	'і05і                    і'
		db	'і06і                    і'
		db	'і07і                    і'
		db	'і08і                    і'
		db	'і09і                    і'
		db	'і10і                    і'
		db	'АДДБДДДДДДДДДДДДДДДДДДДДЩ'

DialScreen	db	1,3
		db	78,19,1Bh
		db	'ЪДДДВДДДДДДДДДДДДДДДДДДДДДД[',7,'Dial List by The Brain',11,']ДДДДДВДДДДДДДДДДДДДДДДДДДДї'
		db	'і',14,'Nr.',0Bh,'і',14,'           Board Name         ',11,'і',14,'       Number       ',11,'і',14,'      Comment       ',11,'і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
		db	'і   і                              і                    і                    і'
Line0		db	'ГДДДБДДДДДДДДДДДДДДДДДДДДДДДДДД[',7,'Modem Input, COM'
ComText		db	'1:',11,']ДДДДДБДДДДДДДДДДДДДДДДДДДДґ'
Line1		db	'і                                                                            і'
LineSize	equ	$-offset Line1
Line2		db	'і                                                                            і'
Line3		db	'і                                                                            і'
		db	'АДДДДДДДДДДД '
		db	'[',14,'C',11,']',15,'ards',         11,' / '
		db	'[',14,'E',11,']',15,'dit',          11,' / '
		db	'[',14,'M',11,']',15,'odem command', 11,' / '
		db	'[',14,'P',11,']',15,'ort',          11,' / '
		db	'[',14,'S',11,']',15,'ave',          11,' '
		db	'ДДДДДДДДДДДЩ'
		
		; [C]ards / [E]dit / [M]odem command / [P]ort / [S]ave


MyInt8:		pushf
		db	09Ah
OldInt8		dw	?,?
		cmp	cs:Bussy,1
		je	MyInt8A
		push	ax ds
		xor	ax,ax
		mov	ds,ax
		mov	al,ds:[417h]
		and	al,0Eh
		cmp	al,0Eh
		pop	ds ax
		je	DoeUtil
MyInt8A:	iret
Bussy		db	0


DoeUtil:	mov	cs:Bussy,1
		push	ax bx cx dx
		push	si di ds es
		push	bp
		sti
		mov	al,20h
		out	20h,al
		call	GoTSR
		pop	bp
		pop	es ds di si
		pop	dx cx bx ax
		mov	cs:Bussy,0
		iret


; TSR initialisation
;
GoTSR:		push	cs cs			; DS,ES = CS
		pop	ds es
		mov	ah,0Fh			; Only in screem mode 2/3
		int	10h
		cmp	al,3
		je	GoTSR1
		cmp	al,2
		je	GoTSR1
		ret
GoTSR1:		mov	ah,3			; Store cursor location and
		xor	bh,bh			; cursor shape
		int	10h
		mov	OldShape,cx
		mov	OldPos,dx
		mov	ch,20h			; Cursor off
		mov	ah,1
		int	10h
		mov	di,offset OldScreen	; Store screen data
		xor	bh,bh
		xor	dx,dx
		mov	cx,25
GoTSR2:		push	cx dx
		mov	cx,80
GoTSR3:		mov	ah,2
		int	10h
		mov	ah,8
		int	10h
		stosw
		inc	dl
		loop	GoTSR3
		pop	dx cx
		inc	dh
		loop	GoTSR2
		call	ComCapture
		call	Main			; Go for it
		call	ComRelease
		mov	si,offset OldScreen	; Restore screen data
		xor	bh,bh
		xor	dx,dx
		mov	cx,25
GoTSR4:		push	cx dx
		mov	cx,80
GoTSR5:		push	cx
		mov	ah,2
		int	10h
		lodsw
		mov	bl,ah
		mov	ah,9
		mov	cx,1
		int	10h
		inc	dl
		pop	cx
		loop	GoTSR5
		pop	dx cx
		inc	dh
		loop	GoTSR4
		mov	cx,OldShape		; Restore cursor shape
		mov	ah,1
		int	10h
		mov	dx,OldPos		; Restore cursor position
		xor	bh,bh
		mov	ah,2
		int	10h
		ret


; Disable interrupt from COM-port ---------------------------------------------
;
ComCapture	proc	near
		push	ax dx
		call	ComPortIO
		jc	ComCapture1		; Quit => not connected!
		inc	dx			; Disable interrupt from port
		xor	al,al
		out	dx,al
ComCapture1:	pop	dx ax
		ret
ComCapture	endp


; Enable interrupt from COM-port ----------------------------------------------
;
ComRelease	proc	near
		push	ax dx
		call	ComPortIO
		jc	ComRelease1		; Quit => not connected!
		inc	dx			; Enable interrupt from port
		mov	al,0Fh
		out	dx,al
ComRelease1:	pop	dx ax
		ret
ComRelease	endp


; Get COM port I/O adress -----------------------------------------------------
; output:	CF=1 => not available
;
ComPortIO	proc	near
		push	bx ds
		mov	bx,40h
		mov	ds,bx
		mov	bx,cs:ComPort
		shl	bx,1
		mov	dx,[bx]
		cmp	dx,1
		pop	ds bx
		ret
ComPortIO	endp


ComSend		proc	near
		push	cx dx
		call	ComPortIO
		jc	ComSend2
		push	ax
		add	dx,5			; Send request to send
		xor	cx,cx
ComSend1:	jmp	$+2
		jmp	$+2
		in	al,dx
		test	al,20h
		loopz	ComSend1
		pop	ax
		sub	dx,5
		out	dx,al
ComSend2:	pop	dx cx
		ret
ComSend		endp
	
	
ComReceive	proc	near
		push	cx dx
		call	ComPortIO
		jc	ComReceive2
		add	dx,5			; DTR
		in	al,dx
		test	al,1
		stc
		jz	ComReceive2
		sub	dx,5
		in	al,dx
ComReceive2:	pop	dx cx
		ret
ComReceive	endp
	

; Update lower part of dial window --------------------------------------------
;
UpdateLower	proc	near
		push	ax bx cx dx si
		mov	ah,3
		xor	bh,bh
		int	10h
		push	dx
		mov	dx,word ptr DialScreen
		add	dh,14
		mov	cx,044Eh
		mov	ah,DialScreen[4]
		mov	si,offset Line0		
UpdateLower1:	push	cx dx
		xor	ch,ch
UpdateLower2:	lodsb
		cmp	al,32
		jae	UpdateLower3
		and	ah,0F0h
		or	ah,al
		lodsb
UpdateLower3:	call	ShowChar
		loop	UpdateLower2
		pop	dx cx
		inc	dh
		dec	ch
		jnz	UpdateLower1
		pop	dx
		mov	ah,2
		xor	bh,bh
		int	10h
		pop	si dx cx bx ax
		ret
UpdateLower	endp


; Scroll receive window up ----------------------------------------------------
; input:	none
; output:	none
; modified:	AX, CX, SI, DI, flags
;
ScrollUp	proc	near
		push	ax cx si di
		mov	di,offset Line1
		mov	si,offset Line2
		mov	cx,2
ScrollUp1:	inc	si
		inc	di
		push	cx
		mov	cx,LineSize-2
		rep	movsb
		pop	cx
		inc	si
		inc	di
		loop	ScrollUp1
		inc	di
		mov	al,' '
		mov	cx,LineSize-2
		rep	stosb
		mov	dx,0200h
		pop	di si cx ax
		ret
ScrollUp	endp


; Send character to receive window --------------------------------------------
; input:	AL = character
; output:	none
; modifed:	...
;
MonitorChar	proc	near
		push	ax bx cx dx si di
		mov	si,offset ReceiveBuf+1	; Flush in buffer
		mov	di,offset ReceiveBuf
		mov	cx,19
		rep	movsb
		stosb
		push	ax
		mov	dx,ReceivePos		; [SI] = cursor position
		mov	al,LineSize		; DX = cursor location
		mul	dh
		add	al,dl
		adc	ah,0
		mov	si,ax
		add	si,offset Line1+1
		pop	ax
		cmp	al,13
		jne	MonitorChar1
		xor	dl,dl
		jmp	MonitorChar9
MonitorChar1:	cmp	al,10
		jne	MonitorChar3
MonitorChar2:	inc	dh
		cmp	dh,3
		jb	MonitorChar9
		call	ScrollUp
		jmp	MonitorChar9
MonitorChar3:	mov	[si],al
		inc	dl
		cmp	dl,LineSize-2
		jb	MonitorChar9
		xor	dl,dl
		jmp	MonitorChar2
MonitorChar9:	mov	ReceivePos,dx
		call	UpdateLower
		pop	di si dx cx bx ax
		ret
MonitorChar	endp


; Check presence of string in receive buffer ----------------------------------
; input:	DS:SI = string
; output:	zf=1 => found in receive buffer
;
TestString	proc	near
		push	cx si di
		mov	cl,[si]
		xor	ch,ch
		inc	si
		mov	di,offset ReceiveBuf+20
		sub	di,cx
		repe	cmpsb
		pop	di si cx
		ret
TestString	endp


; Handle receiving data -------------------------------------------------------
;
DoReceive	proc	near		
		call	ComReceive
		jc	DoReceive1
		call	MonitorChar
DoReceive1:	ret
DoReceive	endp


; Handle command sending ------------------------------------------------------
;
DoSending	proc	near
		mov	si,SendPtr		; Command available
		or	si,si
		jz	DoSending5
		cmp	[si],'1^'		; ^1 => send number to call
		jne	DoSending3
		mov	si,SendSub
		or	si,si
		jne	DoSending1
		mov	si,SendLineAdr
		add	si,30
DoSending1:	lodsb
		or	al,al
		jnz	DoSending2
		mov	SendSub,0
		add	SendPtr,2
		ret
DoSending2:	mov	SendSub,si
		call	ComSend
		ret
DoSending3:	cmp	[si],'2^'		; ^2 => send card/pin
		jne	DoSending4
		mov	si,SendSub
		or	si,si
		jne	DoSending1
		mov	si,SendCardAdr
		jmp	DoSending1
DoSending4:	cmp	[si],'M^'		; ^M => send CR and wait 'OK'
		jne	DoSending7
		cmp	SendSub,0
		jne	DoSending6
		mov	SendSub,1
		mov	al,13
		call	ComSend
DoSending5:	ret
DoSending6:	mov	si,offset StringOK
		call	TestString
		jne	DoSending5
		mov	SendSub,0
		add	SendPtr,2
		ret
DoSending7:	cmp	byte ptr [si],0		; 0 => stop sending
		jne	DoSending8
		mov	SendPtr,0
		mov	al,13
		call	ComSend
		ret
DoSending8:	lodsb				; Send next character
		mov	SendPtr,si
		call	ComSend
		ret
DoSending	endp		
		

; Read key with COM-port watching ect -----------------------------------------
;
ReadKey		proc	near
		push	bx cx dx si di
		call	DoReceive		; Receive characters
		call	DoSending		; Send command
		pop	di si dx cx bx
		mov	ah,1			; Key pressed?
		int	16h
		jz	ReadKey			; No => wait
ReadKey1:	mov	ah,0			; Get key (wait for it)
		int	16h
		ret
ReadKey		endp
		

; Show character and increment DL ---------------------------------------------
; input:	DL,DH = location
;		AL    = character
;		AH    = attribute
; output:	DL+1
; modified:	nothing
;
ShowChar	proc	near
		push	ax bx cx
		push	ax
		mov	ah,2
		xor	bh,bh
		int	10h
		pop	ax
		mov	bl,ah
		mov	ah,9
		mov	cx,1
		int	10h
		pop	cx bx ax
		inc	dl
		ret
ShowChar	endp


; Show ASCIIZ string with fixed display length --------------------------------
; Input:	DS:SI = ASCIIZ string
;		CX    = length
;		DL,DH = position
;		AH    = attribute
; Output:	SI+CX, DL+CX
; Modified:	AL, flags
;
ShowASCIIZ	proc	near
		push	cx si
ShowASCIIZ1:	lodsb
		cmp	al,1
		sbb	si,0
		call	ShowChar
		loop	ShowASCIIZ1
		pop	si cx
		add	si,cx
		ret
ShowASCIIZ	endp


;		DX = string-positie
;		SI = string-adres
;		BP = maximum length
;		BX = huidige adres
;		AX = toets


EditKeys:	cmp	ax,4B00h	; [Left]
		je	EditLeft
		cmp	ax,4D00h	; [Right]
		je	EditRight
		cmp	ax,5300h	; [Del]
		je	EditDel
		cmp	ax,5200h	; [Ins]
		je	EditIns
		cmp	ax,4700h	; [Home]
		je	EditHome
		cmp	ax,4F00h	; [End]
		je	EditEnd
		cmp	al,8		; [BackSpace]
		jne	EditKeys1
		call	EditLeft
		jmp	EditDel
EditKeys1:	cmp	al,32		; Insert character
		jb	EditKeys2
		push	ax
		call	EditIns
		pop	ax
		mov	[bx],al
		jmp	EditRight
EditKeys2:	ret

		; [Left]
EditLeft:	cmp	si,bx
		sbb	bx,0
		ret

		; [Right]
EditRight:	mov	ax,si
		add	ax,bp
		dec	ax
		cmp	bx,ax
		jae	EditRight1
		cmp	byte ptr [bx],0
		je	EditRight1
		inc	bx
EditRight1:	ret

		; [Ins]
EditIns:	push	si
		mov	cx,si
		add	cx,bp
		sub	cx,bx
		add	si,bp
		mov	di,si
		dec	di
		sub	si,2
		std
		rep	movsb
		cld
		mov	byte ptr [bx],' '
		pop	si
		ret

		; [Del]
EditDel:	push	si
		mov	cx,si
		add	cx,bp
		sub	cx,bx
		mov	si,bx
		mov	di,si
		inc	si
		rep	movsb
		dec	di
		xor	al,al
		stosb
		pop	si
		ret
		
EditHome:	mov	bx,si
		ret
		
EditEnd:	mov	bx,si
		dec	bx
		mov	cx,bp
EditEnd1:	inc	bx
		cmp	byte ptr [bx],0
		loopnz	EditEnd1
		ret

; input:	DS:SI = string
;		BP    = maximum length
;		DL,DH = display position
;
EditASCIIZ	proc	near
		push	dx
		mov	ah,3
		int	10h
		pop	dx
		push	cx
		mov	ah,1
		mov	cx,0607h
		int	10h
		call	EditEnd
EditASCIIZ2:	push	bx dx si		; Show string and cursor
		sub	bx,si
		mov	cx,bp
		mov	ah,0Fh
		call	ShowASCIIZ
		add	dx,bx
		sub	dx,bp
		mov	ah,2
		xor	bh,bh
		int	10h
		pop	si dx bx
		call	ReadKey			; Read key
		push	ax
		call	EditKeys
		pop	ax
		cmp	al,13
		je	EditASCIIZ3
		cmp	al,27
		jne	EditASCIIZ2
EditASCIIZ3:	pop	cx
		push	ax
		mov	ah,1
		int	10h
		push	si
		mov	cx,bp
		mov	ah,30h
		call	ShowASCIIZ
		sub	dx,bp
		pop	si
		pop	ax
		cmp	al,27
		ret
EditASCIIZ	endp


; Show window to screen -------------------------------------------------------
; input:	DS:SI = window data
; output:	nothing
; modified:	AX, BX, CX, DX
;
ShowScreen	proc	near
		mov	dx,[si]
		mov	cx,[si+2]
		mov	ah,[si+4]
		xor	bh,bh
		add	si,5
ShowScreen1:	push	cx dx
		xor	ch,ch
ShowScreen2:	lodsb
		cmp	al,32
		jae	ShowScreen3
		and	ah,0F0h
		or	ah,al
		lodsb
ShowScreen3:	call	ShowChar
		loop	ShowScreen2
		pop	dx cx
		inc	dh
		dec	ch
		jnz	ShowScreen1
		ret
ShowScreen	endp		


; Show current dial list ------------------------------------------------------
;
ShowList	proc	near
		mov	al,70
		mul	DialOfs
		add	ax,offset DialList
		mov	si,ax
		mov	bl,DialOfs
		mov	cx,12
		mov	dx,word ptr DialScreen	; DX = cursor loc of first nr.
		add	dx,201h				
ShowList1:	mov	al,13
		sub	al,cl
		cmp	al,DialCur
		mov	bh,1Bh
		jne	ShowList2
		mov	bh,30h
ShowList2:	push	cx dx
		mov	al,bl			; Show number
		xor	ah,ah
		mov	cx,640Ah
		div	ch
		push	ax
		add	al,'0'
		mov	ah,bh
		call	ShowChar
		pop	ax
		mov	al,ah
		xor	ah,ah
		div	cl
		add	ax,'00'
		push	ax
		mov	ah,bh
		call	ShowChar
		pop	ax
		mov	al,ah
		mov	ah,bh
		call	ShowChar
		mov	al,'і'
		call	ShowChar
		mov	cx,30			; Show name
		mov	ah,bh
		call	ShowASCIIZ
		mov	al,'і'
		call	ShowChar
		mov	cx,20			; Show number
		call	ShowASCIIZ
		mov	al,'і'
		call	ShowChar
		mov	cx,20			; how comment
		call	ShowASCIIZ
		pop	dx cx
		inc	bl
		inc	dh
		loop	ShowList1
		ret
ShowList	endp


; Show card menu --------------------------------------------------------------
;
ShowCards	proc	near
		push	ax bx cx dx si
		mov	si,offset CardScreen
		call	ShowScreen
		mov	si,offset CardList
		mov	dx,word ptr CardScreen
		add	dx,201h
		mov	cx,10
		mov	bx,'01'
ShowCards1:	push	cx
		mov	ax,1B0Bh
		sub	al,cl
		cmp	al,CardCur
		jne	ShowCards2
		mov	ah,30h
ShowCards2:	mov	al,bh
		call	ShowChar
		mov	al,bl
		call	ShowChar
		mov	al,'і'
		call	ShowChar
		mov	cx,20
		call	ShowASCIIZ
		sub	dl,23
		pop	cx
		inc	bl
		cmp	bl,'9'
		jbe	ShowCards3
		inc	bh
		mov	bl,'0'
ShowCards3:	inc	dh
		loop	ShowCards1
		pop	si dx cx bx ax
		ret
ShowCards	endp	
		
CardEdit	proc	near
		call	ShowCards
		call	ReadKey
		cmp	ax,4800h		; [Up]
		jne	CardEdit1
		cmp	CardCur,2
		adc	CardCur,-1
		jmp	CardEdit
CardEdit1:	cmp	ax,5000h		; [Down]
		jne	CardEdit2
		cmp	CardCur,10
		adc	CardCur,0
		jmp	CardEdit
CardEdit2:	and	al,0DFh
		cmp	al,13			; [Enter] = [E]dit
		je	CardEdit3
		cmp	al,'E'
		jne	CardEdit4
CardEdit3:	mov	al,20
		mul	CardCur
		add	ax,offset CardList-20
		mov	si,ax
		mov	bp,20
		mov	dx,word ptr CardScreen
		add	dh,CardCur
		add	dx,104h
		call	EditASCIIZ
		jmp	CardEdit
CardEdit4:	cmp	al,27
		jne	CardEdit
		ret
CardEdit	endp




; Edit dial entry -------------------------------------------------------------
;
DialEdit:	mov	dx,word ptr DialScreen
		add	dx,105h
		add	dh,DialCur
		mov	al,DialOfs
		add	al,DialCur
		dec	al
		mov	ah,70
		mul	ah
		add	ax,offset DialList
		mov	si,ax
DialEdit1:	mov	bp,30
		call	EditASCIIZ
		je	DialEdit2
		add	si,30
		mov	bp,20
		add	dl,31
		call	EditASCIIZ
		je	DialEdit2
		add	si,20
		mov	bp,20
		add	dl,21
		call	EditASCIIZ
		je	DialEdit2
		sub	si,50
		sub	dl,52
		jmp	DialEdit1
DialEdit2:	ret
		; DX = pos, SI = adres
		
				
; Save data file --------------------------------------------------------------
;
SaveData	proc	near
		mov	dx,offset DataFile
		mov	ah,3Ch
		mov	cx,20h
		int	21h
		jnc	SaveData1
		mov	si,offset SaveErr
		call	ShowScreen
		jmp	ReadKey
SaveData1:	mov	bx,ax
		mov	dx,offset DataStart
		mov	cx,DataSize
		mov	ah,40h
		int	21h
		mov	ah,3Eh
		int	21h
		mov	si,offset SaveOk
		call	ShowScreen
		jmp	ReadKey
SaveData	endp


; Handle extended keys for dial list ------------------------------------------
;
DialExtend:	cmp	ah,72			; Up
		jne	DialExtend1
		dec	DialCur
		jnz	DialExtend8
		inc	DialCur
		cmp	DialOfs,1
		adc	DialOfs,-1
		jmp	DialExtend8
DialExtend1:	cmp	ah,80			; Down
		jne	DialExtend2
		inc	DialCur
		cmp	DialCur,12
		jbe	DialExtend8
		dec	DialCur
		cmp	DialOfs,256-12
		adc	DialOfs,0
		jmp	DialExtend8
DialExtend2:	cmp	ah,73			; PgUp
		jne	DialExtend3
		cmp	DialCur,1
		mov	DialCur,1
		jne	DialExtend8
		sub	DialOfs,11
		jnc	DialExtend8
		mov	DialOfs,0
DialExtend8:	ret
DialExtend3:	cmp	ah,81			; PgDn
		jne	DialExtend4
		cmp	DialCur,12
		mov	DialCur,12
		jne	DialExtend9
		add	DialOfs,11
		cmp	DialOfs,256-12
		jb	DialExtend9
		mov	DialOfs,256-12
		jmp	DialExtend9
DialExtend4:	cmp	ah,53h			; [Del]
		jne	DialExtend6
		mov	al,DialOfs
		add	al,DialCur
		dec	al
		mov	ah,70
		mul	ah
		mov	cx,255*70
		sub	cx,ax
		add	ax,offset DialList
		mov	di,ax
		mov	si,di
		add	si,70
		jcxz	DialExtend5
		rep	movsb
DialExtend5:	mov	cx,70
		xor	al,al
		rep	stosb
		jmp	DialExtend9
DialExtend6:	cmp	ah,52h			; [Ins]			
		jne	DialExtend9
		mov	al,DialCur
		add	al,DialOfs
		dec	al
		mov	ah,70
		mul	ah
		mov	cx,255*70
		sub	cx,ax
		add	ax,offset DialList
		std
		mov	di,offset DialList+256*70-1
		mov	si,offset DialList+255*70-1
		jcxz	DialExtend7
		rep	movsb
DialExtend7:	xor	al,al
		mov	cx,70
		rep	stosb
		cld
DialExtend9:	ret		
				
		
; Main TSR routine (dial list) ------------------------------------------------
;
Main		proc	near
		mov	SendPtr,0		; Cut of sending string
Main7:		mov	al,byte ptr ComPort
		add	al,'1'
		mov	ComText,al
		mov	si,offset DialScreen
		call	ShowScreen
Main1:		call	ShowList
Main2:		call	ReadKey
		cmp	al,0
		jne	Main3
		call	DialExtend
		jmp	Main1		
Main3:		cmp	al,'a'			; UpCase
		jb	Main4
		cmp	al,'z'
		ja	Main4
		sub	al,20h
Main4:		cmp	al,'P'			; [P]ort
		jne	Main5
		call	ComRelease		; Release current port
		inc	ComPort			; Next port (1,2,3,4)
		and	ComPort,3
		call	ComCapture		; Capture port again
		jmp	Main
Main5:		cmp	al,'E'			; [E]dit
		jne	Main6
		call	DialEdit
		jmp	Main1
Main6:		cmp	al,'C'			; [C]ards
		jne	Main9
		xor	al,al
		xchg	DialCur,al
		push	ax
		call	ShowList
		pop	ax
		mov	DialCur,al
		call	CardEdit
		jmp	Main7
Main9:		cmp	al,'M'			; [M]odem string
		jne	Main10
		xor	al,al
		xchg	DialCur,al
		push	ax
		call	ShowList
		pop	ax
		mov	DialCur,al
		mov	si,offset ModemScreen
		call	ShowScreen
		mov	si,offset ModemString
		mov	dx,word ptr ModemScreen
		add	dx,101h
		mov	bp,60
		call	EditASCIIZ
		jmp	Main7
Main10:		cmp	al,'S'			; [S]ave
		jne	Main11
		call	SaveData
		jmp	Main7
Main11:		cmp	al,13			; [Enter]
		jne	Main8
		cmp	SendPtr,0
		je	Main12
		mov	SendPtr,offset AbortString
		jmp	Main2
Main12:		mov	al,20
		mul	CardCur
		add	ax,offset CardList-20
		mov	SendCardAdr,ax
		mov	al,DialCur
		add	al,DialOfs
		dec	al
		mov	ah,70
		mul	ah
		add	ax,offset DialList
		mov	SendLineAdr,ax
		mov	SendPtr,offset ModemString
		mov	SendSub,0
		jmp	Main2
Main8:		cmp	al,27			; [Esc]
		je	Main999
		jmp	Main2
Main999:	ret

Main		endp
		

; Initialization --------------------------------------------------------------
;
GoInit:		mov	ax,3508h		; Get old INT 8 vector
		int	21h
		mov	OldInt8[0],bx
		mov	OldInt8[2],es
		cmp	es:IdString[0],'A'	; Install in not 'AT&T' loaded
		jne	GoInitLoad
		cmp	es:IdString[1],'T'
		jne	GoInitLoad
		cmp	es:IdString[2],'&'
		jne	GoInitLoad
		cmp	es:IdString[3],'T'
		jne	GoInitLoad
		lds	dx,dword ptr es:OldInt8	; Remove TSR from memory
		mov	ax,2508h
		int	21h
		mov	ah,49h
		int	21h
		push	cs			; 'Unloaded'
		pop	ds
		mov	dx,offset Unload
		mov	ah,9
		int	21h
		mov	ah,4Ch
		int	21h
GoInitLoad:	mov	es,cs:[2Ch]		; Find load-file (DIAL.COM)
		mov	di,1
		xor	ax,ax
GoInitLoad1:	dec	di
		scasw
		jne	GoInitLoad1
		add	di,2
		mov	si,di
		repne	scasb
		push	cs es
		pop	ds es
		mov	byte ptr [di-4],'D'	; Replace '.COM' by '.DAT'
		mov	byte ptr [di-3],'A'
		mov	byte ptr [di-2],'T'
		mov	di,offset DataFile
GoInitLoad3:	movsb				; Copy to file-buffer
		cmp	byte ptr [si-1],0
		jne	GoInitLoad3
		push	cs			; DS = CS
		pop	ds
		mov	dx,offset DataFile	; Try to open file
		mov	ax,3D00h
		int	21h
		jc	GoInitLoad4
		mov	bx,ax			; Read if succesfull
		mov	dx,offset DataStart
		mov	cx,DataSize
		mov	ah,3Fh
		int	21h
		mov	ah,3Eh
		int	21h
GoInitLoad4:	mov	dx,offset LoadOk	; 'OK'
		mov	ah,9
		int	21h
		mov	dx,offset MyInt8	; Revector interrupt
		mov	ax,2508h
		int	21h
		mov	dx,offset GoInit
		int	27h

Unload		db	'AT&T dialer disabled!',13,10,'$'
LoadOk		db	'AT&T dialer loaded!',13,10,'$'

		code	ends
		end	Start
		
		
