; LOGIN.ASM  (Retro Unix 8086 v1 - /bin/login)
; ----------------------------------------------------------------------------
;
; RETRO UNIX 8086 (Retro Unix == Turkish Rational Unix)
; Operating System Project (v0.1) by ERDOGAN TAN (Beginning: 11/07/2012) 
; Retro UNIX 8086 v1 - /etc/login file
;
; [ Last Modification: 04/11/2013 ]
;
; Derivation from UNIX Operating System (v1.0 for PDP-11) 
; (Original) Source Code by Ken Thompson (Bell Laboratories, 1971-1972)
;
; ****************************************************************************

; Derived from 'login.s' file of original UNIX v1

; LOGIN0.ASM, 27/10/2013

.8086

; UNIX v1 system calls
_rele 	equ 0
_exit 	equ 1
_fork 	equ 2
_read 	equ 3
_write	equ 4
_open	equ 5
_close 	equ 6
_wait 	equ 7
_creat 	equ 8
_link 	equ 9
_unlink	equ 10
_exec	equ 11
_chdir	equ 12
_time 	equ 13
_mkdir 	equ 14
_chmod	equ 15
_chown	equ 16
_break	equ 17
_stat	equ 18
_seek	equ 19
_tell 	equ 20
_mount	equ 21
_umount	equ 22
_setuid	equ 23
_getuid	equ 24
_stime	equ 25
_quit	equ 26	
_intr	equ 27
_fstat	equ 28
_emt 	equ 29
_mdate 	equ 30
_stty 	equ 31
_gtty	equ 32
_ilgins	equ 33

;;;

sys macro syscallnumber, arg1, arg2, arg3

    ; Retro UNIX 8086 v1 system call.

    ifnb <arg1> 	
      mov bx, arg1
    endif
    
    ifnb <arg2> 	
      mov cx, arg2
    endif

    ifnb <arg3> 	
      mov dx, arg3
    endif
     			
    mov ax, syscallnumber	
    int 20h	
   
    endm

; Retro UNIX 8086 v1 system call format:
; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>


UNIX   	SEGMENT PUBLIC 'CODE'
        assume cs:UNIX,ds:UNIX,es:UNIX,ss:UNIX

START_CODE:
	; from 'sysexec' system calls
	; cs=ds=es=ss
	; ax=bx=cx=dx=si=di=bp=0
	;  (stack pointer -sp- points to 
	; to the head of arguments list which is 
	; on top the stack, backward from 'ecore'.) 
	; sp = offset argc (argument count)
	;

	;sys 	_quit, 0
	;sys 	_intr, 0

	;call 	ttyn
	;; ah = 0
	;mov	byte ptr [ttyx]+8, al
	;sub	al, '0'
	;shl	ax, 1
	;shl	ax, 1
	;shl	ax, 1
	;shl	ax, 1
	;mov	word ptr [s_off], ax

	pop	dx ; argument count
	pop	ax ; pointer to argument 0
		   ; executable file name	
	cmp	dx, 1
	jna	short login
	dec	dx ; dec dl
	pop	si ; pointer to argument 1
		   ; user name
	mov	di, offset uname
@@:
	lodsb
	stosb
	and 	al, al
	jnz 	short @b
	dec	dx
	jz	short login
	pop	si
	mov	di, offset passwd	
@@:
	lodsb
	stosb
	or 	al, al
	jnz 	short @b	

login:
	call 	guname
	mov	si, offset uname
	call	compar
	jnc	short @f	
sorry:
	mov	si, offset msgIL
	call	mesg
	xor	ax, ax
	mov	word ptr [uname], ax
	mov	word ptr [passwd], ax
	jmp	short login
@@:
	call	gpasswd
	mov	si, offset passwd
	call	comparg
	jc	short sorry

	sys	_write, 1, nextline, 2
	
        sys     _exec, shell, shellp
	mov	si, offset msgNoSh
	call 	mesg
        sys     _exit
here:	
	hlt
        jmp     short here

gpasswd:
	;sys	_write, 1, nextline, 2
	mov	di, offset passwd
	cmp	byte ptr [DI], 1
	jnb	short gun2
	mov	si, offset msgPswd
	call	mesg
gp1:
	call 	tgetc
	stosb
	and	al, al
	jz	short gun2
	mov	byte ptr [chr], '*'
	call 	tputc	
	cmp	di, offset passwd + 9
	jb	short gp1
	dec	di
	jmp	short gp1

