;..................................................................
;
;  File:        B5MEINIT.ASM
;  Written by:  Kevin Murphy / Tim Gary
;  Date:        10/02/85
;  Based on:    MEINIT.ASM
;  Written by:  Tim Gary
;
;  This routine will pass a number of useful pieces of information
;  from METAL (131XX28 or later) to BYE (501 or later)
;  This is done via the extended BDOS calls in the latest versions of BYE.
;  The data is proccessed and transfered to the LCDATA buffer in BYE.
;      >>>> Thanks to Tim Gary, a real gem of an idea <<<<
;
;  1) Edit your BYE equates as follows
; 
;  ->NO25TH 	EQU	YES
;  ->READLC     EQU	NO
;
;  ->Now reassemble BYE, the rest is up to METAL
;
;  2) What info is passed ?
;
;   - Users first and last name
;   - Users stataus level (+,s,n,x,X,a,b,c)
;   - Users password
;   - Users location (city & state)
;     (these 4 will be displayed by the ^W in bye now)
;   - Max-time allowed on system is written into BYE, so that the Max-time
;     you set in METAL is also true in BYE
;   - User number, the user number is passed to BYE via locations
;     LCDATA + 76, and LCDATA + 77. They may be read in bye or an 
;     application program to ease file ops and so on   
;   - also notice that I clear the KMODEM/XMODEM upload/download counters
;..............................................................................
;
;  Installing B5MEINIT.....
;
;  Use ASM or another to create a hex file.
;
;  Then.......
;  
;  DDT METAL.COM
;  -IB5MEINIT.HEX
;  -R
;  -^C 
;  SAVE xx METAL.COM
;
;.............................................................................
; 
;
;  File: MEINIT.ASM
; 
;  This file can be used as a starting point for an initialization
; routine file Metal/Z-Msg versions 1.31 and later..
;
;  This is an entirely optional insert file.
;
;  An initialization routine is handy for setting up other remote
; access system programs (eg. bye).  The following information is
; passed to this routine from the message system:
;
;	. Whether or not BYE is active
;	. a pointer to the 'user structure' which contains the user
;	  name, where they are from, etc..
;	. a pointer to the 'user status' parameter block coresponding
;	  to the current user.  This will give things like the max
;	  amount of time allowed on the system, max user, max drive, etc..
;
;   The init routine is called after the user name and password have
; been verified by the system.
;
; *** This routine must not excede 251 bytes in length ***
;				   ===

	org	384h		; fixed location to put it at..

	db	0ffh		; flag to tell message system init routine
				; is installed...
bye:	db	00		; passed flag if bye is active..
user:	dw	0000		; pointer to user structure
status:	dw	0000		; pointer to user status info
	db	00,00,00,00,00,00	; reserved for later..

; The following are offsets from 'user' above

unumber	equ	0	; user number (also seek pos into users file) (2 bytes)
ufirst	equ	2	; first name of user          (0 terminated string)
ulast	equ	17	; last name of user           (0 terminated string)
upass	equ	38	; password                    (0 terminated string)
udate	equ	47	; date last logged on         (0 terminated string)
utime	equ	56	; time last logged on         (0 terminated string)
ucity	equ	65	; city of user                (0 terminated string)
ulastrd	equ	94	; message at last login               (2 bytes)
ustatus	equ	96	; user status character (+snXxabc)    (1 byte)
ujmpos	equ	99	; auto jump to OS on login? ('1'=yes) (1 byte)
ubell	equ	101	; bell enabled? ('1'=yes)             (1 byte)
urp	equ	102	; auto read on login? ('1'=yes)       (1 byte) 
unulls	equ	104	; nulls                               (1 byte)
uheight	equ	105	; terminal height                     (1 byte)
uwidth	equ	106	; terminal width                      (1 byte)
uupload	equ	109	; upload file count   (2 byte) --not used yet--
udnload	equ	111	; download file count (2 byte) --not used yet--
umins	equ	113	; minutes on today    (1 byte) --not used yet--
ucalls	equ	117	; unsigned number of calls            (2 byte)
udef	equ	124	; You can actually use these locs..   (124-127)

; The following offsets are from 'status' above...

sstatus	equ	0	; status char (+snXxabc)
smaxdrv	equ	1	; max drive
smaxusr	equ	2	; max user
sacttout equ	3	; activity timeout in mins (timeout if not typing)
skillflg equ	4	; kill messages flag..
szcprflg equ	5	; wheel privs?
sreadprv equ	6	; read private msgs?
spostmsg equ	7	; allowed to post messages?
stimeout equ	8	; logoff timeout in minutes
sz3flags equ	9	; 2 byte commands file flag (zcpr3 only)

; --------
; B5MEINIT special equates..
; --------
;........................
; these constants never change..
;
NO	EQU	0
YES	EQU	NOT NO
;
BDOS	  EQU	0005	; define the BDOS jump
;
GETLCDATA EQU	80	; bye bdos code to get pointer to lcdata
SETMAXTIM EQU	81	; bye set max time
;
;........................
; 
KMD	 EQU	YES	; yes if useing kmd upload/download counters
;
UPLOAD	 EQU	0054h	; location of kmd/xmodem upload counter
DOWNLOAD EQU	0055h	; location of kmd/xmodem download counter
;
;
; end of equates
;
;........................
; Start of the code...

	PUSH	H		;save everything, cause Tim says so
	PUSH	D		;better safe than sorry
	PUSH	B
	PUSH	PSW

