     1                                  ; ****************************************************************************
     2                                  ; mount8086.s (mount0.s) - by Erdogan Tan - 08/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 8086 v1 - mount -- mount file system
     5                                  ;
     6                                  ; [ Last Modification: 10/05/2022 ]
     7                                  ;
     8                                  ; ****************************************************************************
     9                                  ; (/etc/mount)
    10                                  
    11                                  ; mount0.s - Retro UNIX 8086 v1 (16 bit version of 'mount1.s')
    12                                  ; mount1.s - Retro UNIX 386 v1 (& v1.1 & v1.2)
    13                                  
    14                                  ; UNIX v1 system calls
    15                                  _rele 	equ 0
    16                                  _exit 	equ 1
    17                                  _fork 	equ 2
    18                                  _read 	equ 3
    19                                  _write	equ 4
    20                                  _open	equ 5
    21                                  _close 	equ 6
    22                                  _wait 	equ 7
    23                                  _creat 	equ 8
    24                                  _link 	equ 9
    25                                  _unlink	equ 10
    26                                  _exec	equ 11
    27                                  _chdir	equ 12
    28                                  _time 	equ 13
    29                                  _mkdir 	equ 14
    30                                  _chmod	equ 15
    31                                  _chown	equ 16
    32                                  _break	equ 17
    33                                  _stat	equ 18
    34                                  _seek	equ 19
    35                                  _tell 	equ 20
    36                                  _mount	equ 21
    37                                  _umount	equ 22
    38                                  _setuid	equ 23
    39                                  _getuid	equ 24
    40                                  _stime	equ 25
    41                                  _quit	equ 26	
    42                                  _intr	equ 27
    43                                  _fstat	equ 28
    44                                  _emt 	equ 29
    45                                  _mdate 	equ 30
    46                                  _stty 	equ 31
    47                                  _gtty	equ 32
    48                                  _ilgins	equ 33
    49                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    50                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    51                                  _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
    52                                  
    53                                  ;;;
    54                                  ESCKey equ 1Bh
    55                                  EnterKey equ 0Dh
    56                                  
    57                                  ;%macro sys 1-4
    58                                  ;   ; 03/09/2015
    59                                  ;   ; 13/04/2015
    60                                  ;   ; Retro UNIX 386 v1 system call.
    61                                  ;   %if %0 >= 2   
    62                                  ;       mov ebx, %2
    63                                  ;       %if %0 >= 3
    64                                  ;           mov ecx, %3
    65                                  ;           ;%if %0 = 4
    66                                  ;           %if	%0 >= 4 ; 11/03/2022
    67                                  ;		mov edx, %4
    68                                  ;           %endif
    69                                  ;       %endif
    70                                  ;   %endif
    71                                  ;   mov eax, %1
    72                                  ;   int 30h
    73                                  ;%endmacro
    74                                  
    75                                  %macro sys 1-4
    76                                      ; Retro UNIX 8086 v1 system call.
    77                                      %if %0 >= 2   
    78                                          mov bx, %2
    79                                          %if %0 >= 3
    80                                              mov cx, %3
    81                                              %if %0 >= 4
    82                                                 mov dx, %4
    83                                              %endif
    84                                          %endif
    85                                      %endif
    86                                      mov ax, %1
    87                                      int 20h
    88                                  %endmacro
    89                                  
    90                                  ;; Retro UNIX 386 v1 system call format:
    91                                  ;; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    92                                  
    93                                  ;; 11/03/2022
    94                                  ;; Note: Above 'sys' macro has limitation about register positions;
    95                                  ;;	ebx, ecx, edx registers must not be used after their
    96                                  ;;	positions in sys macro.
    97                                  ;; for example:
    98                                  ;;	'sys _write, 1, msg, ecx' is defective, because
    99                                  ;;	 ecx will be used/assigned before edx in 'sys' macro.
   100                                  ;; correct order may be:
   101                                  ;;	'sys _write, 1, msg, eax ; (eax = byte count)
   102                                  
   103                                  ; Retro UNIX 8086 v1 system call format:
   104                                  ; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>
   105                                  
   106                                  ; ----------------------------------------------------------------------------
   107                                  
   108                                  [BITS 16] ; 16-bit intructions (8086/8088 - Real Mode)
   109                                  
   110                                  [ORG 0] 
   111                                  
   112                                  START_CODE:
   113                                  	; 10/05/2022
   114                                  	; 09/05/2022 (16 bit code)
   115                                  	; 08/05/2022
   116 00000000 59                      	pop	cx ; cx = number of arguments
   117                                  	;
   118 00000001 58                      	pop	ax ; ax = argument 0 = executable file name
   119                                  	;
   120                                  	;cmp	cx, 3
   121 00000002 80F903                  	cmp	cl, 3
   122 00000005 7529                    	jne	short mnt_0
   123                                  
   124 00000007 5F                      	pop	di ; argument 1 = device name
   125 00000008 5D                      	pop	bp ; argument 2 = mounting directory
   126                                  
   127 00000009 89EE                    	mov	si, bp
   128                                  
   129                                  	; 09/05/2022
   130                                  
   131                                  ;; 'pwd' command compatibility restriction !
   132                                  ;;	; ---
   133                                  ;;	; Only '/usr' or '/mnt' directories can be used
   134                                  ;;	;  with current mount version (otherwise current
   135                                  ;;	; 'pwd' will not recognize mounting directory
   136                                  ;;	;  as correct).
   137                                  ;
   138                                  ;	; short way...
   139                                  ;
   140                                  ;	lodsw
   141                                  ;	cmp	al, '/'
   142                                  ;	jne	short mnt_5
   143                                  ;	cmp	ah, 'u'
   144                                  ;	jne	short mnt_m
   145                                  ;mnt_u:
   146                                  ;	lodsw
   147                                  ;	cmp	ax, 'sr'
   148                                  ;	je	short mnt_1
   149                                  ;	jmp	short mnt_2
   150                                  ;mnt_m:
   151                                  ;	cmp	ah, 'm'
   152                                  ;	jne	short mnt_2
   153                                  ;	lodsw
   154                                  ;	cmp	ax, 'nt'
   155                                  ;	jne	short mnt_2
   156                                  ;mnt_1:
   157                                  ;	cmp	byte [si], 0 ;
   158                                  ;	jna	short mnt_5 ; '/usr' or '/mnt', continue
   159                                  ;
   160                                  ;	; neither '/usr' or '/mnt'
   161                                  
   162                                  ;	; print usage message and then exit
   163                                  ;mnt_0:
   164                                  ;	mov	ax, usage_msg
   165                                  ;	jmp	short mnt_7
   166                                  
   167                                  ;p_msg_exit:
   168                                  ;	call	print_msg
   169                                  ;exit:
   170                                  ;	sys	_exit
   171                                  ;hang:
   172                                  ;	nop
   173                                  ;	jmp	short hang
   174                                  
   175                                  mnt_2:
   176                                  	; long way...
   177                                  	sys	_stat, bp, stbuf
    76                              <1> 
    77                              <1>  %if %0 >= 2
    78 0000000B 89EB                <1>  mov bx, %2
    79                              <1>  %if %0 >= 3
    80 0000000D B9[1C01]            <1>  mov cx, %3
    81                              <1>  %if %0 >= 4
    82                              <1>  mov dx, %4
    83                              <1>  %endif
    84                              <1>  %endif
    85                              <1>  %endif
    86 00000010 B81200              <1>  mov ax, %1
    87 00000013 CD20                <1>  int 20h
   178 00000015 7234                    	jc	short mnt_dir_err
   179                                  	; ax = device number
   180                                  
   181                                  	; is directory ? (check inode mode)
   182 00000017 F606[1F01]40            	test	byte [stbuf+3], 40h ; directory
   183 0000001C 742D                    	jz	short mnt_dir_err	
   184                                  
   185                                  	; is already mounted ?
   186 0000001E 09C0                    	or	ax, ax
   187 00000020 7529                    	jnz	short mnt_dir_err	
   188                                  
   189                                  ;	mov	dx, [stbuf] ; inode number
   190                                  ;	
   191                                  ;	sys	_stat, usr, stbuf
   192                                  ;	jc	short mnt_4
   193                                  ;	
   194                                  ;	; check if it is '/usr' inode
   195                                  ;	cmp	dx, [stbuf] ; same inode number
   196                                  ;	je	short mnt_5
   197                                  ;mnt_4:
   198                                  ;	sys	_stat, mnt, stbuf
   199                                  ;	jc	short mnt_dir_err
   200                                  ;
   201                                  ;	; check if it is '/mnt' inode
   202                                  ;	cmp	dx, [stbuf] ; same inode number
   203                                  ;	jne	short mnt_dir_err
   204                                  
   205                                  mnt_5:
   206                                  	; only superuser (root) can do mount/umount
   207                                  	sys	_getuid
    76                              <1> 
    77                              <1>  %if %0 >= 2
    78                              <1>  mov bx, %2
    79                              <1>  %if %0 >= 3
    80                              <1>  mov cx, %3
    81                              <1>  %if %0 >= 4
    82                              <1>  mov dx, %4
    83                              <1>  %endif
    84                              <1>  %endif
    85                              <1>  %endif
    86 00000022 B81800              <1>  mov ax, %1
    87 00000025 CD20                <1>  int 20h
   208 00000027 21C0                    	and	ax, ax ; uid = 0 -> root
   209 00000029 7410                    	jz	short mnt_6
   210 0000002B B8[B800]                	mov	ax, deny_msg
   211 0000002E EB03                    	jmp	short mnt_7
   212                                  
   213                                  	; 10/05/2022
   214                                  	; print usage message and then exit
   215                                  mnt_0:
   216 00000030 B8[6D00]                	mov	ax, usage_msg
   217                                  mnt_7:
   218 00000033 E81F00                  	call	print_msg
   219                                  exit:
   220                                  	sys	_exit
    76                              <1> 
    77                              <1>  %if %0 >= 2
    78                              <1>  mov bx, %2
    79                              <1>  %if %0 >= 3
    80                              <1>  mov cx, %3
    81                              <1>  %if %0 >= 4
    82                              <1>  mov dx, %4
    83                              <1>  %endif
    84                              <1>  %endif
    85                              <1>  %endif
    86 00000036 B80100              <1>  mov ax, %1
    87 00000039 CD20                <1>  int 20h
   221                                  ;hang:
   222                                  ;	nop
   223                                  ;	jmp	short hang
   224                                  
   225                                  mnt_6:
   226                                  	; di = device name address
   227                                  	; bp = mounting directory path/name address
   228                                   	;
   229                                  	; 09/05/2022
   230                                  	; Note: Retro UNIX 8086 v1 kernel 
   231                                  	; (and original unix v1 kernel, sysmount)
   232                                  	; mounts devices without checking superblock
   233                                  	; validity. So, sysmount does not return
   234                                  	; with 'invalid file system' error.
   235                                  	; (but Retro UNIX 386 sysmount returns with
   236                                  	; 'invalid file system' error)
   237                                  	;
   238                                  	; At sysmount system call return,
   239                                  	; if cf=1 it is user permission error
   240                                  	; or disk r/w error or 'already mounted' error.
   241                                  
   242                                  	sys	_mount, di, bp
    76                              <1> 
    77                              <1>  %if %0 >= 2
    78 0000003B 89FB                <1>  mov bx, %2
    79                              <1>  %if %0 >= 3
    80 0000003D 89E9                <1>  mov cx, %3
    81                              <1>  %if %0 >= 4
    82                              <1>  mov dx, %4
    83                              <1>  %endif
    84                              <1>  %endif
    85                              <1>  %endif
    86 0000003F B81500              <1>  mov ax, %1
    87 00000042 CD20                <1>  int 20h
   243 00000044 720A                    	jc	short mnt_err
   244                                  	;
   245 00000046 B8[1101]                	mov	ax, ok_msg
   246                                  	; 10/05/2022
   247 00000049 EBE8                    	jmp	short mnt_7
   248                                  
   249                                  ;mnt_7:
   250                                  ;	call	print_msg
   251                                  ;exit:
   252                                  ;	sys	_exit
   253                                  ;;hang:
   254                                  ;;	nop
   255                                  ;;	jmp	short hang
   256                                  
   257                                  mnt_dir_err:
   258 0000004B B8[F600]                	mov	ax, dir_err_msg
   259 0000004E EBE3                    	jmp	short mnt_7
   260                                  
   261                                  mnt_err:
   262                                  	; 09/05/2022
   263 00000050 B8[EA00]                	mov	ax, err_msg
   264 00000053 EBDE                    	jmp	short mnt_7
   265                                  
   266                                  ;-----------------------------------------------------------------
   267                                  
   268                                  print_msg:
   269                                  	; ax = asciiz string address
   270 00000055 89C6                    	mov	si, ax
   271 00000057 4E                      	dec	si
   272                                  nextchr:
   273 00000058 46                      	inc	si
   274 00000059 803C00                  	cmp	byte [si], 0
   275 0000005C 77FA                    	ja	short nextchr
   276                                  	;cmp	[si], 0Dh
   277                                  	;ja	short nextchr
   278 0000005E 29C6                    	sub	si, ax
   279                                  	; si = asciiz string length
   280                                  	;
   281                                  	sys	_write, 1, ax, si
    76                              <1> 
    77                              <1>  %if %0 >= 2
    78 00000060 BB0100              <1>  mov bx, %2
    79                              <1>  %if %0 >= 3
    80 00000063 89C1                <1>  mov cx, %3
    81                              <1>  %if %0 >= 4
    82 00000065 89F2                <1>  mov dx, %4
    83                              <1>  %endif
    84                              <1>  %endif
    85                              <1>  %endif
    86 00000067 B80400              <1>  mov ax, %1
    87 0000006A CD20                <1>  int 20h
   282                                  	;
   283 0000006C C3                      	retn
   284                                  
   285                                  ;-----------------------------------------------------------------
   286                                  ;  data - initialized data
   287                                  ;-----------------------------------------------------------------
   288                                  
   289                                  ; default mounting directories (for current retro unix version)
   290                                  ;usr:	db '/usr', 0
   291                                  ;mnt:	db '/mnt', 0
   292                                  
   293                                  usage_msg:
   294 0000006D 0D0A                    	db 0Dh, 0Ah
   295                                  	;db "Usage: mount <block device name> </usr> "
   296                                  	;db 0Dh, 0Ah
   297                                  	;db "    or mount <block device name> </mnt> "	
   298 0000006F 55736167653A206D6F-     	db "Usage: mount <block device name> <dir> "
   298 00000078 756E74203C626C6F63-
   298 00000081 6B2064657669636520-
   298 0000008A 6E616D653E203C6469-
   298 00000093 723E20             
   299                                  	;db 0Dh, 0Ah
   300 00000096 0D0A                    	db 0Dh, 0Ah
   301 00000098 4578616D706C653A20-     	db "Example: mount /dev/fd1 /usr "
   301 000000A1 6D6F756E74202F6465-
   301 000000AA 762F666431202F7573-
   301 000000B3 7220               
   302 000000B5 0D0A00                  	db 0Dh, 0Ah, 0
   303                                  
   304                                  deny_msg:
   305 000000B8 0D0A                    	db 0Dh, 0Ah	
   306 000000BA 4D6F756E743A204F6E-     	db "Mount: Only superuser/root can mount devices!"	
   306 000000C3 6C7920737570657275-
   306 000000CC 7365722F726F6F7420-
   306 000000D5 63616E206D6F756E74-
   306 000000DE 206465766963657321 
   307 000000E7 0D0A00                   	db 0Dh, 0Ah, 0  		
   308                                  err_msg:
   309 000000EA 0D0A                    	db 0Dh, 0Ah
   310 000000EC 4572726F722120          	db 'Error! '
   311 000000F3 0D0A00                  	db 0Dh, 0Ah, 0
   312                                  dir_err_msg:
   313 000000F6 0D0A                    	db 0Dh, 0Ah
   314 000000F8 4D6F756E7420446972-     	db 'Mount Directory Error!'
   314 00000101 6563746F7279204572-
   314 0000010A 726F7221           
   315                                  	;db 0Dh, 0Ah
   316                                  	;db "(Mounting directory must exist "
   317                                  	;db "and be '/usr' or '/mnt'.)",
   318 0000010E 0D0A00                  	db 0Dh, 0Ah, 0
   319                                  ok_msg:
   320 00000111 0D0A                    	db 0Dh, 0Ah
   321 00000113 4F4B2E20                	db 'OK. '
   322                                  nextline:
   323 00000117 0D0A00                  	db 0Dh, 0Ah, 0
   324                                  
   325                                  ;-----------------------------------------------------------------
   326                                  ;  bss - uninitialized data
   327                                  ;-----------------------------------------------------------------	
   328                                  
   329 0000011A 90<rep 2h>              align 4
   330                                  
   331                                  bss_start:
   332                                  
   333                                  ABSOLUTE bss_start
   334                                  
   335                                  ; sysstat buffer
   336 0000011C <res 22h>               stbuf: resb 34 ; (Retro UNIX 8086/386 v1 & Retro UNIX 386 v1.1)
   337                                  
   338                                  ;-----------------------------------------------------------------