guname:
	;sys	_write, 1, nextline, 2
	mov	di, offset uname
	cmp	byte ptr [DI], 1
	jnb	short gun2
	xor	ax, ax ; mov ax, 0
	stosw
	stosw
	stosw
	stosw
	mov	si, offset msgName
	call	mesg
	mov	di, offset uname
gun1:
	call	tgetc
	stosb
	and 	al, al
	jz	short gun2
	call 	tputc
	cmp	di, offset uname + 9
	jb	short gun1
	dec	di
	jmp	short gun1
gun2:
	retn

comparu:
compar:
	lodsw
	cmp	ax, 'or'
	jne	short cmp1
	lodsw
	cmp	ax, 'to'
	jne	short cmp2
	lodsb
	or	al, al
	jnz	short cmp2
cmp0:
	retn
cmp1:
	cmp 	ax, 're'
	jne	short cmp2
	lodsw
	cmp	ax, 'od'
	jne	short cmp2
	lodsw
	cmp	ax, 'ag'
	jne	short cmp2
	lodsb
	cmp	al, 'n'
	jne	short cmp2
	lodsb
	and 	al, al
	jz	short cmp0
cmp2:
	stc
	retn
	
comparg:
	lodsb
	and	al, al
	jz	short cmpp0
	cmp	al, '4'
	jne	short cmp2
	lodsb
	cmp	al, '1'
	jne	short cmp2
	lodsb
	cmp	al, '7'
	jnz	short cmp2
cmpp0:
	retn

tgetc:
	sys	_read, 0, chr, 1
	and	ax, ax
	jnz	short @f
	sys	_exit
@@:
	mov	al, byte ptr [chr]
	cmp	al, 0Dh
	jne	short @f
	xor	al, al
@@:
	retn

tputc:
	cmp	byte ptr [chr], 20h
	jb	short @f 
	sys	_write, 1, chr, 1
@@:
	retn	

mesg:
	mov	dx, si
@@:	
	lodsb
	and 	al, al
	jnz 	short @b
	sub	si, dx
	xchg	si, dx
	; dx = string length
	sys	_write, 1, si 
	retn


;/ return name of current tty
;

ttyn:
	push	di
	push	si
	push	dx
	mov	byte ptr [ttyname], 'x'
	sys	_fstat, 1, buf ; get tty file status
			       ; file descriptor = 1 
			       ; (standard output) 
	jc	short er1
	sys	_open, dev, 0
	jnc	short @f
er:
er1:
	xor 	al, al
ttyn_r:
	xor	ah, ah
	pop	dx
	pop	si
	pop	di
	retn	
@@:
	mov	si, word ptr [buf]
	mov	di, ax	
@@:
	sys	_read, di, buf, 10
	jc	er
	cmp	ax, 10
	jne	er
	mov	dx, word ptr [buf]
	cmp	dx, si
	jne	short @b
	mov	dx, word ptr [buf]+2
	cmp	dx, 'tt'
	jne	short @b
	mov	dx, word ptr [buf]+4
	cmp	dl, 'y'
	jne	short @b
	or	dh, dh
	jz	short @b
	cmp	byte ptr [buf]+6, 0
	jne	short @b
	mov	byte ptr [ttyname], dh
	sys	_close, di
	mov	al, byte ptr [ttyname]
	jmp 	short ttyn_r

EVEN
shellp:
	dw mshell
	dw 0
;utmp:   db '/tmp/utmp'
;        db 0
;wtmp:   db '/tmp/wtmp'
;        db 0
shell:	db '/bin/sh'
	db 0
shpl 	equ offset shell + 32 - offset shpad
shpad:  db shpl dup (0)

mshell: db '-'
	db 0
;motd:   db '/etc/motd'
;        db 0
;mailf:  db 'mailbox'
;        db 0
;passwdf: db '/etc/passwd'
;        db 0
;ttyx:   db '/dev/ttyx'
;        db 0
;EVEN
uname: 	db 16 dup(0)
passwd: db 8 dup(0)
;dirbuf: db 32 dup(0)
;shbuf:  db 32 dup(0)
;ttyb:   db 6 dup(0)
;uid:    dw 0
chr:	dw 0
;pbuf:   db 518 dup (0)

;; ttyn data
;EVEN
dev:    db '/dev', 0
EVEN
buf:	db 34 dup(0)
;EVEN
ttyname:dw 0

;s_off:	dw 0
msgName: db 0Dh, 0Ah, 'Name: ', 0
EVEN
msgPswd: db 0Dh, 0Ah, 'Password: ', 0
EVEN
msgIL:	 db 0Dh, 0Ah, 'Login incorrect !', 0
;EVEN
msgNoSh: db 0Dh, 0Ah, 'No Shell !'
nextline: db 0Dh, 0Ah, 0