;
;
;..............................
; make sure BYE is home
; we use this method to insure that we have BYE501 or later/else BYE337 or
; later.....else this is all going to barf !!!
;
	MVI	E,241		;Use extended BDOS check
	MVI	C,32		;ask for user #241
	CALL	BDOS
	CPI	77		;are we alive in BYE ?
	JNZ	METOUT		;nope, oopps... exit
;
;
;.............................
;
	
	MVI	C,GETLCDATA	;get LCDATA address from BYE
	CALL	BDOS	

	MOV	A,M		;get the first character
	CPI	' '		;is it a space
	JNZ	METOUT		;nope... we have been here before.. exit

	XCHG			;swap the LCDATA pointer into DE

	LHLD	USER	
	LXI	B,UFIRST	; point to first name
	DAD	B		; add offset to user pointer
	CALL	REDO		; copy it into buffer, and add ending space

	LHLD	USER		; get user pointer again
	LXI	B,ULAST		; and copy over last name..
	DAD	B
	CALL	REDO
;
;
;..............................
; enclose the users status symbol in
; "( )" so it is real pretty
;
	XCHG			; get current lcdata location into HL
	MVI	M,' '		; insert a space in the proccessed data
	INX	H		; goto next position

	MVI	M,'('		; insert "(" 
	INX	H
	XCHG			; put current lcdata pos back into DE
	
	LHLD	USER		; get user pointer again
	LXI	B,USTATUS	; offset to status char
	DAD	B

	MOV	A,M		;put the character in reg A, this is the
				;users status character 

	XCHG			; get current lcdata into HL again..
	MOV	M,A		; insert stat char
	INX	H

	MVI	M,')'		;insert ")"
	INX	H

	MVI	M,' '		; add a space
	INX	H

	MVI	M,'-'		;inerst a dash to seperate status from password
	INX	H

	MVI	M,' '
	INX	H
	XCHG			; current lcdata back to DE
	
	LHLD	USER
	LXI	B,UPASS		; point to the password
	DAD	B
	CALL	REDO		; and copy it over

; Make things pretty...

	XCHG			; current lcdata pointer back to HL
	MVI	M,' '
	INX	H

	MVI	M,'-'
	INX	H

	MVI	M,'>'
	INX	H

	MVI	M,' '
	INX	H
	XCHG			; current lcdata back to DE..

	LHLD	USER
	LXI	B,UCITY		; point to city..
	DAD	B
	CALL	REDO		; and copy it over..

	XRA	A		; clear a (null)
	STAX	D		; save it into current lcdata pointer

;
;
;...........................
;
; put the user number in the last 2 bytes of LCDATA buffer
; protect it with a leading null
;
; We do this last incase it was a long one and it took up
; our space, we'll just over write, and cut of the who data
;

	MVI	C,GETLCDATA	;get LCDATA address again
	CALL	BDOS

	LXI	B,75		; point to 75 bytes into the lcdata area
	DAD	B
	MVI	M,0		; put a NULL at lcdata+75
	INX	H

	XCHG			; DE now has pointer to lcdata+75

	LHLD	USER		; get pointer to user number
	MOV	A,M		; get user number (1st byte)
	STAX	D		; these go into lcdata+76....
	INX	D
	INX	H
	MOV	A,M		; get second byte of user number
	STAX	D
;
;
;............................
;
; set max time allowed on system
;
	LHLD	STATUS		; get pointer to user status area
	LXI	B,STIMEOUT	; point to timeout in minutes
	DAD	B
	MOV	E,M		; and put in e

	MVI	C,SETMAXTIM	; use extended BDOS to set the max time allowed
	CALL	BDOS
;
;
;................................
;
; zero the KMODEM/XMODEM upload/download counters
	
	 IF	KMD		; if KMD  counters are used

	XRA	A		;zero out A reg
	STA	UPLOAD		;zero the upload counter
	STA	DOWNLOAD	;zero the download counter

	 ENDIF

	JMP	METOUT		;thats it so exit back to real METAL
;
;
;..........................
;
REDO:
	MOV	A,M		;get a character from the metal buffer
	ORA	A		; is it a null???
	JZ	SPNXT		;yep.. insert a space and return to sender
	STAX	D		;nope, then put it in the LCDATA buffer
	INX	D		;advance the pointer for LCDATA
	INX	H		;advance the pointer for METAL	
	JMP	REDO		;else keep looping	
;
;
;.............................
;
SPNXT:
	MVI	A,' '		;put a space in reg A
	STAX	D		;insert it in the LCDATA buffer
	INX	D		;advance the LCDATA pointer
	RET			;return to sender
;
;
;..............................
;
METOUT:	

	POP	PSW		;restore everything
	POP	B
	POP	D
	POP	H

;
;
;..............................
;
	RET		; simple return ends routine

;   The RET (above) is the last byte of the routine
;   and it's address must be 047fh or less ----
;   (you can TYPE the B5MEINIT.PRN file after assembley
;   to check this)
;
;   END  of B5MEINIT.ASM    
;...............................
;