UNIX    ends


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; login.s
;
;/  login --  enter new user
;
;.globl	ttyn
;.globl	crypt
;.globl	fopen
;.globl	getc
;.globl	mesg
;
;	sys	quit; 0
;	sys	intr; 0
;	jsr	pc,ttyn
;	movb	r0,ttyx+8.
;	sub	$'0,r0
;	cmp	r0,$'a-'0
;	blo	1f
;	sub	$'a-'0-10.,r0	/ map a-z into 10. on
;1:
;	asl	r0
;	asl	r0
;	asl	r0
;	asl	r0
;	mov	r0,offset
;	mov	(sp)+,r5
;	tst	(sp)+
;	dec	r5
;	ble	login
;	mov	(sp)+,r4
;	mov	$uname,r1
;2:
;	movb	(r4)+,(r1)+
;	bne	2b
;	dec	r5
;	ble	login
;	mov	(sp)+,r4
;	mov	$passwd,r1
;2:
;	movb	(r4)+,(r1)+
;	bne	2b
;login:
;	clrb	uname+8.
;	mov	$passwdf,r0
;	jsr	r5,fopen; pbuf
;	bec	1f
;	jsr	r5,mesg; <Can't open password file\n\0>; .even
;	sys	exit
;1:
;	jsr	pc,guname
;1:
;	jsr	r5,compar; uname
;		br .+4
;	br	2f
;3:
;	jsr	r5,getc; pbuf
;	bes	sorry
;	cmp	r0,$'\n
;	bne	3b
;	br	1b
;sorry:
;	jsr	r5,mesg; <Login incorrect\n\0>; .even
;	mov	pbuf,r0
;	sys	close
;	clr	uname
;	clr	passwd
;	br	login
;2:
;	jsr	r5,getc; pbuf
;	cmp	r0,$':
;	beq	2f
;	mov	r0,-(sp)
;	jsr	pc,gpasswd
;	cmpb	(r0)+,(sp)+
;	bne	sorry
;	mov	r0,0f
;	jsr	r5,compar; 0:..
;		br sorry
;2:
;	clr	r1
;2:
;	jsr	r5,getc; pbuf
;	cmp	r0,$':
;	beq	2f
;	mpy	$10.,r1
;	sub	$'0,r0
;	add	r0,r1
;	br	2b
;2:
;	mov	r1,0f
;	sys	chown; ttyx; 0:..
;	mov	r1,uid
;1:
;	jsr	r5,getc; pbuf
;	cmp	r0,$':
;	bne	1b			/ skip ident field
;	mov	$dirbuf,r1
;1:
;	jsr	r5,getc; pbuf
;	cmpb	r0,$':
;	beq	1f
;	movb	r0,(r1)+
;	br	1b
;1:
;	clrb	(r1)
;	sys	chdir; dirbuf
;	bec	1f
;	jsr	r5,mesg; <No directory\n\0>; .even
;	br	sorry
;1:
;	mov	$uname+8.,r1
;1:
;	tstb	-(r1)
;	bne	1f
;	movb	$' ,(r1)
;	br	1b
;1:
;	cmpb	ttyx+8.,$'x
;	beq	1f
;	sys	open; utmp; 1
;	bes	1f
;	mov	r0,r2
;	sys	seek; offset:..; 0
;	movb	ttyx+8.,uname+8.
;	sys	time
;	mov	r0,uname+10.
;	mov	r1,uname+12.
;	mov	r2,r0
;	sys	write; uname; 16.
;	mov	r2,r0
;	sys	close
;1:
;	cmpb	ttyx+8.,$'x
;	beq	1f
;	sys	open; wtmp; 1
;	bes	1f
;	mov	r0,r1
;	sys	seek; 0; 2
;	sys	write; uname; 16.
;	mov	r1,r0
;	sys	close
;1:
;	jsr	r5,getc; pbuf
;	cmp	r0,$'\n
;	beq	1f
;	mov	$shell,r1
;2:
;	movb	r0,(r1)+
;	jsr	r5,getc; pbuf
;	cmp	r0,$'\n
;	bne	2b
;	clrb	(r1)
;1:
;	mov	pbuf,r0
;	sys	close
;	mov	$motd,r0
;	jsr	r5,fopen; pbuf
;	bes	1f
;2:
;	jsr	r5,getc; pbuf
;	bes	1f
;	mov	r0,uname
;	mov	$1,r0
;	sys	write; uname; 1
;	br	2b
;1:
;	mov	pbuf,r0
;	sys	close
;	sys	stat; mailf; pbuf
;	bes	1f
;	tst	pbuf+6
;	beq	1f
;	jsr	r5,mesg; <You have mail\n\0>; .even
;1:
;	mov	uid,r0
;	sys	setuid
;	sys	exec; shell; shellp
;	jsr	r5,mesg; <No Shell\n\0>; .even
;	sys	exit
;
;gpasswd:
;	mov	$passwd,r1
;	tstb	(r1)
;	bne	3f
;	clr	r0
;	sys	gtty; ttyb
;	bic	$10,ttyb+4		/ turn off echo
;	clr	r0
;	sys	stty; ttyb
;	jsr	r5,mesg; <Password: \0>; .even
;2:
;	jsr	pc,tgetc
;	movb	r0,(r1)+
;	beq	1f
;	cmp	r1,$passwd+9.
;	blo	2b
;	dec	r1
;	br	2b
;1:
;	bis	$10,ttyb+4		/ turn on echo
;	clr	r0
;	sys	stty; ttyb
;	jsr	r5,mesg; <\n\0>; .even
;3:
;	mov	$passwd,r0
;	jsr	pc,crypt
;	clrb	8(r0)
;	rts	pc
;
;guname:
;	mov	$uname,r1
;	tstb	(r1)
;	bne	1f
;	clr	(r1)+
;	clr	(r1)+
;	clr	(r1)+
;	clr	(r1)+
;	mov	$uname,r1
;	jsr	r5,mesg; <Name: \0>; .even
;2:
;	jsr	pc,tgetc
;	movb	r0,(r1)+
;	beq	1f
;	cmp	r1,$uname+9.
;	blo	2b
;	dec	r1
;	br	2b
;1:
;	rts	pc
;
;compar:
;	mov	(r5)+,r4
;1:
;	jsr	r5,getc; pbuf
;	bes	2f
;	cmpb	r0,(r4)+
;	beq	1b
;	cmp	r0,$':
;	bne	1f
;	tstb	-(r4)
;	bne	1f
;	tst	(r5)+
;1:
;	rts	r5
;2:
;	tst	(sp)+
;	jmp	sorry
;
;tgetc:
;	clr	r0
;	sys	read; ch; 1
;	tst	r0
;	bne	1f
;	sys	exit
;1:
;	mov	ch,r0
;	cmp	r0,$'\n
;	bne	1f
;	clr	r0
;1:
;	rts	pc
;
;shellp:
;	mshell
;	0
;utmp:	</tmp/utmp\0>
;wtmp:	</tmp/wtmp\0>
;shell:	</bin/sh\0>; .=shell+32.
;mshell:<-\0>
;motd:	</etc/motd\0>
;mailf:	<mailbox\0>
;passwdf:</etc/passwd\0>
;ttyx:	</dev/ttyx\0>
;.even
;.bss
;uname: .=.+16.
;passwd:.=.+8.
;dirbuf:.=.+32.
;shbuf:	.=.+32.
;ttyb:	.=.+6
;uid:	.=.+2
;ch:	.=.+2
;pbuf:	.=.+518.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ttyn.s
;
;/ return name of current tty
;
;.globl	ttyn, _ttyn
;
;_ttyn:
;	mov	2(sp),r0
;	br	1f
;ttyn:
;	clr	r0
;1:
;	mov	$'x,name
;	tst	-(sp)
;	sys	fstat; buf
;	bes	er1
;	mov	buf+2,(sp)
;	sys	open; dev; 0
;	bes	er1
;	mov	r0,r1
;1:
;	mov	r1,r0
;	sys	read; buf; 16.
;	bes	er
;	cmp	r0,$16.
;	bne	er
;	mov	$buf,r0
;	cmp	(r0)+,(sp)
;	bne	1b
;	cmp	(r0)+,$"tt
;	bne	1b
;	cmpb	(r0)+,$'y
;	bne	1b
;	tstb	(r0)+
;	beq	1b
;	cmpb	(r0),$'\0
;	bne	1b
;	movb	-(r0),name
;
;er:
;	mov	r1,r0
;	sys	close
;
;er1:
;	tst	(sp)+
;	movb	name,r0
;	rts	pc
;
;.data
;dev:	</dev\0>
;.even
;.bss
;buf:	.=.+40.
;name:	.=.+2

	end START_CODE
